在使用Google进行身份验证时,从Spring OAuth2授权服务器发出JWT令牌
我想使用SpringOAuth创建一个授权服务器,它能够发布自己的JWT令牌。授权服务器必须将身份验证委托给Google。我一直在遵循本教程,它几乎完成了我想要的一切: 我能够将Google添加为身份验证提供商,但我正在努力解决JWT部分的问题 以下是我的授权服务器配置:在使用Google进行身份验证时,从Spring OAuth2授权服务器发出JWT令牌,jwt,google-oauth,spring-oauth2,Jwt,Google Oauth,Spring Oauth2,我想使用SpringOAuth创建一个授权服务器,它能够发布自己的JWT令牌。授权服务器必须将身份验证委托给Google。我一直在遵循本教程,它几乎完成了我想要的一切: 我能够将Google添加为身份验证提供商,但我正在努力解决JWT部分的问题 以下是我的授权服务器配置: @SpringBootApplication @EnableOAuth2Client @EnableAuthorizationServer @Order(SecurityProperties.ACCESS_OVERRIDE_
@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);
}
}
我得到以下例外情况:
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发布访问令牌时,授权服务器(作为Google OAuth的客户端)试图将访问令牌解码为JWT,并抛出异常,因为Google的令牌不是有效的JWT(它只是一个访问令牌)
我想创建一个JWT,其中包含访问令牌(将用于访问GoogleAPI)和一些关于用户的附加信息。我还希望能够在访问令牌过期时刷新JWT令牌。有什么办法可以做到这一点吗?我不确定GMail,但对于您自己的授权服务器,您可以添加一个令牌增强器
JwtAccessTokenConverter
,它将您的令牌转换为JWT
有关样品,请参考
通常,正常令牌有效负载为以下类型
{
"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"
}
{
"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"
}