spring security oauth2 动态切换角色或者岗位,更新redis缓存

2023-11-20

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<SysPost> postList= postService.selectPostsByUserName(user.getUserName());
        user.setPosts(postList);
        user.setPostId(postId);
        //角色集合
        //先查询对应岗位的角色ID
        Set<Integer> roles=postService.selectRoleIdsByPostId(postId);
        if(roles.size()<1){
            return R.failed("该岗位无权访问系统");
        }
        user.setRoleIds(roles.toArray(new Integer[roles.size()]));
        // 角色集合
        //Set<Integer> roles = permissionService.getRolePermission(sysUser.getUserId());
        // 权限集合
        //Set<String> permissions = permissionService.getMenuPermission(sysUser.getUserId());
        Set<String> permissions = permissionService.getMenuPermissionByRoles(user.getUserId(),roles);
        Set<String> 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<SysPost> postList= postService.selectPostsByUserName(user.getUserName());
        user.setPosts(postList);
        user.setPostId(postId);
        //角色集合
        //先查询对应岗位的角色ID
        Set<Integer> roles=postService.selectRoleIdsByPostId(postId);
        if(roles.size()<1){
            return R.failed("该岗位无权访问系统");
        }
        user.setRoleIds(roles.toArray(new Integer[roles.size()]));
        // 角色集合
        //Set<Integer> roles = permissionService.getRolePermission(sysUser.getUserId());
        // 权限集合
        //Set<String> permissions = permissionService.getMenuPermission(sysUser.getUserId());
        Set<String> permissions = permissionService.getMenuPermissionByRoles(user.getUserId(),roles);
        Set<String> 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<LoginUser> info(@PathVariable("username") String username)
    {
        SysUser sysUser = userService.selectUserByUserName(username);
        if (StringUtils.isNull(sysUser))
        {
            return R.failed("用户名或密码错误");
        }

        //根据业务需求需要根据岗位来查询相关角色及权限
       List<SysPost> postList= postService.selectPostsByUserName(sysUser.getUserName());
        //首次登陆默认使用第一个岗位来登陆,使用岗位获取角色。

        if(postList.size()<1){
            return R.failed("用户暂无所属岗位,无法登陆");
        }

        sysUser.setPosts(postList);
        sysUser.setPostId(postList.get(0).getPostId());
        //角色集合
        //先查询对应岗位的角色ID
        Set<Integer> roles=postService.selectRoleIdsByPostId(postList.get(0).getPostId());
        if (SysUser.isAdmin(sysUser.getUserId()))
        {
            roles.add(1);
        }
        if(roles.size()<1){
            return R.failed("用户暂无所属角色,无法登陆");
        }

        // 角色集合
        //Set<Integer> roles = permissionService.getRolePermission(sysUser.getUserId());
        // 权限集合
        //Set<String> permissions = permissionService.getMenuPermission(sysUser.getUserId());
        Set<String> 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<Integer> roles = permissionService.getRolePermission(userId);
        // 权限集合
        //Set<String> permissions = permissionService.getMenuPermission(userId);

        //根据业务需求需要根据岗位来查询相关角色及权限
        List<SysPost> 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<Integer> roles=postService.selectRoleIdsByPostId(sysPost.getPostId());
        if (SysUser.isAdmin(sysUser.getUserId()))
        {
            roles.add(1);
        }
        // 角色集合
        //Set<Integer> roles = permissionService.getRolePermission(sysUser.getUserId());
        // 权限集合
        //Set<String> permissions = permissionService.getMenuPermission(sysUser.getUserId());
        Set<String> permissions = permissionService.getMenuPermissionByRoles(sysUser.getUserId(),roles);
        Map<String,Object> 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<String,Object> map = new HashMap<>();
        //List<SysRole> 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;
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring security oauth2 动态切换角色或者岗位,更新redis缓存 的相关文章

  • AI合同比对:提高合同审核效率的利器

    每到合同签署前期 审稿员小火就被淹没在了不同版本的合同中 即使有些是制式合同 但为了防止合同被修改过 小火仍需要对不同版本的全部条款做确认 其中涉及到的文本审核工作量巨大 一旦错漏 可能会造成不可估量的影响 为了解决了人工比对合同时间长 风

随机推荐