本文不详述如何创建 JWT,oauth 2.0 服务端可以参考文章: Spring Security oauth2.0 服务端
JWT 添加额外信息
oauth 2.0 JWT 默认返回 OAuth2AccessToken 接口的实现类,默认实现类是 DefaultOAuth2AccessToken,返回字段有 5 个
- access_token:表示访问令牌,必选项
- token_type:表示令牌类型,该值大小写不敏感,必选项,默认是 bearer 类型
- expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
- refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
- scope:表示权限范围,如果与客户端申请的范围一致,此处可省略
TokenEhancer
实现 TokenEhancer(令牌增强器)接口
- DefaultOAuth2AccessToken:默认的 token 实现类
- setAdditionalInformation:添加其他信息,参数类型是 Map<String, Object>
- 添加自定义的 fat 字段
@Bean
public TokenEnhancer customTokenEnhancer() {
return (accessToken, authentication) -> {
final Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("fat", "test");
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
};
}
AuthorizationServerEndpointsConfigurer
把 TokenEnhancer 添加到 AuthorizationServerConfigurerAdapter 里
- 创建 TokenEnhancerChain,传参类型为 list
- 创建 DefaultTokenServices,传入 TokenEnhancerChain
- endpoints 传入 DefaultTokenServices
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
...
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter(), customTokenEnhancer()));
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenEnhancer(enhancerChain);
tokenServices.setTokenStore(tokenStore());
endpoints
.authenticationManager(authenticationManager)
.tokenServices(tokenServices)
;
}
...
}
访问 /oauth/token 接口时,返回值返回插入的 fat 字段
JWT 解析发现没有 fat 字段
**踩坑:**这里有一个值得注意的地方了,若要 JWT 解析时有新增字段,在 setTokenEnhancers 时,参数 list 需要把自定义的 customTokenEnhancer() 放前面
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(), jwtAccessTokenConverter()));
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenEnhancer(enhancerChain);
tokenServices.setTokenStore(tokenStore());
endpoints
.authenticationManager(authenticationManager)
.tokenServices(tokenServices)
;
}
check/token 添加额外信息
自定义 AccessTokenConverter
- 继承 DefaultAccessTokenConverter
- 重新 convertAccessToken 方法,添加需要新增的字段
@Configuration
public class AuthAccessTokenConverter extends DefaultAccessTokenConverter {
@Override
public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
Map<String, Object> response = (Map<String, Object>) super.convertAccessToken(token, authentication);
response.put("feng","myfat");
return response;
}
}
把新建的 AccessTokenConverter 放进配置里
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthAccessTokenConverter converter;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
...
endpoints.accessTokenConverter(converter);
}
}