title: Issue JWT tokens from Spring OAuth2 Authorization Server when authenticating with Google
body: <p>I want to create an authorization server using Spring Oauth which is able to issue it's own JWT tokens. The authorization server must delegate the authentication to Google. I have been following this tutorial which does almost everything I want: <a href="https://spring.io/guides/tutorials/spring-boot-oauth2/" rel="nofollow noreferrer">https://spring.io/guides/tutorials/spring-boot-oauth2/</a></p>
  
  <p>I was able to add Google as an authentication provider, but I'm struggling with the JWT part.</p>
  
  <p>Here's my authorization server configuration:</p>
  
  <pre><code>@SpringBootApplication 
  @EnableOAuth2Client
  @EnableAuthorizationServer
  @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
  public class MsAuthorizationGmailApplication extends WebSecurityConfigurerAdapter {
  
      @Autowired
      OAuth2ClientContext oauth2ClientContext;
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**").permitAll().anyRequest()
              .authenticated().and().exceptionHandling()
              .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login/gmail")).and().logout()
              .logoutSuccessUrl("/").permitAll().and().csrf()
              .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
              .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
      }
  
      @Bean
      @ConfigurationProperties("gmail")
      public ClientResources gmail() {
          return new ClientResources();
      }
  
      private Filter ssoFilter() {
          CompositeFilter filter = new CompositeFilter();
          List&lt;Filter&gt; filters = new ArrayList&lt;&gt;();
          filters.add(ssoFilter(gmail(), "/login/gmail"));
          filter.setFilters(filters);
          return filter;
      }
  
      private Filter ssoFilter(ClientResources client, String path) {
          OAuth2ClientAuthenticationProcessingFilter filter = new     OAuth2ClientAuthenticationProcessingFilter(
              path);
          OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
          filter.setRestTemplate(template);
          filter.setTokenServices(JwtConfig.tokenServices());
          return filter;
      }
  
      public static void main(String[] args) {
          SpringApplication.run(MsAuthorizationGmailApplication.class, args);
      }
  
  }
  </code></pre>
  
  <p>In the JWT config I'm not trying to do anything fancy, just trying to make it pass for now:</p>
  
  <pre><code>public final class JwtConfig {
  
      private static final String KEY = "123";
  
      private JwtConfig() {
      }
  
      private static JwtAccessTokenConverter accessTokenConverter() {
          JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
          converter.setSigningKey(KEY);
          return converter;
      }
  
      private static TokenStore tokenStore() {
          return new JwtTokenStore(accessTokenConverter());
      }
  
      public static DefaultTokenServices tokenServices() {
          DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
          defaultTokenServices.setTokenStore(tokenStore());
          defaultTokenServices.setSupportRefreshToken(true);
          return defaultTokenServices;
      }
  }
  </code></pre>
  
  <p>I get the following exception:</p>
  
  <pre><code>org.springframework.security.authentication.BadCredentialsException: Could not obtain user details from token
  at org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:122) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
  at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:112) [spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
  at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73) [spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
  ....
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar:8.5.11]
  at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
  Caused by: org.springframework.security.oauth2.common.exceptions.InvalidTokenException: Cannot convert access token to JSON
  at org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter.decode(JwtAccessTokenConverter.java:287) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  at org.springframework.security.oauth2.provider.token.store.JwtTokenStore.convertAccessToken(JwtTokenStore.java:88) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  at org.springframework.security.oauth2.provider.token.store.JwtTokenStore.readAccessToken(JwtTokenStore.java:80) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  at org.springframework.security.oauth2.provider.token.DefaultTokenServices.loadAuthentication(DefaultTokenServices.java:229) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  at org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:112) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  ... 62 common frames omitted
  Caused by: java.lang.IllegalArgumentException: JWT must have 3 tokens
  at org.springframework.security.jwt.JwtHelper.decode(JwtHelper.java:49) ~[spring-security-jwt-1.0.0.RELEASE.jar:na]
  at org.springframework.security.jwt.JwtHelper.decodeAndVerify(JwtHelper.java:74) ~[spring-security-jwt-1.0.0.RELEASE.jar:na]
  at org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter.decode(JwtAccessTokenConverter.java:277) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na]
  ... 66 common frames omitted
  </code></pre>
  
  <p>How I understand this: It looks like that when Google issues an access token, the authorization server (being a client of Google OAuth) tries to decode the access token as a JWT, and throws an exception because Google's token is not a valid JWT (it's just an access token). </p>
  
  <p>I would like to create a JWT containing the access token (which will be used to access Google APIs) and some additional information about the user. I would also like to be able to refresh the JWT token when the access token expires. Is there any way to achieve this?</p>