From 2d4267b1da20ffb451a32e03266d8000a9fa9765 Mon Sep 17 00:00:00 2001 From: hjc Date: Tue, 27 Apr 2021 09:28:14 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8F=B7=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=20=E6=B7=BB=E5=8A=A0=E6=9C=AA=E8=AF=86=E5=88=ABloginK?= =?UTF-8?q?ey=E5=BC=82=E5=B8=B8=20=E5=88=A0=E9=99=A4StpUtil=E5=8D=95?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E4=BD=93=E7=B3=BB=E9=BB=98=E8=AE=A4loginKey?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../satoken/annotation/SaCheckLogin.java | 9 ++++++ .../exception/NotPermissionException.java | 8 +---- .../satoken/exception/NotRoleException.java | 6 ---- .../UnrecognizedLoginKeyException.java | 29 +++++++++++++++++++ .../cn/dev33/satoken/aop/SaCheckAspect.java | 27 +++++++++++++++++ 5 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java index a7a644db..f2d85fac 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java @@ -15,4 +15,13 @@ import java.lang.annotation.Target; @Target({ ElementType.METHOD, ElementType.TYPE }) public @interface SaCheckLogin { + /** + * 多账号下哪些需要校验 + * 每个StpUtil都有一个stpLogic属性 + * 初始化StpLogic时,指定的LoginKey字符串放入这里 + * 可以放多个,所以类型为数组 + * @return LoginKey字符串数组 + */ + String [] loginKeys() default {}; + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java index 9b9e2c76..9cd0c245 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java @@ -1,7 +1,5 @@ package cn.dev33.satoken.exception; -import cn.dev33.satoken.stp.StpUtil; - /** * 没有指定权限码,抛出的异常 * @@ -13,7 +11,7 @@ public class NotPermissionException extends SaTokenException { /** * 序列化版本号 */ - private static final long serialVersionUID = 6806129545290130142L; + private static final long serialVersionUID = 6806129545290130141L; /** 权限码 */ private String code; @@ -39,10 +37,6 @@ public class NotPermissionException extends SaTokenException { return loginKey; } - public NotPermissionException(String code) { - this(code, StpUtil.stpLogic.loginKey); - } - public NotPermissionException(String code, String loginKey) { super("无此权限:" + code); this.code = code; diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotRoleException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotRoleException.java index fe87c33c..fd171e44 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotRoleException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotRoleException.java @@ -1,7 +1,5 @@ package cn.dev33.satoken.exception; -import cn.dev33.satoken.stp.StpUtil; - /** * 没有指定角色标识,抛出的异常 * @@ -39,10 +37,6 @@ public class NotRoleException extends SaTokenException { return loginKey; } - public NotRoleException(String role) { - this(role, StpUtil.stpLogic.loginKey); - } - public NotRoleException(String role, String loginKey) { // 这里到底要不要拼接上loginKey呢?纠结 super("无此角色:" + role); diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java new file mode 100644 index 00000000..a4b5b117 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java @@ -0,0 +1,29 @@ +package cn.dev33.satoken.exception; + +public class UnrecognizedLoginKeyException extends RuntimeException{ + + /** + * 序列化版本号 + */ + private static final long serialVersionUID = 6806129545290130140L; + + /** + * loginKey + */ + private String loginKey; + + /** + * 获得loginKey + * + * @return loginKey + */ + public String getLoginKey() { + return loginKey; + } + + public UnrecognizedLoginKeyException(String loginKey) { + super("未知的loginKey: " + loginKey); + this.loginKey = loginKey; + } + +} 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 a57194f6..baaf0fef 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 @@ -1,5 +1,7 @@ package cn.dev33.satoken.aop; +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.annotation.SaCheckLogin; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -12,6 +14,8 @@ import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaTokenConsts; +import java.lang.reflect.Method; + /** * sa-token 基于 Spring Aop 的注解鉴权 * @@ -58,8 +62,31 @@ public class SaCheckAspect { */ @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + + + // 注解鉴权 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + // ----------- 验证登录 + 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 (SaManager.stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = SaManager.stpLogicMap.get(loginKey); + stpLogic.checkLogin(); + } else { + + } + + } + } + } + + getStpLogic().checkMethodAnnotation(signature.getMethod()); try { // 执行原有逻辑 From a69e41b04c0fce84cf0e9c3a8c7a57dc36d1a1e6 Mon Sep 17 00:00:00 2001 From: hjc Date: Tue, 27 Apr 2021 10:03:35 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A4=9A=E8=B4=A6=E5=8F=B7=E4=BD=93?= =?UTF-8?q?=E7=B3=BB=E4=B8=8B=E5=B0=B1=E4=B8=8D=E8=83=BD=E5=86=8D=E4=B8=80?= =?UTF-8?q?=E4=B8=AAstpLogic=E9=87=8C=E9=9D=A2=E9=89=B4=E5=88=AB=E6=89=80?= =?UTF-8?q?=E6=9C=89=E6=9D=83=E9=99=90=E4=BA=86=20=E6=8A=BD=E7=A6=BB?= =?UTF-8?q?=E6=9C=80=E5=B0=8F=E9=89=B4=E5=AE=9A=E5=8D=95=E4=BD=8D=E5=B9=B6?= =?UTF-8?q?=E5=9C=A8=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; From 9c1ff87023aee49b23960658f084d8f8f6a5052f Mon Sep 17 00:00:00 2001 From: hjc Date: Tue, 27 Apr 2021 15:48:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E4=BA=8C:=20=E5=9C=A8=E5=8E=9F=E6=9D=A5=E7=9A=84=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E7=99=BB=E5=BD=95,=E6=A3=80=E6=B5=8B=E6=9D=83?= =?UTF-8?q?=E9=99=90,=E6=A3=80=E6=B5=8B=E8=A7=92=E8=89=B2=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E4=B8=AD=20=E6=AF=8F=E4=B8=AA=E9=83=BD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=B8=80=E4=B8=AA=E5=94=AF=E4=B8=80loginKey,=20?= =?UTF-8?q?=E6=A0=B9=E6=8D=AEloginKey=E5=88=86=E5=88=AB=E9=89=B4=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../satoken/annotation/SaCheckLogin.java | 11 +- .../satoken/annotation/SaCheckPermission.java | 10 +- .../dev33/satoken/annotation/SaCheckRole.java | 9 +- .../UnrecognizedLoginKeyException.java | 29 ----- .../cn/dev33/satoken/aop/SaCheckAspect.java | 115 ++++++------------ .../interceptor/SaAnnotationInterceptor.java | 113 ++++++----------- 6 files changed, 89 insertions(+), 198 deletions(-) delete mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java index f2d85fac..f09211a6 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java @@ -1,5 +1,7 @@ package cn.dev33.satoken.annotation; +import cn.dev33.satoken.stp.StpUtil; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -16,12 +18,11 @@ import java.lang.annotation.Target; public @interface SaCheckLogin { /** - * 多账号下哪些需要校验 + * 多账号体系下使用哪个体系检测登录 * 每个StpUtil都有一个stpLogic属性 - * 初始化StpLogic时,指定的LoginKey字符串放入这里 - * 可以放多个,所以类型为数组 - * @return LoginKey字符串数组 + * 初始化StpLogic时, 指定的LoginKey字符串复制到这里 + * @return LoginKey字符串 */ - String [] loginKeys() default {}; + String key() default "login"; } 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 ff84b7d8..95d7c000 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 @@ -28,11 +28,11 @@ public @interface SaCheckPermission { SaMode mode() default SaMode.AND; /** - * 多账号下哪些需要校验 + * 多账号体系下使用哪个体系检测权限 * 每个StpUtil都有一个stpLogic属性 - * 初始化StpLogic时,指定的LoginKey字符串放入这里 - * 可以放多个,所以类型为数组 - * @return LoginKey字符串数组 + * 初始化StpLogic时, 指定的LoginKey字符串复制到这里 + * @return LoginKey字符串 */ - String [] loginKeys() default {}; + String key() default "login"; + } 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 e33390c0..c11e777f 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 @@ -28,12 +28,11 @@ public @interface SaCheckRole { SaMode mode() default SaMode.AND; /** - * 多账号下哪些需要校验 + * 多账号体系下使用哪个体系检测角色 * 每个StpUtil都有一个stpLogic属性 - * 初始化StpLogic时,指定的LoginKey字符串放入这里 - * 可以放多个,所以类型为数组 - * @return LoginKey字符串数组 + * 初始化StpLogic时, 指定的LoginKey字符串复制到这里 + * @return LoginKey字符串 */ - String [] loginKeys() default {}; + String key() default "login"; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java deleted file mode 100644 index a4b5b117..00000000 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/UnrecognizedLoginKeyException.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.dev33.satoken.exception; - -public class UnrecognizedLoginKeyException extends RuntimeException{ - - /** - * 序列化版本号 - */ - private static final long serialVersionUID = 6806129545290130140L; - - /** - * loginKey - */ - private String loginKey; - - /** - * 获得loginKey - * - * @return loginKey - */ - public String getLoginKey() { - return loginKey; - } - - public UnrecognizedLoginKeyException(String loginKey) { - super("未知的loginKey: " + loginKey); - this.loginKey = loginKey; - } - -} 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 a03fe344..abdab736 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 @@ -4,7 +4,7 @@ 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 cn.dev33.satoken.exception.NotLoginException; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -70,98 +70,59 @@ public class SaCheckAspect { // 注解鉴权 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); + Class cutClass = method.getDeclaringClass(); 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(); + SaCheckLogin checkLogin = null; + if(method.isAnnotationPresent(SaCheckLogin.class)) { // 方法注解的优先级高于类注解 + checkLogin = method.getAnnotation(SaCheckLogin.class); + } else if(cutClass.isAnnotationPresent(SaCheckLogin.class)) { + checkLogin = cutClass.getAnnotation(SaCheckLogin.class); + } + if (checkLogin != null) { + String loginKey = checkLogin.key(); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkLogin(); } else { - for(String loginKey : checkLogin.loginKeys()) { - if (stpLogicMap.containsKey(loginKey)) { - StpLogic stpLogic = stpLogicMap.get(loginKey); - stpLogic.checkLogin(); - } else { - throw new UnrecognizedLoginKeyException(loginKey); - } - } + // StpUserUtil里面的StpLogic对象只有调用至少一次才会初始化,如果没有初始化SaManager.stpLogicMap里面是没有loginKey的 + // 还有一种可能是使用者写错了loginKey,这两种方式都会导致SaManager.stpLogicMap查不到loginKey + throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE); } } // ----------- 验证角色 - // 验证方法上的 - 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); - } - } - } + SaCheckRole saCheckRole = null; + if (method.isAnnotationPresent(SaCheckRole.class)) { // 方法注解的优先级高于类注解 + saCheckRole = method.getAnnotation(SaCheckRole.class); + } else if (cutClass.isAnnotationPresent(SaCheckRole.class)) { + saCheckRole = cutClass.getAnnotation(SaCheckRole.class); } - // 验证类上的 - scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class); - if(scr != null) { - if (scr.loginKeys().length == 0) { - String[] roleArray = scr.value(); - getStpLogic().checkHasRoles(roleArray, scr.mode()); + if (saCheckRole != null) { + String loginKey = saCheckRole.key(); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkHasRoles(saCheckRole.value(), saCheckRole.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); - } - } + throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE); } } // ----------- 验证权限 - // 验证方法上的 - 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); - } - } - } + SaCheckPermission saCheckPermission = null; + if (method.isAnnotationPresent(SaCheckPermission.class)) { // 方法注解的优先级高于类注解 + saCheckPermission = method.getAnnotation(SaCheckPermission.class); + } else if (cutClass.isAnnotationPresent(SaCheckPermission.class)){ + saCheckPermission = cutClass.getAnnotation(SaCheckPermission.class); } - // 验证类上的 - scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class); - if(scp != null) { - if (scr.loginKeys().length == 0) { - String[] permissionArray = scp.value(); - getStpLogic().checkHasPermissions(permissionArray, scp.mode()); + if (saCheckPermission != null) { + String loginKey = saCheckPermission.key(); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkHasPermissions(saCheckPermission.value(), saCheckPermission.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); - } - } + throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE); } } 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 9bac1635..318d7bf1 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 @@ -10,7 +10,7 @@ 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 cn.dev33.satoken.exception.NotLoginException; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; @@ -68,98 +68,57 @@ public class SaAnnotationInterceptor implements HandlerInterceptor { Method method = ((HandlerMethod) handler).getMethod(); // 进行验证 + Class cutClass = method.getDeclaringClass(); 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(); + SaCheckLogin checkLogin = null; + if(method.isAnnotationPresent(SaCheckLogin.class)) { // 方法注解的优先级高于类注解 + checkLogin = method.getAnnotation(SaCheckLogin.class); + } else if(cutClass.isAnnotationPresent(SaCheckLogin.class)) { + checkLogin = cutClass.getAnnotation(SaCheckLogin.class); + } + if (checkLogin != null) { + String loginKey = checkLogin.key(); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkLogin(); } else { - for(String loginKey : checkLogin.loginKeys()) { - if (stpLogicMap.containsKey(loginKey)) { - StpLogic stpLogic = stpLogicMap.get(loginKey); - stpLogic.checkLogin(); - } else { - throw new UnrecognizedLoginKeyException(loginKey); - } - } + throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE); } } // ----------- 验证角色 - // 验证方法上的 - 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); - } - } - } + SaCheckRole saCheckRole = null; + if (method.isAnnotationPresent(SaCheckRole.class)) { // 方法注解的优先级高于类注解 + saCheckRole = method.getAnnotation(SaCheckRole.class); + } else if (cutClass.isAnnotationPresent(SaCheckRole.class)) { + saCheckRole = cutClass.getAnnotation(SaCheckRole.class); } - // 验证类上的 - scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class); - if(scr != null) { - if (scr.loginKeys().length == 0) { - String[] roleArray = scr.value(); - getStpLogic().checkHasRoles(roleArray, scr.mode()); + if (saCheckRole != null) { + String loginKey = saCheckRole.key(); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkHasRoles(saCheckRole.value(), saCheckRole.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); - } - } + throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE); } } // ----------- 验证权限 - // 验证方法上的 - 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); - } - } - } + SaCheckPermission saCheckPermission = null; + if (method.isAnnotationPresent(SaCheckPermission.class)) { // 方法注解的优先级高于类注解 + saCheckPermission = method.getAnnotation(SaCheckPermission.class); + } else if (cutClass.isAnnotationPresent(SaCheckPermission.class)){ + saCheckPermission = cutClass.getAnnotation(SaCheckPermission.class); } - // 验证类上的 - scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class); - if(scp != null) { - if (scr.loginKeys().length == 0) { - String[] permissionArray = scp.value(); - getStpLogic().checkHasPermissions(permissionArray, scp.mode()); + if (saCheckPermission != null) { + String loginKey = saCheckPermission.key(); + if (stpLogicMap.containsKey(loginKey)) { + StpLogic stpLogic = stpLogicMap.get(loginKey); + stpLogic.checkHasPermissions(saCheckPermission.value(), saCheckPermission.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); - } - } + throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE); } }