特别注意:以下内容如果访问失败或有其他疑问,可先学习:
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<? extends GrantedAuthority> defaultAuthorities;
public void setDefaultAuthorities(String[] defaultAuthorities) {
this.defaultAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.arrayToCommaDelimitedString(defaultAuthorities));
}
private static final String USER_INFO = "userInfo";
/**
* 设置存入认证信息中的Map
*
* @param authentication
* @return
*/
@Override
public Map<String, ?> convertUserAuthentication(Authentication authentication) {
// 入参authentication中保存了完整的用户信息(都已经有完整信息了还查个P)。
Map<String, Object> 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
*/
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
Authentication authentication = null;
if (map.containsKey(USER_INFO)) {
// 将用户对象作为用户信息。
Object principal = map.get(USER_INFO);
Collection<? extends GrantedAuthority> authorities = this.getAuthorities(map);
authentication = new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
}
return authentication;
}
private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> 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中,具体实现如下:
@Bean
public 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,如图所示:文章来源:https://www.toymoban.com/news/detail-411501.html
注意,如果访问不通过,需要在资源配置类中将用户访问接口添加到资源配置ResourceServiceConfig.java中,如无该类,自己新建一个,代码如下所示:文章来源地址https://www.toymoban.com/news/detail-411501.html
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 {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
// 受保护的资源
.and().requestMatchers()
.antMatchers("/user/**");
}
}
到了这里,关于SpringSecurity +oauth2获取当前登录用户(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!