05.扩展jwt

  1. 新增一个UserDetailsExpand,继承User(注意是Spring Security的User),添加一些想要扩展的字段
@Getter
@Setter
public class UserDetailsExpand extends User {
    public UserDetailsExpand(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
    }
    //扩展的信息写这

    private String id;
    //电子邮箱
    private String email;
    //手机号
    private String mobile;
    private String nickname;

}
  1. 在UserDetailsService中返回定义的扩展UserDetailsExpand
@Component("UsernamePasswordUserDetailService")
public class UsernamePasswordUserDetailService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        User user = userMapper.loadUserByUsername(s);

        List<String> permissions = new ArrayList<>();
        permissions.add("p1");

        String[] authorities = permissions.toArray(new String[0]);

        UserDetails userDetails = org.springframework.security.core.userdetails.User.withUsername(user.getUsername()).password(user.getPassword()).authorities(authorities).build();


        UserDetailsExpand userDetailsExpand = new UserDetailsExpand(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());

        userDetailsExpand.setId(user.getId());
        userDetailsExpand.setEmail(user.getEmail());
        userDetailsExpand.setMobile(user.getMobile());
        userDetailsExpand.setNickname(user.getNickname());

        return userDetailsExpand;

    }
}

  1. 新增一个TokenEnhancer

/**
 * @ClassName MyTokenEnhancer
 * @Description TODO
 * @Author CY
 * @Date 2023/11/22 16:02
 * @Version 1.0
 */
@Slf4j
@Component("MyTokenEnhancer")
public class MyTokenEnhancer implements TokenEnhancer {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        Map<String,Object> additionalInfo = new HashMap<>();
        Object principal = authentication.getPrincipal();
        try {
            String s = objectMapper.writeValueAsString(principal);
            log.info("{}",s);
            Map map = objectMapper.readValue(s, Map.class);
            //将一些不想要的字段剔除
            map.remove("password");
            map.remove("authorities");
            map.remove("accountNonExpired");
            map.remove("accountNonLocked");
            map.remove("credentialsNonExpired");
            map.remove("enabled");
            additionalInfo.put("user_info",map);
            ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo);
        } catch (IOException e) {
            log.error("",e);
        }
        return accessToken;
    }
}


  1. 在配置AuthorizationServerTokenServices时添加定义的TokenEnhancer:
@Bean(name="authorizationServerTokenServicesCustom")
    public AuthorizationServerTokenServices tokenService() {
        DefaultTokenServices service=new DefaultTokenServices();
        service.setSupportRefreshToken(true);//支持刷新令牌
        service.setTokenStore(tokenStore);//令牌存储策略

        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        //配置扩展信息,一定要将自定义的TokenEnhancer放在前面,否则无效
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(myTokenEnhancer,accessTokenConverter));
        service.setTokenEnhancer(tokenEnhancerChain);

        service.setClientDetailsService(clientDetails());//设置客户端信息

        service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时
        service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天
        return service;
    }

//配置扩展信息,一定要将自定义的TokenEnhancer放在前面,否则无效

这是为什么呢?

因为JwtAccessTokenConverter也是一个TokenEnhancer,他会从map中取出值,然后生成token。如果自定义的tokenEnhancer放在了JwtAccessTokenConverter的后面,那token已经生成了,所以就无效了。

public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
		DefaultOAuth2AccessToken result = new DefaultOAuth2AccessToken(accessToken);
		Map<String, Object> info = new LinkedHashMap<String, Object>(accessToken.getAdditionalInformation());
		String tokenId = result.getValue();
		if (!info.containsKey(TOKEN_ID)) {
			info.put(TOKEN_ID, tokenId);
		}
		else {
			tokenId = (String) info.get(TOKEN_ID);
		}
		result.setAdditionalInformation(info);//将自定义的放入
		result.setValue(encode(result, authentication));//将自定义的信息一起生成token
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值