news 2026/4/16 14:17:22

使用 SpringBoot + AOP 实现简单的用户权限控制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 SpringBoot + AOP 实现简单的用户权限控制

前置安排:这里的权限控制使用的是五张 MySQL 表:分别为:

用户表、角色表、权限表、用户角色表(存储用户id和角色id的绑定关系)、角色权限表(存储角色id和权限id的绑定关系)

1、自定义注解,读取自定义的权限码

@Target(ElementType.METHOD) //表示该注解只能用于方法上 @Retention(RetentionPolicy.RUNTIME) //表示注解会在运行时保留 public @interface CheckPermission { String[] value(); // 定义需要的权限 }

切面类定义

@Aspect @Component public class PermissionAspect { private final PermissionService permissionService; //private final HttpServletRequest request; public PermissionAspect(PermissionService permissionService) { this.permissionService = permissionService; //this.request = request; } @Before("@annotation(checkPermission)") public void checkUserPermission(JoinPoint joinPoint, CheckPermission checkPermission) throws Exception { // 从请求头中获取用户ID //String userIdHeader = request.getHeader("User-Id"); // if (userIdHeader == null) { // throw new Exception("请求头中未找到 User-Id"); // } Long userId = Long.parseLong("1"); // 获取注解中所需的权限 String[] requiredPermissions = checkPermission.value(); // 校验用户是否具备指定权限 for (String permission : requiredPermissions) { System.out.println("permission = " + permission); if (!permissionService.hasPermission(userId, permission)) { throw new Exception("用户无权访问: " + permission); } } } }

注意:在 PermissionAspect 类中,去判断该用户是否拥有此权限。一般是根据用户的 id 传参,用户的id一般是在请求头中获取的,我这里为了方便,把用户的id写死为了 “1”。

@Service public class PermissionService { @Autowired private PermissionMapper permissionMapper; public boolean hasPermission(Long userId, String permissionName) { Set<String> userPermissions = permissionMapper.selectPermissionByUserId(userId); for (String permission : userPermissions) { if (permission.equals(permissionName)) { return true; } } return false; } }

2、根据用户的id关联查询权限码

@Mapper public interface PermissionMapper { Set<String> selectPermissionByUserId(@Param("userId") Long userId); }

XML语句

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.soft.mapper.PermissionMapper"> <select id="selectPermissionByUserId" resultType="java.lang.String" parameterType="map"> SELECT p.permission_name from users u left join user_role ur on u.id = ur.user_id left join roles r on ur.role_id = r.id left join role_permission rp on r.id = rp.role_id left join permissions p on rp.permission_id = p.id where u.id = #{userId} </select> </mapper>

3、在controller层使用权限校验

@RestController public class PermissopnController { //@CheckPermission({"100001", "100002"}) @CheckPermission("100001") @GetMapping("/hello") public String test1(){ return "hello world permission"; } }

注意:该权限码必须是该登录用户拥有的权限码,只有拥有权限码的用户才能访问该接口,如果是多个权限码,可以使用 {"权限码","权限码"} ,在这里多个权限码是并集。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 12:46:57

Java面试题及答案整理(2026最新版,后端通用)

Java学到什么程度可以面试工作&#xff1f; 要达到能够面试Java开发工作的水平&#xff0c;需要掌握以下几个方面的知识和技能&#xff1a; 1. 基础扎实&#xff1a;熟悉Java语法、面向对象编程概念、异常处理、I/O流等基础知识。这是所有Java开发者必备的基础&#xff0c;也…

作者头像 李华
网站建设 2026/4/16 10:20:08

C++ 数组引用

一、先搞懂&#xff1a;为什么需要数组引用&#xff1f; 先看 C 语言 / 普通 C 代码的痛点&#xff1a;数组作为函数参数时&#xff0c;会自动退化为指向首元素的指针&#xff0c;丢失数组的长度信息和数组类型&#xff0c;比如&#xff1a; cpp 运行 #include <iostrea…

作者头像 李华
网站建设 2026/4/16 10:16:30

CNVD证书挖掘:20大技巧,一网打尽安全漏洞!

CNVD证书挖掘&#xff1a;20大技巧&#xff0c;一网打尽安全漏洞&#xff01; 在网络安全领域&#xff0c;CNVD&#xff08;国家信息安全漏洞共享平台&#xff09;证书不仅是技术能力的证明&#xff0c;更是求职、晋升的“硬通货”。本文将从证书获取条件、20种实战方法到核心…

作者头像 李华
网站建设 2026/4/16 10:19:33

存储涨价,预算吃紧,项目还得上,我该怎么办?

推荐阅读 zData X数据库一体机之存储压缩技术解析&#xff1a;应对SSD涨价危机的降本增效方案 END 数据驱动&#xff0c;成就未来&#xff0c;云和恩墨&#xff0c;不负所托&#xff01; 云和恩墨创立于2011年&#xff0c;是业界领先的“智能的数据技术提供商”。公司以“数据驱…

作者头像 李华
网站建设 2026/4/16 10:17:56

【异常】解决 Windows PowerShell 无法识别 ‘claude‘ 命令的实战指南

在使用 Anthropic 推出的终端 AI 工具 Claude Code 时,许多 Windows 用户在配置完环境变量后会遇到“无法识别命令”的报错。本文将带你快速复现问题并提供三种解决方案。 一、报错内容 在 PowerShell 中尝试通过环境变量启动 Claude Code 时,出现如下错误: PS E:\exe\CC&…

作者头像 李华