我正在尝试在Spring Boot OAuth项目中使用JWT令牌。
以这种方式完成授权服务器的基本配置
@Configuration
@EnableAuthorizationServer
public class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authManager;
@Autowired
private TokenEnhancer tokenEnhancer;
@Autowired
private TokenStore tokenStore;
@Autowired
private AccessTokenConverter accessTokenConverter;
private final Logger logger = LoggerFactory.getLogger(AuthServerConfiguration.class);
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter)
.authenticationManager(authManager);
}
}
如果我尝试获取令牌,则会得到正确的答复
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdF9hcGkiXSwidXNlcl9uYW1lIjoiYWRtaW5AYWRtaW4uaXQiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXhwIjoxNTUzNzI1NTk4LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjY1ZjNmZjQ0LTdlNTUtNGVlMS1hZDc4LTQyODFmZjEyY2E4MSIsImNsaWVudF9pZCI6InRlc3QifQ.8rXk3zzD9WUPhJ6Ehqot4tlkOWVJI0_NwNAdrsftNx0",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdF9hcGkiXSwidXNlcl9uYW1lIjoiYWRtaW5AYWRtaW4uaXQiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiYXRpIjoiNjVmM2ZmNDQtN2U1NS00ZWUxLWFkNzgtNDI4MWZmMTJjYTgxIiwiZXhwIjoxNTUzNzI1NTk4LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjlmNWViMmM0LTMzODMtNDlmMi05MTViLTJhNGNhZWZiNTA2ZiIsImNsaWVudF9pZCI6InRlc3QifQ.zTQZjrLMV5aJ7bkumvXWeh1npxVD-CDdldSwEsju3kk",
"expires_in": 35999,
"scope": "read write",
"jti": "65f3ff44-7e55-4ee1-ad78-4281ff12ca81"
}
这看起来是正确的jwt令牌(已通过jwt.io测试)
现在我想增强令牌,所以我做了一个CustomTokenEnhancer
public class CustomTokenEnhancer implements TokenEnhancer{
@Autowired
private IUserService userService;
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<>();
User user = userService.findByEmail(authentication.getName());
additionalInfo.put("userId", user.getUserId());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(
additionalInfo);
return accessToken;
}
}
并将其添加到AuthorizationServer中,因此configure
方法现在是
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer, (TokenEnhancer)accessTokenConverter));
endpoints.tokenStore(tokenStore)
.tokenEnhancer(tokenEnhancer)
.authenticationManager(authManager);
}
这是我配置所有JTW功能的地方
@Configuration
public class JWTConfig {
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("AAA");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
此实现后,当我索取令牌时,它看起来像是带有额外声明的普通access_token,没有JWT
{
"access_token": "cfc28147-10fe-4abb-bb0a-bdf79b452f82",
"token_type": "bearer",
"refresh_token": "81467402-8494-4d89-aa35-7345313f372a",
"expires_in": 35999,
"scope": "read write",
"userId": 1
}
有些东西在增强令牌时会改变其性质...