实现方案二:

在原来的检测登录,检测权限,检测角色注解中
每个都添加一个唯一loginKey,
根据loginKey分别鉴权
This commit is contained in:
hjc
2021-04-27 15:48:11 +08:00
parent a69e41b04c
commit 9c1ff87023
6 changed files with 89 additions and 198 deletions

View File

@@ -1,5 +1,7 @@
package cn.dev33.satoken.annotation; package cn.dev33.satoken.annotation;
import cn.dev33.satoken.stp.StpUtil;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -16,12 +18,11 @@ import java.lang.annotation.Target;
public @interface SaCheckLogin { public @interface SaCheckLogin {
/** /**
* 多账号下哪些需要校验 * 多账号体系下使用哪个体系检测登录
* 每个StpUtil都有一个stpLogic属性 * 每个StpUtil都有一个stpLogic属性
* 初始化StpLogic时,指定的LoginKey字符串放入这里 * 初始化StpLogic时, 指定的LoginKey字符串复制到这里
* 可以放多个,所以类型为数组 * @return LoginKey字符串
* @return LoginKey字符串数组
*/ */
String [] loginKeys() default {}; String key() default "login";
} }

View File

@@ -28,11 +28,11 @@ public @interface SaCheckPermission {
SaMode mode() default SaMode.AND; SaMode mode() default SaMode.AND;
/** /**
* 多账号下哪些需要校验 * 多账号体系下使用哪个体系检测权限
* 每个StpUtil都有一个stpLogic属性 * 每个StpUtil都有一个stpLogic属性
* 初始化StpLogic时,指定的LoginKey字符串放入这里 * 初始化StpLogic时, 指定的LoginKey字符串复制到这里
* 可以放多个,所以类型为数组 * @return LoginKey字符串
* @return LoginKey字符串数组
*/ */
String [] loginKeys() default {}; String key() default "login";
} }

View File

@@ -28,12 +28,11 @@ public @interface SaCheckRole {
SaMode mode() default SaMode.AND; SaMode mode() default SaMode.AND;
/** /**
* 多账号下哪些需要校验 * 多账号体系下使用哪个体系检测角色
* 每个StpUtil都有一个stpLogic属性 * 每个StpUtil都有一个stpLogic属性
* 初始化StpLogic时,指定的LoginKey字符串放入这里 * 初始化StpLogic时, 指定的LoginKey字符串复制到这里
* 可以放多个,所以类型为数组 * @return LoginKey字符串
* @return LoginKey字符串数组
*/ */
String [] loginKeys() default {}; String key() default "login";
} }

View File

@@ -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;
}
}

View File

@@ -4,7 +4,7 @@ import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole; 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.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
@@ -70,98 +70,59 @@ public class SaCheckAspect {
// 注解鉴权 // 注解鉴权
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod(); Method method = signature.getMethod();
Class<?> cutClass = method.getDeclaringClass();
Map<String, StpLogic> stpLogicMap = SaManager.stpLogicMap; Map<String, StpLogic> stpLogicMap = SaManager.stpLogicMap;
// ----------- 验证登录 // ----------- 验证登录
if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) { SaCheckLogin checkLogin = null;
SaCheckLogin checkLogin = method.getAnnotation(SaCheckLogin.class); if(method.isAnnotationPresent(SaCheckLogin.class)) { // 方法注解的优先级高于类注解
if(checkLogin.loginKeys().length == 0) { checkLogin = method.getAnnotation(SaCheckLogin.class);
getStpLogic().checkLogin(); } else if(cutClass.isAnnotationPresent(SaCheckLogin.class)) {
} else { checkLogin = cutClass.getAnnotation(SaCheckLogin.class);
for(String loginKey : checkLogin.loginKeys()) { }
if (checkLogin != null) {
String loginKey = checkLogin.key();
if (stpLogicMap.containsKey(loginKey)) { if (stpLogicMap.containsKey(loginKey)) {
StpLogic stpLogic = stpLogicMap.get(loginKey); StpLogic stpLogic = stpLogicMap.get(loginKey);
stpLogic.checkLogin(); stpLogic.checkLogin();
} else { } else {
throw new UnrecognizedLoginKeyException(loginKey); // StpUserUtil里面的StpLogic对象只有调用至少一次才会初始化,如果没有初始化SaManager.stpLogicMap里面是没有loginKey
} // 还有一种可能是使用者写错了loginKey,这两种方式都会导致SaManager.stpLogicMap查不到loginKey
} throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
} }
} }
// ----------- 验证角色 // ----------- 验证角色
// 验证方法上的 SaCheckRole saCheckRole = null;
SaCheckRole scr = method.getAnnotation(SaCheckRole.class); if (method.isAnnotationPresent(SaCheckRole.class)) { // 方法注解的优先级高于类注解
if(scr != null) { saCheckRole = method.getAnnotation(SaCheckRole.class);
if (scr.loginKeys().length == 0) { } else if (cutClass.isAnnotationPresent(SaCheckRole.class)) {
String[] roleArray = scr.value(); saCheckRole = cutClass.getAnnotation(SaCheckRole.class);
getStpLogic().checkHasRoles(roleArray, scr.mode()); }
} else { if (saCheckRole != null) {
for(String loginKey : scr.loginKeys()) { String loginKey = saCheckRole.key();
if (stpLogicMap.containsKey(loginKey)) { if (stpLogicMap.containsKey(loginKey)) {
StpLogic stpLogic = stpLogicMap.get(loginKey); StpLogic stpLogic = stpLogicMap.get(loginKey);
String[] roleArray = scr.value(); stpLogic.checkHasRoles(saCheckRole.value(), saCheckRole.mode());
stpLogic.checkHasRoles(roleArray, scr.mode());
} else { } else {
throw new UnrecognizedLoginKeyException(loginKey); throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
}
}
}
}
// 验证类上的
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 saCheckPermission = null;
SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class); if (method.isAnnotationPresent(SaCheckPermission.class)) { // 方法注解的优先级高于类注解
if(scp != null) { saCheckPermission = method.getAnnotation(SaCheckPermission.class);
if (scr.loginKeys().length == 0) { } else if (cutClass.isAnnotationPresent(SaCheckPermission.class)){
String[] permissionArray = scp.value(); saCheckPermission = cutClass.getAnnotation(SaCheckPermission.class);
getStpLogic().checkHasPermissions(permissionArray, scp.mode()); }
} else { if (saCheckPermission != null) {
for(String loginKey : scr.loginKeys()) { String loginKey = saCheckPermission.key();
if (stpLogicMap.containsKey(loginKey)) { if (stpLogicMap.containsKey(loginKey)) {
StpLogic stpLogic = stpLogicMap.get(loginKey); StpLogic stpLogic = stpLogicMap.get(loginKey);
String[] permissionArray = scp.value(); stpLogic.checkHasPermissions(saCheckPermission.value(), saCheckPermission.mode());
stpLogic.checkHasPermissions(permissionArray, scp.mode());
} else { } else {
throw new UnrecognizedLoginKeyException(loginKey); throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
}
}
}
}
// 验证类上的
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);
}
}
} }
} }

