SpringSecurity +oauth2获取当前登录用户(二)
创始人
2025-05-30 01:32:06

特别注意:以下内容如果访问失败或有其他疑问,可先学习:

SpringSecurity +oauth2+JWT实现统一授权和认证及项目搭建(一)

1 获取当前用户的信息代码为:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

但是,通过运行会发现principal的值只是用户名,没有用户信息,通过去看源码,才发现问题所在,以下是源码:

源码类:DefaultUserAuthenticationConverter.java

通过源码分析,发现这里的map只存储用户名,对此,如果要获取用户,我这里提供的方案是重写该方法,步骤如下:

新建UserAuthenticationConverter.java配置类,继承DefaultUserAuthenticationConverter.java,代码如下:

package com.yty.system.oauth.config.jwt;import com.yty.system.oauth.entity.SysUser;
import com.yty.system.oauth.entity.vo.SecurityUser;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.util.StringUtils;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;@Configuration
public class UserAuthenticationConverter extends DefaultUserAuthenticationConverter {private Collection defaultAuthorities;public void setDefaultAuthorities(String[] defaultAuthorities) {this.defaultAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.arrayToCommaDelimitedString(defaultAuthorities));}private static final String USER_INFO = "userInfo";/*** 设置存入认证信息中的Map** @param authentication* @return*/@Overridepublic Map convertUserAuthentication(Authentication authentication) {// 入参authentication中保存了完整的用户信息(都已经有完整信息了还查个P)。Map map = new HashMap<>(1);// 获取用户信息并保存。Object o = authentication.getPrincipal();SecurityUser userInfo = (SecurityUser) o;SysUser sysUser = userInfo.getSysUser();map.put(USER_INFO, sysUser);// 保存了账户的权限信息,可以通过Authentication..getAuthorities()方法获取。if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {map.put(AUTHORITIES, AuthorityUtils.authorityListToSet(authentication.getAuthorities()));}return map;}/*** 选择存入认证信息中的数据** @param map* @return*/@Overridepublic Authentication extractAuthentication(Map map) {Authentication authentication = null;if (map.containsKey(USER_INFO)) {// 将用户对象作为用户信息。Object principal = map.get(USER_INFO);Collection authorities = this.getAuthorities(map);authentication = new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);}return authentication;}private Collection getAuthorities(Map map) {if (!map.containsKey(AUTHORITIES)) {return this.defaultAuthorities;} else {Object authorities = map.get(AUTHORITIES);if (authorities instanceof String) {return AuthorityUtils.commaSeparatedStringToAuthorityList((String)authorities);} else if (authorities instanceof Collection) {return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.collectionToCommaDelimitedString((Collection)authorities));} else {throw new IllegalArgumentException("Authorities must be either a String or a Collection");}}}
}

修改JwtTokenStoreConfig.java类,将以上配置类引用到方法jwtAccessTokenConverter中,具体实现如下:

@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();DefaultAccessTokenConverter defaultAccessTokenConverter = new DefaultAccessTokenConverter();defaultAccessTokenConverter.setUserTokenConverter(new UserAuthenticationConverter());// 赋予新的Token转换器。accessTokenConverter.setAccessTokenConverter(defaultAccessTokenConverter);//配置JWT使用的秘钥accessTokenConverter.setSigningKey(secret);return accessTokenConverter;}

在UserDetailService编写静态方法getCurrentUser获取用户信息,代码如下:

/*** 获取当前用户信息*/public static SysUser getCurrentUser() {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (Objects.isNull(authentication)) {throw new RuntimeException("请登录");}Object principal = authentication.getPrincipal();if (Objects.isNull(principal)) {throw new RuntimeException("请登录");}ObjectMapper objectMapper = new ObjectMapper();SysUser sysUser = objectMapper.convertValue(principal, SysUser.class);return sysUser;}

在UserController.java类中编写测试入口方法getCurrentUser,代码如下:


@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/getCurrentUser")public Object getCurrentUser() {SysUser currentUser = UserDetailService.getCurrentUser();return currentUser;}
}

postman访问:

1 先获取token

2 调用接口http://localhost:8500/oauth_api/user/getCurrentUser,注意参数,需要在请求头中添加参数Authorization,内容为:oken_type+空格+access_token,如图所示:

注意,如果访问不通过,需要在资源配置类中将用户访问接口添加到资源配置ResourceServiceConfig.java中,如无该类,自己新建一个,代码如下所示:

package com.yty.system.oauth.config.jwt;import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;@Configuration
@EnableResourceServer
public class ResourceServiceConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated()// 受保护的资源.and().requestMatchers().antMatchers("/user/**");}
}

相关内容

热门资讯

2025上半年哪些国内新游最赚... 文 | 点点数据,作者 | April Z转眼间2025年已经过半,根据今年已经发布的《中国游戏产业...
两度易主、三任托管,这一次弘元... 文 | 华夏能源网在第二次破产重整后,“光伏老厂”无锡尚德迎来新一任托管方。华夏能源网(公众号hxn...
“身价暴涨”500%,蜜雪冰城... 文 | 电商在线“入行十年来,第一次见到这么贵的黄柠檬。”近日,“柠檬疯涨似黄金”“柠檬水成本飙升”...
青岛造芯新势力突击“联动”无锡... 7月11日复牌首日,长龄液压(605389.SH)以一字涨停告别两连跌阴霾,股价强势反弹的核心推力,...
对标泡泡玛特?AI玩具厂商的必... 文|执牛耳传媒从产业基础看,AI 玩具凭借场景多元、客群广泛、产业链成熟等优势,早已成为 AI 技术...