jwt token 附加用户信息_利用 jwt 可以获取用户的额外信息?

List authorityList = AuthorityUtils.createAuthorityList(authSet.toArray( newString[ 0]));

returnnewSecurityUser(sysUser.getId,sysUser.getMobile,sysUser.getUsername,sysUser.getPassword,authorityList);}

3. 在ehance方法中获取当前用户并设置用户信息

publicclassCustomJwtTokenConverterextendsJwtAccessTokenConverter{@OverridepublicOAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication authentication){SecurityUser securityUser = (SecurityUser) authentication.getUserAuthentication.getPrincipal;finalMap additionalInformation = newHashMap<>( 4);additionalInformation.put( "userId", securityUser.getId);additionalInformation.put( "mobile", securityUser.getMobile);...((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(additionalInformation);returnsuper.enhance(oAuth2AccessToken,authentication);}}

如何在资源服务器中获取这些自定义信息

通过上面的配置我们可以往 jwt 的 token 中添加上用户的数据信息,但是在资源服务器中还是获取不到,通过SecurityContextHolder.getContext.getAuthentication.getPrincipal获取到的用户信息 还是只包含用户名。

这里还是得从 token 的转换器入手,默认情况下 JwtAccessTokenConverter 会调用 DefaultUserAuthenticationConverter 中的 extractAuthentication 方法从 token 中获取用户信息。

我们先看看具体实现逻辑:

publicclassDefaultUserAuthenticationConverterimplementsUserAuthenticationConverter{...publicAuthentication extractAuthentication(Map map){if( map.containsKey(USERNAME)) {Object principal = map.get(USERNAME);Collection extends GrantedAuthority> authorities = getAuthorities( map);if(userDetailsService != null) {UserDetails user = userDetailsService.loadUserByUsername((String) map.get(USERNAME));authorities = user.getAuthorities;principal = user;}returnnewUsernamePasswordAuthenticationToken(principal, "N/A", authorities);}returnnull;}...}

在没有注入 UserDetailService 的情况下,oauth2 只会获取用户名 user_name。如果注入了 UserDetailService 就可以返回所有用户信息。

所以这里我们对应的实现方式也有两种:

在资源服务器中也注入 UserDetailService ,这种方法不推荐,资源服务器与认证服务器分开的情况下强行耦合在一起,也需要加入用户认证的功能。

扩展DefaultUserAuthenticationConverter,重写extractAuthentication方法 ,手动取出额外数据,然后在资源服务器配置中将其注入到 AccessTokenConverter 中。

这里我们采用第二种方法实现,实现顺序如下:

1. 自定义 token 解析器,从 jwt token 中解析用户信息。

package com.javadaily.common.security.component;importcom.javadaily.common.security.user.SecurityUser;importorg.springframework.security.authentication.UsernamePasswordAuthenticationToken;importorg.springframework.security.core.Authentication;importorg.springframework.security.core.GrantedAuthority;importorg.springframework.security.core.authority.AuthorityUtils;importorg.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;importorg.springframework.util.StringUtils;

importjava.util.Collection;importjava.util.Map;

publicclassCustomUserAuthenticationConverterextendsDefaultUserAuthenticationConverter{

/*** 重写抽取用户数据方法* @author javadaily* @date 2020/11/18 10:56* @param map 用户认证信息* @return Authentication*/@ OverridepublicAuthenticationextractAuthentication( Map< String, ?> map) {if( map.containsKey( USERNAME)) {Collection extends GrantedAuthority> authorities = getAuthorities( map);Stringusername = ( String) map. get( USERNAME);Integerid = ( Integer) map. get( "userId");Stringmobile = ( String) map. get( "mobile");SecurityUseruser = new SecurityUser(id, mobile, username, "N/A", authorities);returnnew UsernamePasswordAuthenticationToken(user, "N/A", authorities);}returnnull;}

privateCollection extends GrantedAuthority> getAuthorities( Map< String, ?> map) {Objectauthorities = map. get( AUTHORITIES);if(authorities instanceof String) {returnAuthorityUtils.commaSeparatedStringToAuthorityList(( String) authorities);}if(authorities instanceof Collection) {returnAuthorityUtils.commaSeparatedStringToAuthorityList( StringUtils.collectionToCommaDelimitedString(( Collection>) authorities));}thrownew IllegalArgumentException( "Authorities must be either a String or a Collection");}

}

2. 编写自定义token转换器,注入自定义解压器

publicclassCustomAccessTokenConverterextendsDefaultAccessTokenConverter{publicCustomAccessTokenConverter{super.setUserTokenConverter( newCustomUserAuthenticationConverter);}}

3. 在资源服务器中配置类ResourceServerConfig中注入自定义token转换器

@BeanpublicJwtAccessTokenConverter jwtTokenConverter{JwtAccessTokenConverter jwtAccessTokenConverter = newJwtAccessTokenConverter;jwtAccessTokenConverter.setSigningKey( "javadaily");jwtAccessTokenConverter.setAccessTokenConverter( newCustomAccessTokenConverter);returnjwtAccessTokenConverter;}

通过上面三步配置我们再调用 SecurityContextHolder.getContext.getAuthentication.getPrincipal方法时 就可以获取到用户的额外信息了。

当然我们可以再来一个工具类,从上下文中直接获取用户信息:

@UtilityClasspublicclassSecurityUtils{/*** 获取Authentication*/publicAuthentication getAuthentication{returnSecurityContextHolder.getContext.getAuthentication;}publicSecurityUser getUser{Authentication authentication = getAuthentication;if(authentication == null) {returnnull;}returngetUser(authentication);}

/*** 获取当前用户* @paramauthentication 认证信息* @return当前用户*/privatestaticSecurityUser getUser(Authentication authentication){Object principal = authentication.getPrincipal;if(principal instanceofSecurityUser){return(SecurityUser) principal;}returnnull;}}

以上,希望对你有所帮助。返回搜狐,查看更多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值