Oauth2+JWT续签方案

改造上一篇

改造上一篇登出白名单(为什么要改造,后面说)
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多参数

  1. 复制并改造类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;
    }

推荐阅读更多精彩内容