改造上一篇
改造上一篇登出白名单(为什么要改造,后面说)
DefaultTokenServices.createAccessToken()方法里有个一行代码:
OAuth2AccessToken existingAccessToken = this.tokenStore.getAccessToken(authentication);
因此我们要去CustomJwtTokenStore自定义类,重写该方法,参照上一篇白名单方法三,把下面这段代码移除,放到前面重写的类方法中,源码会判断,如果有,则直接返回token,不懂的看源码createAccessToken()方法。
if(!StringUtils.isEmpty(tokenByteStr)){
byte[] tokenByte = Base64.getDecoder().decode(tokenByteStr);
DefaultOAuth2AccessToken tokenSource = (DefaultOAuth2AccessToken) deserializeAccessToken(tokenByte);
//对象默认传递是引用传递,要改变整个对象。如果直接写 token = tokenSource; 是不行的,因为这不能改变对象的指针,默认拿到的还是之前的对象
//想改变对象里面值,有两种办法,1.直接set属性(但是这样一个一个set比较麻烦) 2.直接深复制,就是下面这句话
BeanUtils.copyProperties(tokenSource, accessToken);
}
解决登录单参数,使用PIN多参数
- 复制并改造类UserDetailsByNameServiceWrapper,主要是改该类loadUserDetails()方法,内容是读loadUserByPIN()方法。而loadUserDetails()方法中T authentication参数需要改造类AuthJwtAccessTokenConverter,塞入用户信息,代码如下:
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
if (map.containsKey("user_info")) {
Object principal = map.get("user_info");
// Collection<? extends GrantedAuthority> authorities = getAuthorities(map);
LoginAppUser loginUser = new LoginAppUser();
if (principal instanceof Map) {
loginUser = BeanUtil.mapToBean((Map) principal, LoginAppUser.class, true);
}
return new UsernamePasswordAuthenticationToken(loginUser, "N/A", loginUser.getAuthorities());
}
return super.extractAuthentication(map);
}
完结。
注意
上面这个方法extractAuthentication()有个问题,map里没有userId那个附加信息,需要改类TokenGranterConfig,注释掉:
// @Autowired(required = false)
// private List<TokenEnhancer> tokenEnhancer;
加入:
@Autowired(required = false)
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Autowired
private TokenEnhancer tokenEnhancer;
然后这个方法,改成如下:
private TokenEnhancer tokenEnhancer() {
if (tokenEnhancer != null) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer, jwtAccessTokenConverter));
return tokenEnhancerChain;
}
return null;
}