2017-03-09 112 views
2

我想使用Spring Oauth创建授权服务器,该服务器能够发布自己的JWT令牌。授权服务器必须将身份验证委托给Google。我一直在关注这个教程,它几乎可以做任何我想要的东西:https://spring.io/guides/tutorials/spring-boot-oauth2/向Google进行身份验证时从Spring OAuth2授权服务器发出JWT令牌

我能够将Google添加为身份验证提供程序,但我正在努力使用JWT部分。

这里是我的授权服务器的配置:

@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<Filter> filters = new ArrayList<>(); 
     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); 
    } 

} 

在JWT配置我不想做任何幻想,只是想使之通过现在:

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; 
    } 
} 

我得到的以下情况除外:

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 

如何理解这一点:它看起来像,当谷歌发出访问令牌,授权服务器(作为Google OAuth的客户端)尝试将访问令牌解码为JWT,并抛出异常,因为Google的令牌不是有效的JWT(它只是一个访问令牌)。

我想创建一个包含访问令牌(将用于访问Google API)的JWT和一些关于用户的附加信息。我还希望能够在访问令牌到期时刷新JWT令牌。有什么办法可以做到这一点?

回答

0

我不确定GMail,但对于您自己的授权服务器,您可以添加一个令牌增强器JwtAccessTokenConverter,它可以将令牌转换为JWT。

样本,请参阅oauth2-spring-boot-mongo-jwt-sample

通常,正常令牌有效载荷是以下类型

{ 
    "access_token": "bc9c021f-b5ae-43af-9746-737b533f9bc5", 
    "token_type": "bearer", 
    "refresh_token": "fee7a2a1-eff9-4757-8dd3-5392ee225bea", 
    "expires_in": 43199, 
    "scope": "read-foo" } 

而,JWT看起来像这样

{ 
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiZm9vIl0sInVzZXJfbmFtZSI6InVzZXIiLCJzY29wZSI6WyJyZWFkLWZvbyJdLCJleHAiOjE1MTQ3ODMwNTIsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiJlMjM4MDg1YS0xZjFjLTQ5ZWQtODNiMC1iN2Q1MjI5OWUwZjYiLCJjbGllbnRfaWQiOiJ3ZWItY2xpZW50In0.-OSw1Vr4o1dnAQL3n7QFGG6UOXr4itc0Kp8dugyT4zU", 
    "token_type": "bearer", 
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiZm9vIl0sInVzZXJfbmFtZSI6InVzZXIiLCJzY29wZSI6WyJyZWFkLWZvbyJdLCJhdGkiOiJlMjM4MDg1YS0xZjFjLTQ5ZWQtODNiMC1iN2Q1MjI5OWUwZjYiLCJleHAiOjE1MTczMzE4NTIsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiIzYTA2OTZmMy1mYzg1LTQ2YTEtYjVlMC01NmQ2OGVmYTJhMmUiLCJjbGllbnRfaWQiOiJ3ZWItY2xpZW50In0.jSBriPfM-rSgHHLyifIuBHwrwCkyb5I2u2AKa8kQUUU", 
    "expires_in": 43199, 
    "scope": "read-foo", 
    "jti": "e238085a-1f1c-49ed-83b0-b7d52299e0f6" 
} 
相关问题