使用自定义注解和AOP管理shiro权限
一、场景
在使用shiro框架的时候,遇到了这样的需求:本系统有多个用户,每个用户分配不同角色,每个角色的权限也不一致。比如A用户拥有新闻列表的增删改查权限,而B用户只有查看新闻列表的权限,而没有删除、新增、修改的权限,此时有3种方案:1、不给B用户分配删除、新增、修改的菜单,这样用户就无法点击从而无法操作。2、给B用户分配菜单,后台中进行增删改查操作时都要进行权限验证。 3、给B用户分配菜单并且进行操作的时候校验权限。
显然,第2、3种方案比第1中方案要安全。本系统中使用第二种方案。
二、为什么使用注解+AOP
使用shiro过程中一般都会自定义Realm,Realm主要进行权限和登录的校验,当校验登录用户是否有某个权限的时候,有2种方式:1、使用注解 @RequiresPermissions("news:*") 来判断用户是否有news的所有权限。 2、使用Subject.isPermitted("news:*") 方法判断用户是否有news的所有权限。
这两种方法的区别在于,第一种:比如当前用户在新闻列表中删除某篇新闻,但是该用户并没有这种权限,此时会抛出异常,我们需要处理异常即可,但是页面进行跳转,我们希望用户在新闻列进行删除操作的时候,如果没有该权限则会弹窗提示,而不是跳转到统一的异常页面。 第二种,可以实现第一种的不足,但是没有第一种方便快捷。
为了综合上述两种的有点以及缺点,实现shiro校验权限时有异常但不刷新页面,同时以注解的形式使用。
三、实现
实现的效果:需要校验权限的方法比如删除方法del(),只要在该方法上添加自定义注解,即可实现上述效果。
3.1 自定义注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * 类名 :权限控制注解 * 用法 : * 创建人 : shyroke * 时间:2018/12/18 10:33 */ @Documented @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface PermissionAnnotation { String permissionName(); } |
3.2 编写切面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /** * 类名 :权限的切面类 * 用法 : * 创建人 : shyroke * 时间:2018/12/18 10:38 */ @Aspect @Component public class PermissionAspect { @Pointcut ( "@annotation(com.shyroke.daydayzhuan.util.PermissionAnnotation)" ) private void permisson(){ } /** * 给添加PermissionAnnotation注解的方法校验权限,而不必每个方法内都判断权限 * @param joinPoint * @param permissionAnnotation * @return * @throws Throwable */ @Around ( "permisson()&&@annotation(permissionAnnotation)" ) public Object advice(ProceedingJoinPoint joinPoint, PermissionAnnotation permissionAnnotation) throws Throwable { R r = null ; r = (R) joinPoint.proceed(); String permissionName =permissionAnnotation.permissionName(); if (StringUtils.isEmpty(permissionName)){ r.setFlag( false ); r.setMessage( "权限名称不能为空" ); return r; } //校验当前登录用户是否有该权限 boolean isPermission = UserUtils.isPermission(permissionName); if (!isPermission){ r.setFlag( false ); r.setMessage( "没有此操作权限!" ); } return r; } } |
UserUtils.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /** * 类名 :用户的工具类 * 用法 : * 创建人 : shyroke * 时间:2018/12/18 14:39 */ public class UserUtils { /** * 校验当前登录用户是否有该权限 * @param permissionname 权限名称 * @return */ public static boolean isPermission(String permissionname) { Subject subject = SecurityUtils.getSubject(); if (subject.isPermitted(permissionname)){ return true ; } else { return false ; } } } |
3.3 使用
1 2 3 4 5 6 | @PermissionAnnotation (permissionName = "boke:*" ) @PostMapping (value = "desc" ) @ResponseBody public R desc(){ return R.ok( "删除成功!" ); } |
3.4 结果
分类:
shiro
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2017-12-18 (二)Centos之在VM虚拟机中安装Centos操作系统
2017-12-18 (一)Centos之VMware虚拟机安装