From a69e41b04c0fce84cf0e9c3a8c7a57dc36d1a1e6 Mon Sep 17 00:00:00 2001 From: hjc Date: Tue, 27 Apr 2021 10:03:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E8=B4=A6=E5=8F=B7=E4=BD=93=E7=B3=BB?= =?UTF-8?q?=E4=B8=8B=E5=B0=B1=E4=B8=8D=E8=83=BD=E5=86=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?stpLogic=E9=87=8C=E9=9D=A2=E9=89=B4=E5=88=AB=E6=89=80=E6=9C=89?= =?UTF-8?q?=E6=9D=83=E9=99=90=E4=BA=86=20=E6=8A=BD=E7=A6=BB=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E9=89=B4=E5=AE=9A=E5=8D=95=E4=BD=8D=E5=B9=B6=E5=9C=A8?= =?UTF-8?q?=E5=A4=96=E9=83=A8=E7=BB=9F=E4=B8=80=E9=89=B4=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../satoken/annotation/SaCheckPermission.java | 10 +- .../dev33/satoken/annotation/SaCheckRole.java | 9 ++ .../java/cn/dev33/satoken/stp/StpLogic.java | 75 ++++--------- .../cn/dev33/satoken/aop/SaCheckAspect.java | 91 ++++++++++++++-- .../interceptor/SaAnnotationInterceptor.java | 101 +++++++++++++++++- 5 files changed, 223 insertions(+), 63 deletions(-) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckPermission.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckPermission.java index 905e022e..ff84b7d8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckPermission.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckPermission.java @@ -26,5 +26,13 @@ public @interface SaCheckPermission { * @return 验证模式 */ SaMode mode() default SaMode.AND; - + + /** + * 多账号下哪些需要校验 + * 每个StpUtil都有一个stpLogic属性 + * 初始化StpLogic时,指定的LoginKey字符串放入这里 + * 可以放多个,所以类型为数组 + * @return LoginKey字符串数组 + */ + String [] loginKeys() default {}; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckRole.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckRole.java index 08e419e5..e33390c0 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckRole.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckRole.java @@ -26,5 +26,14 @@ public @interface SaCheckRole { * @return 验证模式 */ SaMode mode() default SaMode.AND; + + /** + * 多账号下哪些需要校验 + * 每个StpUtil都有一个stpLogic属性 + * 初始化StpLogic时,指定的LoginKey字符串放入这里 + * 可以放多个,所以类型为数组 + * @return LoginKey字符串数组 + */ + String [] loginKeys() default {}; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index 790bb6a1..adeea2ca 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -1217,65 +1217,32 @@ public class StpLogic { // =================== 其它方法 =================== - + /** - * 对一个Method对象进行注解检查(注解鉴权内部实现) - * @param method Method对象 + * 检查当前登录体系是否拥有给定角色 + * @param roleArray 角色字符串数组 + * @param saMode SaMode.AND, SaMode.OR */ - public void checkMethodAnnotation(Method method) { - - // ----------- 验证登录 - if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) { - this.checkLogin(); + public void checkHasRoles(String[] roleArray, SaMode saMode) { + if(saMode == SaMode.AND) { + this.checkRoleAnd(roleArray); + } else { + this.checkRoleOr(roleArray); } - - // ----------- 验证角色 - // 验证方法上的 - SaCheckRole scr = method.getAnnotation(SaCheckRole.class); - if(scr != null) { - String[] roleArray = scr.value(); - if(scr.mode() == SaMode.AND) { - this.checkRoleAnd(roleArray); - } else { - this.checkRoleOr(roleArray); - } - } - // 验证类上的 - scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class); - if(scr != null) { - String[] roleArray = scr.value(); - if(scr.mode() == SaMode.AND) { - this.checkRoleAnd(roleArray); - } else { - this.checkRoleOr(roleArray); - } - } - - // ----------- 验证权限 - // 验证方法上的 - SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class); - if(scp != null) { - String[] permissionArray = scp.value(); - if(scp.mode() == SaMode.AND) { - this.checkPermissionAnd(permissionArray); - } else { - this.checkPermissionOr(permissionArray); - } - } - // 验证类上的 - scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class); - if(scp != null) { - String[] permissionArray = scp.value(); - if(scp.mode() == SaMode.AND) { - this.checkPermissionAnd(permissionArray); - } else { - this.checkPermissionOr(permissionArray); - } - } - - // 验证通过 } + /** + * 检查当前登录体系是否拥有给定权限 + * @param permissionArray 权限字符串数组 + * @param saMode SaMode.AND, SaMode.OR + */ + public void checkHasPermissions(String[] permissionArray, SaMode saMode) { + if(saMode == SaMode.AND) { + this.checkPermissionAnd(permissionArray); + } else { + this.checkPermissionOr(permissionArray); + } + } // =================== 身份切换 =================== diff --git a/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java b/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java index baaf0fef..a03fe344 100644 --- a/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java +++ b/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java @@ -2,6 +2,9 @@ package cn.dev33.satoken.aop; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaCheckRole; +import cn.dev33.satoken.exception.UnrecognizedLoginKeyException; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -15,6 +18,7 @@ import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaTokenConsts; import java.lang.reflect.Method; +import java.util.Map; /** * sa-token 基于 Spring Aop 的注解鉴权 @@ -63,11 +67,11 @@ public class SaCheckAspect { @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { - - // 注解鉴权 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); + Map stpLogicMap = SaManager.stpLogicMap; + // ----------- 验证登录 if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) { SaCheckLogin checkLogin = method.getAnnotation(SaCheckLogin.class); @@ -75,19 +79,92 @@ public class SaCheckAspect { getStpLogic().checkLogin(); } else { for(String loginKey : checkLogin.loginKeys()) { - if (SaManager.stpLogicMap.containsKey(loginKey)) { - StpLogic stpLogic = SaManager.stpLogicMap.get(loginKey); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); stpLogic.checkLogin(); } else { - + throw new UnrecognizedLoginKeyException(loginKey); } - } } } + // ----------- 验证角色 + // 验证方法上的 + SaCheckRole scr = method.getAnnotation(SaCheckRole.class); + if(scr != null) { + if (scr.loginKeys().length == 0) { + String[] roleArray = scr.value(); + getStpLogic().checkHasRoles(roleArray, scr.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] roleArray = scr.value(); + stpLogic.checkHasRoles(roleArray, scr.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + // 验证类上的 + scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class); + if(scr != null) { + if (scr.loginKeys().length == 0) { + String[] roleArray = scr.value(); + getStpLogic().checkHasRoles(roleArray, scr.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] roleArray = scr.value(); + stpLogic.checkHasRoles(roleArray, scr.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + + // ----------- 验证权限 + // 验证方法上的 + SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class); + if(scp != null) { + if (scr.loginKeys().length == 0) { + String[] permissionArray = scp.value(); + getStpLogic().checkHasPermissions(permissionArray, scp.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] permissionArray = scp.value(); + stpLogic.checkHasPermissions(permissionArray, scp.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + // 验证类上的 + scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class); + if(scp != null) { + if (scr.loginKeys().length == 0) { + String[] permissionArray = scp.value(); + getStpLogic().checkHasPermissions(permissionArray, scp.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] permissionArray = scp.value(); + stpLogic.checkHasPermissions(permissionArray, scp.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } - getStpLogic().checkMethodAnnotation(signature.getMethod()); try { // 执行原有逻辑 Object obj = joinPoint.proceed(); diff --git a/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java b/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java index 8729538e..9bac1635 100644 --- a/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java +++ b/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java @@ -1,10 +1,16 @@ package cn.dev33.satoken.interceptor; import java.lang.reflect.Method; +import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaCheckRole; +import cn.dev33.satoken.exception.UnrecognizedLoginKeyException; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; @@ -62,7 +68,100 @@ public class SaAnnotationInterceptor implements HandlerInterceptor { Method method = ((HandlerMethod) handler).getMethod(); // 进行验证 - getStpLogic().checkMethodAnnotation(method); + Map stpLogicMap = SaManager.stpLogicMap; + + // ----------- 验证登录 + if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) { + SaCheckLogin checkLogin = method.getAnnotation(SaCheckLogin.class); + if(checkLogin.loginKeys().length == 0) { + getStpLogic().checkLogin(); + } else { + for(String loginKey : checkLogin.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkLogin(); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + + // ----------- 验证角色 + // 验证方法上的 + SaCheckRole scr = method.getAnnotation(SaCheckRole.class); + if(scr != null) { + if (scr.loginKeys().length == 0) { + String[] roleArray = scr.value(); + getStpLogic().checkHasRoles(roleArray, scr.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] roleArray = scr.value(); + stpLogic.checkHasRoles(roleArray, scr.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + // 验证类上的 + scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class); + if(scr != null) { + if (scr.loginKeys().length == 0) { + String[] roleArray = scr.value(); + getStpLogic().checkHasRoles(roleArray, scr.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] roleArray = scr.value(); + stpLogic.checkHasRoles(roleArray, scr.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + + // ----------- 验证权限 + // 验证方法上的 + SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class); + if(scp != null) { + if (scr.loginKeys().length == 0) { + String[] permissionArray = scp.value(); + getStpLogic().checkHasPermissions(permissionArray, scp.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] permissionArray = scp.value(); + stpLogic.checkHasPermissions(permissionArray, scp.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } + // 验证类上的 + scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class); + if(scp != null) { + if (scr.loginKeys().length == 0) { + String[] permissionArray = scp.value(); + getStpLogic().checkHasPermissions(permissionArray, scp.mode()); + } else { + for(String loginKey : scr.loginKeys()) { + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + String[] permissionArray = scp.value(); + stpLogic.checkHasPermissions(permissionArray, scp.mode()); + } else { + throw new UnrecognizedLoginKeyException(loginKey); + } + } + } + } // 通过验证 return true;