package com.zsElectric.boot.security.service; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.zsElectric.boot.common.constant.RedisConstants; import com.zsElectric.boot.security.util.SecurityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.PatternMatchUtils; import java.util.*; /** * SpringSecurity 权限校验 * * @author haoxr * @since 2022/2/22 */ @Component("ss") @RequiredArgsConstructor @Slf4j public class PermissionService { private final RedisTemplate redisTemplate; /** * 判断当前登录用户是否拥有操作权限 * * @param requiredPerm 所需权限 * @return 是否有权限 */ public boolean hasPerm(String requiredPerm) { log.info("========== 权限校验开始 =========="); log.info("所需权限: {}", requiredPerm); if (StrUtil.isBlank(requiredPerm)) { log.warn("权限标识为空,拒绝访问"); return false; } // 超级管理员放行 if (SecurityUtils.isRoot()) { log.info("超级管理员,直接放行"); return true; } // 获取当前登录用户的角色编码集合 Set roleCodes = SecurityUtils.getRoles(); log.info("当前用户角色: {}", roleCodes); if (CollectionUtil.isEmpty(roleCodes)) { log.warn("用户角色为空,拒绝访问"); return false; } // 获取当前登录用户的所有角色的权限列表 Set rolePerms = this.getRolePermsFormCache(roleCodes); log.info("角色拥有的权限列表: {}", rolePerms); if (CollectionUtil.isEmpty(rolePerms)) { log.warn("角色权限为空(Redis缓存中无数据),拒绝访问"); return false; } // 判断当前登录用户的所有角色的权限列表中是否包含所需权限 boolean hasPermission = rolePerms.stream() .anyMatch(rolePerm -> // 匹配权限,支持通配符(* 等) PatternMatchUtils.simpleMatch(rolePerm, requiredPerm) ); if (!hasPermission) { log.error("用户无操作权限:{}",requiredPerm); } return hasPermission; } /** * 从缓存中获取角色权限列表 * * @param roleCodes 角色编码集合 * @return 角色权限列表 */ public Set getRolePermsFormCache(Set roleCodes) { // 检查输入是否为空 if (CollectionUtil.isEmpty(roleCodes)) { return Collections.emptySet(); } Set perms = new HashSet<>(); // 从缓存中一次性获取所有角色的权限 Collection roleCodesAsObjects = new ArrayList<>(roleCodes); List rolePermsList = redisTemplate.opsForHash().multiGet(RedisConstants.System.ROLE_PERMS, roleCodesAsObjects); for (Object rolePermsObj : rolePermsList) { if (rolePermsObj instanceof Set) { @SuppressWarnings("unchecked") Set rolePerms = (Set) rolePermsObj; perms.addAll(rolePerms); } } return perms; } }