2017-03-09 24 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" 
} 
相關問題