mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
注解鉴权增加LoginKey属性,用于多账号模式下的注解鉴权支持
This commit is contained in:
parent
76dd333c9b
commit
479b40b92b
@ -11,11 +11,13 @@ import cn.dev33.satoken.context.SaTokenContext;
|
||||
import cn.dev33.satoken.context.SaTokenContextDefaultImpl;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.listener.SaTokenListener;
|
||||
import cn.dev33.satoken.listener.SaTokenListenerDefaultImpl;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpInterfaceDefaultImpl;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
@ -34,6 +36,8 @@ public class SaManager {
|
||||
if(config.getIsV()) {
|
||||
SaFoxUtil.printSaToken();
|
||||
}
|
||||
// 调用一次StpUtil中的方法,保证其可以尽早的初始化 StpLogic
|
||||
StpUtil.getLoginKey();
|
||||
}
|
||||
public static SaTokenConfig getConfig() {
|
||||
if (config == null) {
|
||||
@ -153,12 +157,31 @@ public class SaManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 LoginKey 获取对应的StpLogic,如果不存在则返回null
|
||||
* 根据 LoginKey 获取对应的StpLogic,如果不存在则抛出异常
|
||||
* @param loginKey 对应的LoginKey
|
||||
* @return 对应的StpLogic
|
||||
*/
|
||||
public static StpLogic getStpLogic(String loginKey) {
|
||||
return stpLogicMap.get(loginKey);
|
||||
// 如果key为空则返回框架内置的
|
||||
if(loginKey == null || loginKey.isEmpty()) {
|
||||
return StpUtil.stpLogic;
|
||||
}
|
||||
|
||||
// 从SaManager中获取
|
||||
StpLogic stpLogic = stpLogicMap.get(loginKey);
|
||||
if(stpLogic == null) {
|
||||
/*
|
||||
* 此时有两种情况会造成 StpLogic == null
|
||||
* 1. LoginKey拼写错误,请改正 (建议使用常量)
|
||||
* 2. 自定义StpUtil尚未初始化(静态类中的属性至少一次调用后才会初始化),解决方法两种
|
||||
* (1) 从main方法里调用一次
|
||||
* (2) 在自定义StpUtil类加上类似 @Component 的注解让容器启动时扫描到自动初始化
|
||||
*/
|
||||
throw new SaTokenException("未能获取对应StpLogic,key="+ loginKey);
|
||||
}
|
||||
|
||||
// 返回
|
||||
return stpLogic;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.dev33.satoken.action;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
@ -34,5 +35,11 @@ public interface SaTokenAction {
|
||||
* @return 是否包含
|
||||
*/
|
||||
public boolean hasElement(List<String> list, String element);
|
||||
|
||||
/**
|
||||
* 对一个Method对象进行注解检查(注解鉴权内部实现)
|
||||
* @param method Method对象
|
||||
*/
|
||||
public void checkMethodAnnotation(Method method);
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
package cn.dev33.satoken.action;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
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.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
|
||||
/**
|
||||
* 对 SaTokenAction 接口的默认实现
|
||||
@ -76,5 +80,53 @@ public class SaTokenActionDefaultImpl implements SaTokenAction {
|
||||
// 走出for循环说明没有一个元素可以匹配成功
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对一个Method对象进行注解权限校验(注解鉴权逻辑内部实现)
|
||||
*/
|
||||
@Override
|
||||
public void checkMethodAnnotation(Method method) {
|
||||
|
||||
// 获取这个 Method 所属的 Class
|
||||
Class<?> clazz = method.getDeclaringClass();
|
||||
|
||||
|
||||
// 从 Class 校验 @SaCheckLogin 注解
|
||||
if(clazz.isAnnotationPresent(SaCheckLogin.class)) {
|
||||
SaCheckLogin at = clazz.getAnnotation(SaCheckLogin.class);
|
||||
SaManager.getStpLogic(at.key()).checkByAnnotation(at);
|
||||
}
|
||||
|
||||
// 从 Class 校验 @SaCheckRole 注解
|
||||
if(clazz.isAnnotationPresent(SaCheckRole.class)) {
|
||||
SaCheckRole at = clazz.getAnnotation(SaCheckRole.class);
|
||||
SaManager.getStpLogic(at.key()).checkByAnnotation(at);
|
||||
}
|
||||
|
||||
// 从 Class 校验 @SaCheckPermission 注解
|
||||
if(clazz.isAnnotationPresent(SaCheckPermission.class)) {
|
||||
SaCheckPermission at = clazz.getAnnotation(SaCheckPermission.class);
|
||||
SaManager.getStpLogic(at.key()).checkByAnnotation(at);
|
||||
}
|
||||
|
||||
// 从 Method 校验 @SaCheckLogin 注解
|
||||
if(method.isAnnotationPresent(SaCheckLogin.class)) {
|
||||
SaCheckLogin at = method.getAnnotation(SaCheckLogin.class);
|
||||
SaManager.getStpLogic(at.key()).checkByAnnotation(at);
|
||||
}
|
||||
|
||||
// 从 Method 校验 @SaCheckRole 注解
|
||||
if(method.isAnnotationPresent(SaCheckRole.class)) {
|
||||
SaCheckRole at = method.getAnnotation(SaCheckRole.class);
|
||||
SaManager.getStpLogic(at.key()).checkByAnnotation(at);
|
||||
}
|
||||
|
||||
// 从 Method 校验 @SaCheckPermission 注解
|
||||
if(method.isAnnotationPresent(SaCheckPermission.class)) {
|
||||
SaCheckPermission at = method.getAnnotation(SaCheckPermission.class);
|
||||
SaManager.getStpLogic(at.key()).checkByAnnotation(at);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
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;
|
||||
@ -18,11 +16,9 @@ import java.lang.annotation.Target;
|
||||
public @interface SaCheckLogin {
|
||||
|
||||
/**
|
||||
* 多账号体系下使用哪个体系检测登录
|
||||
* 每个StpUtil都有一个stpLogic属性
|
||||
* 初始化StpLogic时, 指定的LoginKey字符串复制到这里
|
||||
* @return LoginKey字符串
|
||||
* 多账号体系下所属的账号体系标识
|
||||
* @return see note
|
||||
*/
|
||||
String key() default "login";
|
||||
String key() default "";
|
||||
|
||||
}
|
||||
|
@ -27,12 +27,10 @@ public @interface SaCheckPermission {
|
||||
*/
|
||||
SaMode mode() default SaMode.AND;
|
||||
|
||||
/**
|
||||
* 多账号体系下使用哪个体系检测权限
|
||||
* 每个StpUtil都有一个stpLogic属性
|
||||
* 初始化StpLogic时, 指定的LoginKey字符串复制到这里
|
||||
* @return LoginKey字符串
|
||||
*/
|
||||
String key() default "login";
|
||||
/**
|
||||
* 多账号体系下所属的账号体系标识
|
||||
* @return see note
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
}
|
||||
|
@ -27,12 +27,10 @@ public @interface SaCheckRole {
|
||||
*/
|
||||
SaMode mode() default SaMode.AND;
|
||||
|
||||
/**
|
||||
* 多账号体系下使用哪个体系检测角色
|
||||
* 每个StpUtil都有一个stpLogic属性
|
||||
* 初始化StpLogic时, 指定的LoginKey字符串复制到这里
|
||||
* @return LoginKey字符串
|
||||
*/
|
||||
String key() default "login";
|
||||
/**
|
||||
* 多账号体系下所属的账号体系标识
|
||||
* @return see note
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.dev33.satoken.exception;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 没有指定权限码,抛出的异常
|
||||
*
|
||||
@ -37,6 +39,10 @@ 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;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.dev33.satoken.exception;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 没有指定角色标识,抛出的异常
|
||||
*
|
||||
@ -37,8 +39,11 @@ 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);
|
||||
this.role = role;
|
||||
this.loginKey = loginKey;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -24,8 +23,8 @@ import cn.dev33.satoken.exception.NotRoleException;
|
||||
import cn.dev33.satoken.fun.SaFunction;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.session.TokenSign;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
|
||||
/**
|
||||
* sa-token 权限验证,逻辑实现类
|
||||
@ -1219,31 +1218,40 @@ public class StpLogic {
|
||||
// =================== 其它方法 ===================
|
||||
|
||||
/**
|
||||
* 检查当前登录体系是否拥有给定角色
|
||||
* @param roleArray 角色字符串数组
|
||||
* @param saMode SaMode.AND, SaMode.OR
|
||||
* 根据注解(@SaCheckLogin)鉴权
|
||||
* @param at 注解对象
|
||||
*/
|
||||
public void checkHasRoles(String[] roleArray, SaMode saMode) {
|
||||
if(saMode == SaMode.AND) {
|
||||
this.checkRoleAnd(roleArray);
|
||||
} else {
|
||||
this.checkRoleOr(roleArray);
|
||||
}
|
||||
public void checkByAnnotation(SaCheckLogin at) {
|
||||
this.checkLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当前登录体系是否拥有给定权限
|
||||
* @param permissionArray 权限字符串数组
|
||||
* @param saMode SaMode.AND, SaMode.OR
|
||||
* 根据注解(@SaCheckRole)鉴权
|
||||
* @param at 注解对象
|
||||
*/
|
||||
public void checkHasPermissions(String[] permissionArray, SaMode saMode) {
|
||||
if(saMode == SaMode.AND) {
|
||||
this.checkPermissionAnd(permissionArray);
|
||||
public void checkByAnnotation(SaCheckRole at) {
|
||||
String[] roleArray = at.value();
|
||||
if(at.mode() == SaMode.AND) {
|
||||
this.checkRoleAnd(roleArray);
|
||||
} else {
|
||||
this.checkPermissionOr(permissionArray);
|
||||
this.checkRoleOr(roleArray);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解(@SaCheckPermission)鉴权
|
||||
* @param at 注解对象
|
||||
*/
|
||||
public void checkByAnnotation(SaCheckPermission at) {
|
||||
String[] permissionArray = at.value();
|
||||
if(at.mode() == SaMode.AND) {
|
||||
this.checkPermissionAnd(permissionArray);
|
||||
} else {
|
||||
this.checkPermissionOr(permissionArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =================== 身份切换 ===================
|
||||
|
||||
/**
|
||||
|
@ -10,13 +10,17 @@ import cn.dev33.satoken.session.SaSession;
|
||||
* @author kong
|
||||
*/
|
||||
public class StpUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 账号体系标识
|
||||
*/
|
||||
public static final String KEY = "login";
|
||||
|
||||
/**
|
||||
* 底层的 StpLogic 对象
|
||||
*/
|
||||
public static StpLogic stpLogic = new StpLogic("login");
|
||||
public static StpLogic stpLogic = new StpLogic(KEY);
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前StpLogin的loginKey
|
||||
* @return 当前StpLogin的loginKey
|
||||
|
@ -71,8 +71,10 @@ public class TestJwtController {
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||
@RequestMapping("test")
|
||||
public AjaxJson test() {
|
||||
StpUtil.getTokenSession().logout();
|
||||
StpUtil.logoutByLoginId(10001);
|
||||
System.out.println();
|
||||
System.out.println("--------------进入请求--------------");
|
||||
StpUtil.setLoginId(10001);
|
||||
System.out.println(StpUtil.getTokenInfo().getTokenValue());
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
@ -26,12 +26,23 @@
|
||||
1. 新建一个新的权限验证类,比如: `StpUserUtil.java`
|
||||
2. 将`StpUtil.java`类的全部代码复制粘贴到 `StpUserUtil.java`里
|
||||
3. 更改一下其 `LoginKey`, 比如:
|
||||
|
||||
``` java
|
||||
// 底层的 StpLogic 对象
|
||||
public static StpLogic stpLogic = new StpLogic("user"); // 将 LoginKey 改为 user
|
||||
public class StpUserUtil {
|
||||
|
||||
/**
|
||||
* 账号体系标识
|
||||
*/
|
||||
public static final String KEY = "user"; // 将 LoginKey 从`login`改为`user`
|
||||
|
||||
// 其它代码 ...
|
||||
|
||||
}
|
||||
```
|
||||
4. 接下来就可以像调用`StpUtil.java`一样调用 `StpUserUtil.java`了,这两套账号认证的逻辑是完全隔离的
|
||||
|
||||
> 成品样例参考:[码云 StpUserUtil.java](https://gitee.com/click33/sa-plus/blob/master/sp-server/src/main/java/com/pj/current/satoken/StpUserUtil.java)
|
||||
|
||||
|
||||
### 进阶
|
||||
假设我们不仅需要在后台同时集成两套账号,我们还需要在一个客户端同时登陆两套账号(业务场景举例:一个APP中可以同时登陆商家账号和用户账号)
|
||||
@ -46,9 +57,9 @@
|
||||
public static StpLogic stpLogic = new StpLogic("user") {
|
||||
// 重写 `splicingKeyTokenName` 函数,返回一个与 `StpUtil` 不同的token名称, 防止冲突
|
||||
@Override
|
||||
public String splicingKeyTokenName() {
|
||||
return super.splicingKeyTokenName()+"-user";
|
||||
}
|
||||
public String splicingKeyTokenName() {
|
||||
return super.splicingKeyTokenName() + "-user";
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -1,10 +1,5 @@
|
||||
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.NotLoginException;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
@ -13,13 +8,9 @@ import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* sa-token 基于 Spring Aop 的注解鉴权
|
||||
*
|
||||
@ -36,17 +27,11 @@ public class SaCheckAspect {
|
||||
public SaCheckAspect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本切面使用的StpLogic
|
||||
*/
|
||||
public StpLogic getStpLogic() {
|
||||
return StpUtil.stpLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义AOP签名 (切入所有使用sa-token鉴权注解的方法)
|
||||
*/
|
||||
public static final String POINTCUT_SIGN = "@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || "
|
||||
public static final String POINTCUT_SIGN =
|
||||
"@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || "
|
||||
+ "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || "
|
||||
+ "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)";
|
||||
|
||||
@ -66,65 +51,10 @@ public class SaCheckAspect {
|
||||
*/
|
||||
@Around("pointcut()")
|
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
|
||||
|
||||
// 注解鉴权
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
Class<?> cutClass = method.getDeclaringClass();
|
||||
Map<String, StpLogic> stpLogicMap = SaManager.stpLogicMap;
|
||||
|
||||
// ----------- 验证登录
|
||||
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 {
|
||||
// StpUserUtil里面的StpLogic对象只有调用至少一次才会初始化,如果没有初始化SaManager.stpLogicMap里面是没有loginKey的
|
||||
// 还有一种可能是使用者写错了loginKey,这两种方式都会导致SaManager.stpLogicMap查不到loginKey
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- 验证角色
|
||||
SaCheckRole saCheckRole = null;
|
||||
if (method.isAnnotationPresent(SaCheckRole.class)) { // 方法注解的优先级高于类注解
|
||||
saCheckRole = method.getAnnotation(SaCheckRole.class);
|
||||
} else if (cutClass.isAnnotationPresent(SaCheckRole.class)) {
|
||||
saCheckRole = cutClass.getAnnotation(SaCheckRole.class);
|
||||
}
|
||||
if (saCheckRole != null) {
|
||||
String loginKey = saCheckRole.key();
|
||||
if (stpLogicMap.containsKey(loginKey)) {
|
||||
StpLogic stpLogic = stpLogicMap.get(loginKey);
|
||||
stpLogic.checkHasRoles(saCheckRole.value(), saCheckRole.mode());
|
||||
} else {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- 验证权限
|
||||
SaCheckPermission saCheckPermission = null;
|
||||
if (method.isAnnotationPresent(SaCheckPermission.class)) { // 方法注解的优先级高于类注解
|
||||
saCheckPermission = method.getAnnotation(SaCheckPermission.class);
|
||||
} else if (cutClass.isAnnotationPresent(SaCheckPermission.class)){
|
||||
saCheckPermission = cutClass.getAnnotation(SaCheckPermission.class);
|
||||
}
|
||||
if (saCheckPermission != null) {
|
||||
String loginKey = saCheckPermission.key();
|
||||
if (stpLogicMap.containsKey(loginKey)) {
|
||||
StpLogic stpLogic = stpLogicMap.get(loginKey);
|
||||
stpLogic.checkHasPermissions(saCheckPermission.value(), saCheckPermission.mode());
|
||||
} else {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
|
||||
}
|
||||
}
|
||||
SaManager.getSaTokenAction().checkMethodAnnotation(signature.getMethod());
|
||||
|
||||
try {
|
||||
// 执行原有逻辑
|
||||
|
@ -1,21 +1,14 @@
|
||||
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.NotLoginException;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* 注解式鉴权 - 拦截器
|
||||
@ -24,30 +17,6 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
*/
|
||||
public class SaAnnotationInterceptor implements HandlerInterceptor {
|
||||
|
||||
/**
|
||||
* 在进行注解鉴权时使用的 StpLogic 对象
|
||||
*/
|
||||
public StpLogic stpLogic = null;
|
||||
|
||||
/**
|
||||
* @return 在进行注解鉴权时使用的 StpLogic 对象
|
||||
*/
|
||||
public StpLogic getStpLogic() {
|
||||
if (stpLogic == null) {
|
||||
stpLogic = StpUtil.stpLogic;
|
||||
}
|
||||
return stpLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stpLogic 在进行注解鉴权时使用的 StpLogic 对象
|
||||
* @return 拦截器自身
|
||||
*/
|
||||
public SaAnnotationInterceptor setStpLogic(StpLogic stpLogic) {
|
||||
this.stpLogic = stpLogic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建: 注解式鉴权 - 拦截器
|
||||
*/
|
||||
@ -68,60 +37,8 @@ public class SaAnnotationInterceptor implements HandlerInterceptor {
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
|
||||
// 进行验证
|
||||
Class<?> cutClass = method.getDeclaringClass();
|
||||
Map<String, StpLogic> stpLogicMap = SaManager.stpLogicMap;
|
||||
|
||||
// ----------- 验证登录
|
||||
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 {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- 验证角色
|
||||
SaCheckRole saCheckRole = null;
|
||||
if (method.isAnnotationPresent(SaCheckRole.class)) { // 方法注解的优先级高于类注解
|
||||
saCheckRole = method.getAnnotation(SaCheckRole.class);
|
||||
} else if (cutClass.isAnnotationPresent(SaCheckRole.class)) {
|
||||
saCheckRole = cutClass.getAnnotation(SaCheckRole.class);
|
||||
}
|
||||
if (saCheckRole != null) {
|
||||
String loginKey = saCheckRole.key();
|
||||
if (stpLogicMap.containsKey(loginKey)) {
|
||||
StpLogic stpLogic = stpLogicMap.get(loginKey);
|
||||
stpLogic.checkHasRoles(saCheckRole.value(), saCheckRole.mode());
|
||||
} else {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- 验证权限
|
||||
SaCheckPermission saCheckPermission = null;
|
||||
if (method.isAnnotationPresent(SaCheckPermission.class)) { // 方法注解的优先级高于类注解
|
||||
saCheckPermission = method.getAnnotation(SaCheckPermission.class);
|
||||
} else if (cutClass.isAnnotationPresent(SaCheckPermission.class)){
|
||||
saCheckPermission = cutClass.getAnnotation(SaCheckPermission.class);
|
||||
}
|
||||
if (saCheckPermission != null) {
|
||||
String loginKey = saCheckPermission.key();
|
||||
if (stpLogicMap.containsKey(loginKey)) {
|
||||
StpLogic stpLogic = stpLogicMap.get(loginKey);
|
||||
stpLogic.checkHasPermissions(saCheckPermission.value(), saCheckPermission.mode());
|
||||
} else {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.DEFAULT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
SaManager.getSaTokenAction().checkMethodAnnotation(method);
|
||||
|
||||
// 通过验证
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user