1、切换角色或者岗位后更新缓存token,获取token,并更新token,特别要注意token中的内容
accessToken.getAdditionalInformation().put(SecurityConstants.DETAILS_POST_ID,postId);
String key = authenticationKeyGenerator.extractKey(originalOAuth2Authentication);
byte[] serializedKey = serializationStrategy.serialize(CacheConstants.PROJECT_OAUTH_ACCESS+"auth_to_access:" + key);
byte[] bytes = null;
RedisConnection conn = redisConnectionFactory.getConnection();
try {
bytes = conn.get(serializedKey);
} finally {
conn.close();
}
OAuth2AccessToken accessToken =serializationStrategy.deserialize(bytes,OAuth2AccessToken.class);
accessToken.getAdditionalInformation().put(SecurityConstants.DETAILS_POST_ID,postId);
tokenStore.storeAccessToken(accessToken,oauth2Authentication);
切换用户后,进行数据的更新。
SysUser user = userService.selectUserByUserName(SecurityUtils.getUser().getUsername());
Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
List postList= postService.selectPostsByUserName(user.getUserName());
user.setPosts(postList);
user.setPostId(postId);
//角色集合
//先查询对应岗位的角色ID
Set roles=postService.selectRoleIdsByPostId(postId);
if(roles.size()<1){
return R.failed("该岗位无权访问系统");
}
user.setRoleIds(roles.toArray(new Integer[roles.size()]));
// 角色集合
//Set roles = permissionService.getRolePermission(sysUser.getUserId());
// 权限集合
//Set permissions = permissionService.getMenuPermission(sysUser.getUserId());
Set permissions = permissionService.getMenuPermissionByRoles(user.getUserId(),roles);
Set dbAuthsSet = new HashSet<>();
if (ArrayUtil.isNotEmpty(roles)) {
// 获取角色
roles.forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
// 获取资源
dbAuthsSet.addAll(permissions);
}
Collection extends GrantedAuthority> authorities = AuthorityUtils
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
// // 构造security用户
UserDetails userDetails =new ItduUser(user.getUserId(),postId, user.getDeptId(), user.getRoles(), user.getUserName(),
SecurityConstants.BCRYPT + user.getPassword(),
StrUtil.equals("0", CommonConstants.STATUS_NORMAL), true, true, true, authorities);
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
if (cache != null) {
cache.put(user.getUserName(), userDetails);
}
ItduUser itduUser = new ItduUser(user.getUserId(),postId, user.getDeptId(), user.getRoles(), user.getUserName(), N_A, true, true, true, true, authorities);
//替换oauth认证的信息里的details,这里就不展示了
if (authentication instanceof OAuth2Authentication) {
OAuth2Authentication originalOAuth2Authentication = (OAuth2Authentication) authentication;
if (!originalOAuth2Authentication.isClientOnly()) {
Authentication userAuthentication = originalOAuth2Authentication.getUserAuthentication();
if (userAuthentication instanceof UsernamePasswordAuthenticationToken) {
//替换用户信息,权限信息根据自己的需求替换,这里直接取原来的
UsernamePasswordAuthenticationToken usernamePasswordAuthentication = new UsernamePasswordAuthenticationToken(itduUser, N_A, authorities);
usernamePasswordAuthentication.setDetails(itduUser);
OAuth2Authentication oauth2Authentication = new OAuth2Authentication(originalOAuth2Authentication.getOAuth2Request(), usernamePasswordAuthentication);
oauth2Authentication.setDetails(itduUser);
String key = authenticationKeyGenerator.extractKey(originalOAuth2Authentication);
byte[] serializedKey = serializationStrategy.serialize(CacheConstants.PROJECT_OAUTH_ACCESS+"auth_to_access:" + key);
byte[] bytes = null;
RedisConnection conn = redisConnectionFactory.getConnection();
try {
bytes = conn.get(serializedKey);
} finally {
conn.close();
}
OAuth2AccessToken accessToken =serializationStrategy.deserialize(bytes,OAuth2AccessToken.class);
accessToken.getAdditionalInformation().put(SecurityConstants.DETAILS_POST_ID,postId);
tokenStore.storeAccessToken(accessToken,oauth2Authentication);
}
}
}
后期使用
SecurityContextHolder.getContext().getAuthentication() 即可获取到当前登陆用户的相关信息
完整代码:
package com.intasect.upms.sys.controller;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.intasect.common.core.constant.CacheConstants;
import com.intasect.common.core.constant.CommonConstants;
import com.intasect.common.core.constant.SecurityConstants;
import com.intasect.common.core.constant.UserConstants;
import com.intasect.common.core.util.R;
import com.intasect.common.core.util.StringUtils;
import com.intasect.common.security.annotation.Inner;
import com.intasect.common.security.service.ItduUser;
import com.intasect.common.security.util.RedisTokenStore;
import com.intasect.common.security.util.SecurityUtils;
import com.intasect.upms.api.domain.SysPost;
import com.intasect.upms.api.domain.SysUser;
import com.intasect.upms.api.model.LoginUser;
import com.intasect.upms.sys.service.ISysPermissionService;
import com.intasect.upms.sys.service.ISysPostService;
import com.intasect.upms.sys.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.access.prepost.PreAuthorize;
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.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* 用户信息
*/
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class SysUserController
{
@Autowired
private ISysUserService userService;
@Autowired
private ISysPostService postService;
@Autowired
private ISysPermissionService permissionService;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
private AuthenticationKeyGenerator authenticationKeyGenerator=new
DefaultAuthenticationKeyGenerator();
private JdkSerializationStrategy serializationStrategy=new JdkSerializationStrategy();
@Autowired
private TokenStore tokenStore;
@Autowired
private CacheManager cacheManager;
private static final String N_A = "N/A";
/**
* 获取用户列表
*/
@PreAuthorize("@pms.hasPermission('system:user:list')")
@GetMapping("/list")
public R list(Page page, SysUser user)
{
return R.ok(userService.selectUserListPage(user,page));
}
/**
* 切换岗位后相关角色和权限的切换
*/
@GetMapping("/switch/{postId}")
public R switchPost(@PathVariable("postId") Integer postId, HttpServletRequest request, HttpServletResponse response){
SysUser user = userService.selectUserByUserName(SecurityUtils.getUser().getUsername());
Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
List postList= postService.selectPostsByUserName(user.getUserName());
user.setPosts(postList);
user.setPostId(postId);
//角色集合
//先查询对应岗位的角色ID
Set roles=postService.selectRoleIdsByPostId(postId);
if(roles.size()<1){
return R.failed("该岗位无权访问系统");
}
user.setRoleIds(roles.toArray(new Integer[roles.size()]));
// 角色集合
//Set roles = permissionService.getRolePermission(sysUser.getUserId());
// 权限集合
//Set permissions = permissionService.getMenuPermission(sysUser.getUserId());
Set permissions = permissionService.getMenuPermissionByRoles(user.getUserId(),roles);
Set dbAuthsSet = new HashSet<>();
if (ArrayUtil.isNotEmpty(roles)) {
// 获取角色
roles.forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
// 获取资源
dbAuthsSet.addAll(permissions);
}
Collection extends GrantedAuthority> authorities = AuthorityUtils
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
// // 构造security用户
UserDetails userDetails =new ItduUser(user.getUserId(),postId, user.getDeptId(), user.getRoles(), user.getUserName(),
SecurityConstants.BCRYPT + user.getPassword(),
StrUtil.equals("0", CommonConstants.STATUS_NORMAL), true, true, true, authorities);
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
if (cache != null) {
cache.put(user.getUserName(), userDetails);
}
ItduUser itduUser = new ItduUser(user.getUserId(),postId, user.getDeptId(), user.getRoles(), user.getUserName(), N_A, true, true, true, true, authorities);
//替换oauth认证的信息里的details,这里就不展示了
if (authentication instanceof OAuth2Authentication) {
OAuth2Authentication originalOAuth2Authentication = (OAuth2Authentication) authentication;
if (!originalOAuth2Authentication.isClientOnly()) {
Authentication userAuthentication = originalOAuth2Authentication.getUserAuthentication();
if (userAuthentication instanceof UsernamePasswordAuthenticationToken) {
//替换用户信息,权限信息根据自己的需求替换,这里直接取原来的
UsernamePasswordAuthenticationToken usernamePasswordAuthentication = new UsernamePasswordAuthenticationToken(itduUser, N_A, authorities);
usernamePasswordAuthentication.setDetails(itduUser);
OAuth2Authentication oauth2Authentication = new OAuth2Authentication(originalOAuth2Authentication.getOAuth2Request(), usernamePasswordAuthentication);
oauth2Authentication.setDetails(itduUser);
String key = authenticationKeyGenerator.extractKey(originalOAuth2Authentication);
byte[] serializedKey = serializationStrategy.serialize(CacheConstants.PROJECT_OAUTH_ACCESS+"auth_to_access:" + key);
byte[] bytes = null;
RedisConnection conn = redisConnectionFactory.getConnection();
try {
bytes = conn.get(serializedKey);
} finally {
conn.close();
}
OAuth2AccessToken accessToken =serializationStrategy.deserialize(bytes,OAuth2AccessToken.class);
accessToken.getAdditionalInformation().put(SecurityConstants.DETAILS_POST_ID,postId);
tokenStore.storeAccessToken(accessToken,oauth2Authentication);
}
}
}
return R.ok();
}
/**
* 获取当前用户信息
*/
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable("username") String username)
{
SysUser sysUser = userService.selectUserByUserName(username);
if (StringUtils.isNull(sysUser))
{
return R.failed("用户名或密码错误");
}
//根据业务需求需要根据岗位来查询相关角色及权限
List postList= postService.selectPostsByUserName(sysUser.getUserName());
//首次登陆默认使用第一个岗位来登陆,使用岗位获取角色。
if(postList.size()<1){
return R.failed("用户暂无所属岗位,无法登陆");
}
sysUser.setPosts(postList);
sysUser.setPostId(postList.get(0).getPostId());
//角色集合
//先查询对应岗位的角色ID
Set roles=postService.selectRoleIdsByPostId(postList.get(0).getPostId());
if (SysUser.isAdmin(sysUser.getUserId()))
{
roles.add(1);
}
if(roles.size()<1){
return R.failed("用户暂无所属角色,无法登陆");
}
// 角色集合
//Set roles = permissionService.getRolePermission(sysUser.getUserId());
// 权限集合
//Set permissions = permissionService.getMenuPermission(sysUser.getUserId());
Set permissions = permissionService.getMenuPermissionByRoles(sysUser.getUserId(),roles);
LoginUser sysUserVo = new LoginUser();
sysUserVo.setSysUser(sysUser);
sysUserVo.setRoles(roles);
sysUserVo.setPermissions(permissions);
return R.ok(sysUserVo);
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("getInfo")
public R getInfoByPost(){
// OAuth2Authentication originalOAuth2Authentication = (OAuth2Authentication)SecurityUtils.getAuthentication();
// OAuth2AccessToken token = tokenStore.getAccessToken(originalOAuth2Authentication);
// OAuth2Authentication authentication=tokenStore.readAuthentication(token);
// ItduUser itduUser=(ItduUser)authentication.getUserAuthentication().getPrincipal();
// Integer userId = itduUser.getId();
SysUser sysUser=userService.selectUserById(SecurityUtils.getUser().getId());
// 角色集合
//Set roles = permissionService.getRolePermission(userId);
// 权限集合
//Set permissions = permissionService.getMenuPermission(userId);
//根据业务需求需要根据岗位来查询相关角色及权限
List postList= postService.selectPostsByUserName(SecurityUtils.getUser().getUsername());
if(postList.size()<1){
return R.failed("用户暂无所属岗位,无法登陆");
}
sysUser.setPosts(postList);
sysUser.setPostId(SecurityUtils.getUser().getPostId());
SysPost sysPost = postService.selectPostById(SecurityUtils.getUser().getPostId());
//角色集合
//先查询对应岗位的角色ID
Set roles=postService.selectRoleIdsByPostId(sysPost.getPostId());
if (SysUser.isAdmin(sysUser.getUserId()))
{
roles.add(1);
}
// 角色集合
//Set roles = permissionService.getRolePermission(sysUser.getUserId());
// 权限集合
//Set permissions = permissionService.getMenuPermission(sysUser.getUserId());
Set permissions = permissionService.getMenuPermissionByRoles(sysUser.getUserId(),roles);
Map map = new HashMap<>();
map.put("user", sysUser);
map.put("roles", roles);
map.put("permissions", permissions);
return R.ok(map);
}
/**
* 根据用户编号获取详细信息
*/
@PreAuthorize("@pms.hasPermission('system:user:query')")
@GetMapping(value = {"/{userId}",""})
public R getInfo(@PathVariable(value = "userId", required = false) Integer userId)
{
Map map = new HashMap<>();
//List roles = roleService.selectRoleAll();
//map.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
map.put("posts", postService.selectPostAll());
if (StringUtils.isNotNull(userId))
{
map.put("user", userService.selectUserById(userId));
map.put("postIds", postService.selectPostListByUserId(userId));
//map.put("roleIds", roleService.selectRoleListByUserId(userId));
}
return R.ok(map);
}
/**
* 新增用户
*/
@PreAuthorize("@pms.hasPermission('system:user:add')")
@PostMapping
public R add(@Validated @RequestBody SysUser user)
{
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
{
return R.failed("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return R.failed("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return R.failed("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setCreateBy(SecurityUtils.getUser().getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
return R.ok(userService.insertUser(user));
}
/**
* 修改用户
*/
@PreAuthorize("@pms.hasPermission('system:user:edit')")
@PutMapping
public R edit(@Validated @RequestBody SysUser user)
{
userService.checkUserAllowed(user);
if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return R.failed("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return R.failed("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(SecurityUtils.getUser().getUsername());
return R.ok(userService.updateUser(user));
}
/**
* 删除用户
*/
@PreAuthorize("@pms.hasPermission('system:user:remove')")
@DeleteMapping("/{userIds}")
public R remove(@PathVariable Integer[] userIds)
{
return R.ok(userService.deleteUserByIds(userIds));
}
/**
* 重置密码
*/
@PreAuthorize("@pms.hasPermission('system:user:edit')")
@PutMapping("/resetPwd")
public R resetPwd(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
user.setUpdateBy(SecurityUtils.getUser().getUsername());
return R.ok(userService.resetPwd(user));
}
/**
* 状态修改
*/
@PreAuthorize("@pms.hasPermission('system:user:edit')")
@PutMapping("/changeStatus")
public R changeStatus(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
user.setUpdateBy(SecurityUtils.getUser().getUsername());
return R.ok(userService.updateUserStatus(user));
}
@Bean
public TokenStore tokenStore() {
RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
tokenStore.setPrefix(CacheConstants.PROJECT_OAUTH_ACCESS);
return tokenStore;
}
}