title: Spring boot oauth2: No userInfo endpoint - How to load the authentication (Principal) from the JWT access token directly in the client
body: <p>I am setting up an oauth 2.0 client application which will redirect the users to an external IDP (Authorization Server) to sign in. My app will undergo the regular oauth 2 Authorization code grant flow - 1)Redirect the users to sign in. 2)Obtain the access code first 3) Use the access code to obtain the token. Since the external IDP is using oauth 2 just for authentication, they are not going to provide a user-info endpoint url (required by an OIDC provider) to get the user details. Instead they want us to get the claims from the JWT token directly and make any authorizations in our app. 
  I am unable to find the right code/configuration which will not expect a user-info endpoint and instead decode the jwt directly for loading the authentication.
  In the below demo code, if I were to decode the user details from the JWT token issued by OKTA without calling its userInfo endpoint, how do I do that?</p>
  
  <p>I am using spring boot 2.x release using the standard oauth client configuration provided in the spring reference sample social oauth2 projects.</p>
  
  <p>I would really appreciate if someone could guide me in the right path. Thank you! </p>
  
  <p>gradle configuration</p>
  
  <pre><code>buildscript {
  ext {
      springBootVersion = '2.2.0.RELEASE'
  }
  repositories {
      mavenLocal()
      mavenCentral()
  }
  dependencies {
      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
  }
  apply plugin: 'java'
  apply plugin: 'org.springframework.boot'
  sourceCompatibility = 1.8
  targetCompatibility = 1.8
  repositories {
  mavenLocal()
  mavenCentral()
  }
  configurations {
  compile.exclude module: 'spring-boot-starter-logging'
  }
  dependencies {
  compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
  compile("org.springframework.boot:spring-boot-starter-log4j2:${springBootVersion}")
  compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}")
  compile("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:${springBootVersion}")
  compile("org.webjars:jquery:2.1.1")
  compile("org.webjars:bootstrap:3.2.0")
  compile("org.webjars:webjars-locator-core:0.42")
  }
  </code></pre>
  
  <p>application.yml</p>
  
  <pre><code>github:
    client:
       clientId: &lt;clientId&gt;
       clientSecret: &lt;clientSecret&gt;
       accessTokenUri: https://github.com/login/oauth/access_token
       userAuthorizationUri: https://github.com/login/oauth/authorize
       tokenName: oauth_token
       authenticationScheme: query
       clientAuthenticationScheme: form
    resource:
       userInfoUri: https://api.github.com/user
  
  okta:
    client:
     clientId: &lt;clientId&gt;
     clientSecret: &lt;clientSecret&gt;
     accessTokenUri: https://&lt;okta-sub-domain&gt;/oauth2/default/v1/token
     userAuthorizationUri: https://&lt;okta-sub-domain&gt;/oauth2/default/v1/authorize
     scope: openid profile email
   resource:
    userInfoUri: https://&lt;okta-sub-domain&gt;/oauth2/default/v1/userinfo
  </code></pre>
  
  <p>OAuth2Config.java</p>
  
  <pre><code>@Configuration
  @EnableOAuth2Client
  public class Oauth2Config extends WebSecurityConfigurerAdapter {
  
  @Autowired
  OAuth2ClientContext oauth2ClientContext;
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http.antMatcher("/**").authorizeRequests()
      .antMatchers("/", "/login**", "/webjars/**", "/error**")
      .permitAll()
    .anyRequest()
      .authenticated()
              .and().logout().logoutSuccessUrl("/").permitAll()
              .and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);;
      http.csrf().disable();
  }
  
  private Filter ssoFilter() {
      CompositeFilter filter = new CompositeFilter();
      List&lt;Filter&gt; filters = new ArrayList&lt;&gt;();
  
      OAuth2ClientAuthenticationProcessingFilter githubFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
      OAuth2RestTemplate githubTemplate = new OAuth2RestTemplate(github(), oauth2ClientContext);
      githubFilter.setRestTemplate(githubTemplate);
      UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), github().getClientId());
      tokenServices.setRestTemplate(githubTemplate);
      githubFilter.setTokenServices(tokenServices);
      filters.add(githubFilter);
  
      OAuth2ClientAuthenticationProcessingFilter oktaFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/okta");
      OAuth2RestTemplate oktaTemplate = new OAuth2RestTemplate(okta(), oauth2ClientContext);
      oktaFilter.setRestTemplate(oktaTemplate);
      tokenServices = new UserInfoTokenServices(oktaResource().getUserInfoUri(), okta().getClientId());        
      tokenServices.setRestTemplate(oktaTemplate);
      oktaFilter.setTokenServices(tokenServices);
      filters.add(oktaFilter);
  
      filter.setFilters(filters);
      return filter;
  }
  
  //Client registration
  @Bean
  @ConfigurationProperties("github.client")
  public AuthorizationCodeResourceDetails github() {
      return new AuthorizationCodeResourceDetails();
  }
  
  //user info endpoints
  @Bean
  @ConfigurationProperties("github.resource")
  public ResourceServerProperties githubResource() {
      return new ResourceServerProperties();
  }
  
  @Bean
  @ConfigurationProperties("okta.client")
  public AuthorizationCodeResourceDetails okta() {
      return new AuthorizationCodeResourceDetails();
  }
  
  @Bean
  @ConfigurationProperties("okta.resource")
  public ResourceServerProperties oktaResource() {
      return new ResourceServerProperties();
  }
  
  //For Handling Redirects
  @Bean
  public FilterRegistrationBean&lt;OAuth2ClientContextFilter&gt; oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
      FilterRegistrationBean&lt;OAuth2ClientContextFilter&gt; registration = new FilterRegistrationBean&lt;&gt;();
      registration.setFilter(filter);
      registration.setOrder(-100);
      return registration;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>A simple controller with an endpoint used by html page</p>
  
  <pre><code>@RestController
  public class UserController {
  
  @GetMapping("/user")
  public Principal user(Principal principal) {        
      return principal;
  }
  </code></pre>
  
  <p>}</p>
  
  <pre><code>@SpringBootApplication
  public class Oauth2Application {
  
  public static void main(String[] args) {
      SpringApplication.run(Oauth2Application.class, args);
  }
  </code></pre>
  
  <p>}</p>