本文将结合SpringSecurityOAuth2采用JWT生成Token的模式自定义JWT数据内容,主要重点是在JWT自定义数据,所以不会过多介绍SpringSecurityOAuth2相关东西,详情请看过往文章
1.添加自定义JWT数据模板
/**
* @author TAO
* @description: 给生成的jwt签名中添加自定义数据
* @date 2020/12/12 0:20
*/
@Slf4j
public class TokenJwtEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
log.info("给生成的jwt签名中添加自定义数据");
// info是要往JWT中放入的信息
Map<String, String> requestParameters = authentication.getOAuth2Request().getRequestParameters();//端点信息
System.out.println(requestParameters.toString());
Authentication userAuthentication = authentication.getUserAuthentication();//登录用户信息
log.info("username===>" + userAuthentication.getName());
Map<String, Object> info = new HashMap<>();
info.put("rsss", "ssssssssssss");
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);//设置附加信息
return accessToken;
}
}
2.编写JWT生成Token配置
/*
* @description: Token相关配置
* @author TAO
* @date 2020/12/1 21:13
*/
@Configuration
public class TokenConfig {
private String SIGNING_KEY = "yiyi";
@Bean
public TokenStore tokenStore() {
//JWT令牌存储方案
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY); //对称秘钥,资源服务器使用该秘钥来验证
return converter;
}
//JWT添加自定义数据
@Bean
@ConditionalOnMissingBean(name="jwtTokenEnhancer")//这里中的是为了让我们自己的业务系统也可以提供自己的自定义数据模板
public TokenEnhancer jwtTokenEnhancer(){
return new TokenJwtEnhancer();
}
}
3.应用JWT生成Token配置
方式1
认证服务器中添加代码
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
public UserDetailsService userDetailsService;
@Autowired
private TokenEnhancer jwtTokenEnhancer;//自定义jwt生成数据模板
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {//配置令牌的访问端点和令牌服务
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
TokenEnhancerChain enhancerChain=new TokenEnhancerChain();
List<TokenEnhancer> enhancers=new ArrayList<>();
enhancers.add(jwtTokenEnhancer);
enhancers.add(jwtAccessTokenConverter);//将普通的token转换为jwt
enhancerChain.setTokenEnhancers(enhancers);
endpoints
.tokenEnhancer(enhancerChain)
;
}
方式
认证服务器中添加代码
@Autowired
private TokenStore tokenStore;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
public UserDetailsService userDetailsService;
@Autowired
private TokenEnhancer jwtTokenEnhancer;//自定义jwt生成数据模板
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {//配置令牌的访问端点和令牌服务
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)//若无,refresh_token会有UserDetailsService is required错误
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST)
.tokenServices(tokenService());
}
//令牌管理服务
@Primary
@Bean
public AuthorizationServerTokenServices tokenService() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时
defaultTokenServices.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天
defaultTokenServices.setClientDetailsService(clientDetailsService);//客户端详情服务
defaultTokenServices.setSupportRefreshToken(true);//支持刷新令牌
defaultTokenServices.setTokenStore(tokenStore);//令牌存储策略
//令牌转由普通令牌转换为JWT
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancers=new ArrayList<>();
enhancers.add(jwtTokenEnhancer);//自定义JWT模板
enhancers.add(jwtAccessTokenConverter);
tokenEnhancerChain.setTokenEnhancers(enhancers);
//令牌转由普通令牌转换为JWT
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
//
return defaultTokenServices;
}
两种配置写法走完完整的授权码流程后可以看到JWT解析出来的数据信息是包含了我们的自定义数据的
这里由于我配置的时候发现两种方式改动一下授权界面的样式就不同,这个我还没弄清楚原因,示例代码我贴一下
方式一
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
;
TokenEnhancerChain enhancerChain=new TokenEnhancerChain();
List<TokenEnhancer> enhancers=new ArrayList<>();
enhancers.add(jwtTokenEnhancer);
enhancers.add(jwtAccessTokenConverter);
enhancerChain.setTokenEnhancers(enhancers);
endpoints
.tokenEnhancer(enhancerChain)
//添加这行
.accessTokenConverter(jwtAccessTokenConverter);//将普通的token转换为jwt
;
方式二
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)//若无,refresh_token会有UserDetailsService is required错误
.tokenStore(tokenStore)//添加这行
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST)
.tokenServices(tokenService());
授权界面就变成下面这种了
至于为什么是这样欢迎同行评论解答