View File

@@ -10,7 +10,7 @@ import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole; 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.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
@@ -68,98 +68,57 @@ public class SaAnnotationInterceptor implements HandlerInterceptor {
Method method = ((HandlerMethod) handler).getMethod(); Method method = ((HandlerMethod) handler).getMethod();
// 进行验证 // 进行验证
Class<?> cutClass = method.getDeclaringClass();
Map<String, StpLogic> stpLogicMap = SaManager.stpLogicMap; Map<String, StpLogic> stpLogicMap = SaManager.stpLogicMap;
// ----------- 验证登录 // ----------- 验证登录
if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) { SaCheckLogin checkLogin = null;
SaCheckLogin checkLogin = method.getAnnotation(SaCheckLogin.class); if(method.isAnnotationPresent(SaCheckLogin.class)) { // 方法注解的优先级高于类注解
if(checkLogin.loginKeys().length == 0) { checkLogin = method.getAnnotation(SaCheckLogin.class);
getStpLogic().checkLogin(); } else if(cutClass.isAnnotationPresent(SaCheckLogin.class)) {
} else { checkLogin = cutClass.getAnnotation(SaCheckLogin.class);
for(String loginKey : checkLogin.loginKeys()) { }
if (checkLogin != null) {
String loginKey = checkLogin.key();
if (stpLogicMap.containsKey(loginKey)) { if (stpLogicMap.containsKey(loginKey)) {
StpLogic stpLogic = stpLogicMap.get(loginKey); StpLogic stpLogic = stpLogicMap.get(loginKey);
stpLogic.checkLogin(); stpLogic.checkLogin();
} else { } else {
throw new UnrecognizedLoginKeyException(loginKey); throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
}
}
} }
} }
// ----------- 验证角色 // ----------- 验证角色
// 验证方法上的 SaCheckRole saCheckRole = null;
SaCheckRole scr = method.getAnnotation(SaCheckRole.class); if (method.isAnnotationPresent(SaCheckRole.class)) { // 方法注解的优先级高于类注解
if(scr != null) { saCheckRole = method.getAnnotation(SaCheckRole.class);
if (scr.loginKeys().length == 0) { } else if (cutClass.isAnnotationPresent(SaCheckRole.class)) {
String[] roleArray = scr.value(); saCheckRole = cutClass.getAnnotation(SaCheckRole.class);
getStpLogic().checkHasRoles(roleArray, scr.mode()); }
} else { if (saCheckRole != null) {
for(String loginKey : scr.loginKeys()) { String loginKey = saCheckRole.key();
if (stpLogicMap.containsKey(loginKey)) { if (stpLogicMap.containsKey(loginKey)) {
StpLogic stpLogic = stpLogicMap.get(loginKey); StpLogic stpLogic = stpLogicMap.get(loginKey);
String[] roleArray = scr.value(); stpLogic.checkHasRoles(saCheckRole.value(), saCheckRole.mode());
stpLogic.checkHasRoles(roleArray, scr.mode());
} else { } else {
throw new UnrecognizedLoginKeyException(loginKey); throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
}
}
}
}
// 验证类上的
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 saCheckPermission = null;
SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class); if (method.isAnnotationPresent(SaCheckPermission.class)) { // 方法注解的优先级高于类注解
if(scp != null) { saCheckPermission = method.getAnnotation(SaCheckPermission.class);
if (scr.loginKeys().length == 0) { } else if (cutClass.isAnnotationPresent(SaCheckPermission.class)){
String[] permissionArray = scp.value(); saCheckPermission = cutClass.getAnnotation(SaCheckPermission.class);
getStpLogic().checkHasPermissions(permissionArray, scp.mode()); }
} else { if (saCheckPermission != null) {
for(String loginKey : scr.loginKeys()) { String loginKey = saCheckPermission.key();
if (stpLogicMap.containsKey(loginKey)) { if (stpLogicMap.containsKey(loginKey)) {
StpLogic stpLogic = stpLogicMap.get(loginKey); StpLogic stpLogic = stpLogicMap.get(loginKey);
String[] permissionArray = scp.value(); stpLogic.checkHasPermissions(saCheckPermission.value(), saCheckPermission.mode());
stpLogic.checkHasPermissions(permissionArray, scp.mode());
} else { } else {
throw new UnrecognizedLoginKeyException(loginKey); throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
}
}
}
}
// 验证类上的
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);
}
}
} }
} }