title: Add Custom AuthenticationProvider to Spring Boot + oauth +oidc
body: <p>I've developed a basic oauth/oidc example using SpringBoot 2.1.7 with Okta providing authentication services.  Here is my Gradle dependency setup for reference:</p>
  
  <pre><code>plugins {
  id 'org.springframework.boot' version '2.1.7.RELEASE'
  id 'java'
  }
  apply plugin: 'io.spring.dependency-management'
  
  sourceCompatibility = '1.8'
  
  configurations {
    developmentOnly
    runtimeClasspath {
      extendsFrom developmentOnly
   }
  }
  
  repositories {
      mavenCentral()
  }
  
  dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
  implementation 'org.springframework.boot:spring-boot-starter-security'
  implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'com.okta.spring:okta-spring-boot-starter:1.2.1'
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  runtimeOnly 'com.h2database:h2'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  testImplementation 'org.springframework.security:spring-security-test'
  }
  </code></pre>
  
  <p>All elements on the Okta side are configured properly and the example works as expected. Pretty much a "hello world" type demo here.  I would like to add a custom authentication provider that executes after all other AuthenticationProvider's provided by Spring.  I have stepped through the code using my debugger and noticed Spring auto configures several AuthenticationProviders.  They are:</p>
  
  <ol>
  <li>AnonymousAuthenticationProvider</li>
  <li>OAuth2LoginAuthenticationProvider</li>
  <li>OidcAuthorizationCodeAuthenticationProvider</li>
  <li>OAuth2AuthorizationCodeAuthenticationProvider</li>
  <li>JwtAuthenticationProvider</li>
  </ol>
  
  <p>I would like to run my authentication provider in the 6th position. I tried the following WebSecurityConfig that did not work even though the configure(AuthenticationManagerBuilder authBuilder) method fires:</p>
  
  <pre><code>@Configuration
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter
  {
  
      @Autowired
      private CustomAuthenticationProvider customAuthenticationProvider;
  
      @Override
      protected void configure(HttpSecurity http) throws Exception
      {
      http.authorizeRequests()
          .anyRequest().authenticated()
          .and()
          .oauth2Login()
          .successHandler(customOauthLoginSuccessHandler())
          .failureHandler(customOauthLoginFailureHandler())
          .and()
          .oauth2Client();
      http.csrf().disable();
      }
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.authenticationProvider(customAuthenticationProvider);
      }
  
      @Bean
      public CustomOauthLoginSuccessHandler customOauthLoginSuccessHandler()
      {
          CustomOauthLoginSuccessHandler handler = new CustomOauthLoginSuccessHandler();
          return handler;
      }
  
      @Bean
      public CustomOauthLoginFailureHandler customOauthLoginFailureHandler()
      {
          CustomOauthLoginFailureHandler handler = new CustomOauthLoginFailureHandler();
          handler.setUseForward(true);
          handler.setDefaultFailureUrl("/oautherror");
          return handler;
      }
  
  }
  </code></pre>
  
  <p>My Authentication provider never executes. Here is my custom AP:</p>
  
  <pre><code>@Component
  public class CustomAuthenticationProvider implements AuthenticationProvider
  {
      private Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
      private CustomOidcUserService customOidcUserService;
  
      public CustomAuthenticationProvider(CustomOidcUserService customOidcUserService)
      {
          this.customOidcUserService = customOidcUserService;
      }
  
      @Override
      public Authentication authenticate(Authentication authentication) throws AuthenticationException
      {
          logger.info("CustomAuthenticationProvider executing...");
          Object user = authentication.getPrincipal();
          if (user instanceof DefaultOidcUser)
          {
              logger.info("principal is instanceof DefaultOidcUser");
              DefaultOidcUser authToken = (DefaultOidcUser) user;
              this.customOidcUserService.loadUserByUsername(authToken.getClaims().get("preferred_username").toString());
              // add additional info to the Authentication object
          }
  
          return authentication;
      }
  
      @Override
      public boolean supports(Class&lt;?&gt; authentication)
      {
          return OAuth2LoginAuthenticationToken.class.isAssignableFrom(authentication);
      }
  }
  </code></pre>
  
  <p>My main goal is to add additional information about the authenticated user that comes from our legacy Oracle database.  It is NOT an option to add this additional information to the Okta side (in the cloud).</p>
  
  <p>Note that I was able to easily add success and failure handlers into the authentication path.  I feel like the inherent nature of SpringBoot's auto-config may be getting in my way.  Just need to know how to get around this.</p>
  
  <p>Additional info, yml file:</p>
  
  <pre><code>okta:
    oauth2:
      issuer: https://myhost.okta.com/oauth2/default
      client-id: 123456AAABBBCCC
      client-secret: AAAAAAAAABBBBBBBBBBB
  </code></pre>