Browse Source

update 更新saToken版本
update 清除冗余tokenValue信息

18339543638 3 years ago
parent
commit
0156a2a910

+ 1 - 1
nb-admin/src/main/java/com/nb/admin/controller/monitor/OnlineUserController.java

@@ -40,7 +40,7 @@ public class OnlineUserController {
     @SaCheckPermission("monitor:online:page")
     @Log(title = "在线用户分页查询")
     public R page(Page reqPage, String username, String userPlatform) {
-        List<String> keys = SecurityUtil.getStpLogic().searchTokenValue("", -1, 0);
+        List<String> keys = SecurityUtil.getStpLogic().searchTokenValue("", -1, 0,false);
         List<LoginUser> loginUserList = Lists.newArrayList();
         for (String key : keys) {
             // token sample, Authorization:login:token:8734da0866f4440daeea3d836d5ecf8c

+ 1 - 1
nb-admin/src/main/resources/application-dev.yml

@@ -81,7 +81,7 @@ spring:
       # 端口,默认为6379
     port: 9736
       # 数据库索引
-    database: 6
+    database: 3
     # 密码
     password: 6E6985E1F7CB40F24A\.
     # 连接超时时间

+ 1 - 1
nb-admin/src/main/resources/application.yml

@@ -37,7 +37,7 @@ sa-token:
   # token名称 (同时也是cookie名称)
   token-name: Authorization
   # token有效期,单位s 默认30天, -1代表永不过期
-#  timeout: -1
+  timeout: -1
   # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 一天
   activity-timeout: 86400
   # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)

+ 4 - 0
nb-auth/pom.xml

@@ -13,6 +13,10 @@
 
 
     <dependencies>
+        <dependency>
+            <groupId>com.tuoren</groupId>
+            <artifactId>delay-queue-common</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.tuoren</groupId>
             <artifactId>nb-core</artifactId>

+ 12 - 0
nb-auth/src/main/java/com/nb/auth/delay/AuthDelayConstant.java

@@ -0,0 +1,12 @@
+package com.nb.auth.delay;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AuthDelayConstant.java
+ * @Description TODO
+ * @createTime 2022年09月16日 13:46:00
+ */
+public class AuthDelayConstant {
+    public static final String AUTH_HANDLER="auth_login";
+}

+ 23 - 0
nb-auth/src/main/java/com/nb/auth/delay/AuthDelayMessage.java

@@ -0,0 +1,23 @@
+package com.nb.auth.delay;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AuthDelayMessage.java
+ * @Description TODO
+ * @createTime 2022年09月16日 13:40:00
+ */
+@Data
+@AllArgsConstructor(staticName = "of")
+public class AuthDelayMessage implements Serializable {
+    private String loginType;
+    private String tokenValue;
+    private long activityTimeout;
+    private TimeUnit unit;
+}

+ 74 - 0
nb-auth/src/main/java/com/nb/auth/delay/AuthDelayMessageHandler.java

@@ -0,0 +1,74 @@
+package com.nb.auth.delay;
+
+import cn.dev33.satoken.dao.SaTokenDao;
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.exception.SaTokenException;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.nb.auth.utils.SecurityUtil;
+import com.nb.common.queue.delay.handler.DelayMessageHandler;
+import com.nb.common.queue.delay.manager.DelayMessageManager;
+import com.nb.common.queue.delay.message.DelayMessage;
+import com.nb.common.queue.delay.message.DelayMessageProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AuthDelayHandler.java
+ * @Description TODO
+ * @createTime 2022年09月16日 13:46:00
+ */
+@Component
+@Slf4j
+public class AuthDelayMessageHandler implements DelayMessageHandler {
+    @Autowired
+    @Lazy
+    private DelayMessageManager delayMessageManager;
+    @Override
+    public String getId() {
+        return AuthDelayConstant.AUTH_HANDLER;
+    }
+
+    @Override
+    public String description() {
+        return "登录成功后处理,清除冗余token,减少冗余资源";
+    }
+
+    @Override
+    public void handle(DelayMessage message) {
+        AuthDelayMessage body = message.getBody().as(AuthDelayMessage.class);
+        if(body==null){
+            return;
+        }
+        if(StrUtil.isEmpty(body.getTokenValue())){
+            return;
+        }
+        String tokenValue = body.getTokenValue();
+        StpLogic stpLogic =null;
+        try {
+            stpLogic = SecurityUtil.getStpLogic(body.getLoginType());
+            long timeout = stpLogic.getTokenActivityTimeoutByToken(tokenValue);
+            if(timeout == SaTokenDao.NOT_VALUE_EXPIRE) {
+                throw NotLoginException.newInstance(body.getLoginType(), NotLoginException.TOKEN_TIMEOUT, tokenValue);
+            }
+            //继续判断
+            delayMessageManager.add(new DelayMessage(message, AuthDelayConstant.AUTH_HANDLER, DelayMessageProperties.of(TimeUnit.SECONDS,body.getActivityTimeout())));
+        }catch (NotLoginException e){
+            //已过期,清除
+            if(stpLogic!=null){
+                stpLogic.logoutByTokenValue(tokenValue);
+            }
+            log.info("清除冗余tokenValue:{},loginType:{}",tokenValue,body.getLoginType());
+        }catch (SaTokenException e){
+            log.error("清除冗余token数据发生错误,message:{}", JSONUtil.toJsonStr(body),e);
+        }
+
+    }
+}

+ 77 - 0
nb-auth/src/main/java/com/nb/auth/sa/DefaultSaTokenListener.java

@@ -0,0 +1,77 @@
+package com.nb.auth.sa;
+
+import cn.dev33.satoken.config.SaTokenConfig;
+import cn.dev33.satoken.listener.SaTokenListener;
+import cn.dev33.satoken.stp.SaLoginModel;
+import com.nb.auth.delay.AuthDelayConstant;
+import com.nb.auth.delay.AuthDelayMessage;
+import com.nb.common.queue.delay.manager.DelayMessageManager;
+import com.nb.common.queue.delay.message.DelayMessage;
+import com.nb.common.queue.delay.message.DelayMessageProperties;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DefaultSaTokenListener.java
+ * @Description TODO
+ * @createTime 2022年09月16日 13:38:00
+ */
+@Component
+@AllArgsConstructor
+@Slf4j
+public class DefaultSaTokenListener implements SaTokenListener {
+    private final DelayMessageManager delayMessageManager;
+    private final SaTokenConfig saTokenConfig;
+
+
+    @Override
+    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
+        AuthDelayMessage message = AuthDelayMessage.of(loginType, tokenValue, saTokenConfig.getActivityTimeout(), TimeUnit.SECONDS);
+        log.info("账号{}登录成功,tokenValue:{},loginType:{}",loginId,loginModel.getToken(),loginType);
+        delayMessageManager.add(new DelayMessage(message, AuthDelayConstant.AUTH_HANDLER, DelayMessageProperties.of(TimeUnit.SECONDS,saTokenConfig.getActivityTimeout())));
+    }
+
+    @Override
+    public void doLogout(String loginType, Object loginId, String tokenValue) {
+
+    }
+
+    @Override
+    public void doKickout(String loginType, Object loginId, String tokenValue) {
+
+    }
+
+    @Override
+    public void doReplaced(String loginType, Object loginId, String tokenValue) {
+
+    }
+
+    @Override
+    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
+
+    }
+
+    @Override
+    public void doUntieDisable(String loginType, Object loginId, String service) {
+
+    }
+
+    @Override
+    public void doCreateSession(String id) {
+
+    }
+
+    @Override
+    public void doLogoutSession(String id) {
+
+    }
+
+    @Override
+    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
+
+    }
+}

+ 82 - 1
nb-auth/src/main/java/com/nb/auth/sa/SaConfig.java

@@ -1,13 +1,20 @@
 package com.nb.auth.sa;
 
 import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.annotation.*;
+import cn.dev33.satoken.basic.SaBasicUtil;
 import cn.dev33.satoken.dao.SaTokenDaoRedisJackson;
+import cn.dev33.satoken.exception.NotPermissionException;
 import cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.strategy.SaStrategy;
+import cn.hutool.core.util.StrUtil;
 import com.nb.auth.enums.StpTypeEnum;
+import com.nb.auth.utils.SecurityUtil;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
+import java.util.regex.Pattern;
 
 /**
  * @author lifang
@@ -20,13 +27,87 @@ import javax.annotation.PostConstruct;
 @AllArgsConstructor
 public class SaConfig {
     private final SaTokenDaoRedisJackson saTokenDaoRedisJackson;
+    private final DefaultSaTokenListener defaultSaTokenListener;
     @PostConstruct
     public void init(){
-        SaManager.setSaTokenAction(new SaTokenActionDefaultImpl());
+        SaStrategy.me.hasElement=(list,element)->{
+            // 空集合直接返回false
+            if(list == null || list.size() == 0) {
+                return false;
+            }
+            // 先尝试一下简单匹配,如果可以匹配成功则无需继续模糊匹配
+            if (list.contains(element)) {
+                return true;
+            }
+            // 开始模糊匹配
+            for (String patt : list) {
+                if(vagueMatch(patt, element)) {
+                    return true;
+                }
+            }
+            // 走出for循环说明没有一个元素可以匹配成功
+            return false;
+        };
+        SaStrategy.me.checkElementAnnotation=target->{
+            // 校验 @SaCheckLogin 注解
+            SaCheckLogin checkLogin = (SaCheckLogin) SaStrategy.me.getAnnotation.apply(target, SaCheckLogin.class);
+            if(checkLogin != null) {
+                SaManager.getStpLogic(checkLogin.type()).checkByAnnotation(checkLogin);
+            }
+
+            // 校验 @SaCheckRole 注解
+            SaCheckRole checkRole = (SaCheckRole) SaStrategy.me.getAnnotation.apply(target, SaCheckRole.class);
+            if(checkRole != null) {
+                SaManager.getStpLogic(checkRole.type()).checkByAnnotation(checkRole);
+            }
+
+            // 校验 @SaCheckPermission 注解
+            SaCheckPermission checkPermission = (SaCheckPermission) SaStrategy.me.getAnnotation.apply(target, SaCheckPermission.class);
+            if(checkPermission != null) {
+                String type= StrUtil.isBlankIfStr(checkPermission.type())?"login":checkPermission.type();
+                StpLogic stpLogic = SecurityUtil.getStpLogic();
+                if (!type.equals(stpLogic.getLoginType())) {
+                    throw new NotPermissionException("无权限访问此体系接口");
+                }
+                SaManager.getStpLogic(checkPermission.type()).checkByAnnotation(checkPermission);
+            }
+
+            // 校验 @SaCheckSafe 注解
+            SaCheckSafe checkSafe = (SaCheckSafe) SaStrategy.me.getAnnotation.apply(target, SaCheckSafe.class);
+            if(checkSafe != null) {
+                SaManager.getStpLogic(checkSafe.type()).checkByAnnotation(checkSafe);
+            }
+
+            // 校验 @SaCheckBasic 注解
+            SaCheckBasic checkBasic = (SaCheckBasic) SaStrategy.me.getAnnotation.apply(target, SaCheckBasic.class);
+            if(checkBasic != null) {
+                SaBasicUtil.check(checkBasic.realm(), checkBasic.account());
+            }
+        };
+//        SaManager.setSaTokenContext();
+//        SaManager.setSaTokenAction(new SaTokenActionDefaultImpl());
         SaManager.setSaTokenDao(saTokenDaoRedisJackson);
+//        SaManager.setSaTokenListener(defaultSaTokenListener);
         StpTypeEnum[] values = StpTypeEnum.values();
         for (StpTypeEnum value : values) {
             SaManager.putStpLogic(new StpLogic(value.getText()));
         }
     }
+
+    /**
+     * 字符串模糊匹配
+     * <p>example:
+     * <p> user-add user*    --  true
+     * <p> art-add user*     --  false
+     * @param patt 表达式
+     * @param str 待匹配的字符串
+     * @return 是否可以匹配
+     */
+    public static boolean vagueMatch(String patt, String str) {
+        // 如果表达式不带有*号,则只需简单equals即可 (速度提升200倍)
+        if(!str.contains("*")&&!patt.contains("*")) {
+            return patt.equals(str);
+        }
+        return Pattern.matches(str.replaceAll("\\*", ".*"), patt)||Pattern.matches(patt.replaceAll("\\*", ".*"), str);
+    }
 }

+ 178 - 178
nb-auth/src/main/java/com/nb/auth/sa/SaTokenActionDefaultImpl.java

@@ -1,178 +1,178 @@
-package com.nb.auth.sa;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.UUID;
-import java.util.regex.Pattern;
-
-import cn.dev33.satoken.SaManager;
-import cn.dev33.satoken.action.SaTokenAction;
-import cn.dev33.satoken.annotation.SaCheckBasic;
-import cn.dev33.satoken.annotation.SaCheckLogin;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import cn.dev33.satoken.annotation.SaCheckSafe;
-import cn.dev33.satoken.basic.SaBasicUtil;
-import cn.dev33.satoken.exception.NotPermissionException;
-import cn.dev33.satoken.session.SaSession;
-import cn.dev33.satoken.stp.StpLogic;
-import cn.dev33.satoken.strategy.SaStrategy;
-import cn.dev33.satoken.util.SaFoxUtil;
-import cn.dev33.satoken.util.SaTokenConsts;
-import cn.hutool.core.util.StrUtil;
-import com.nb.auth.utils.SecurityUtil;
-
-/**
- * <h1> v1.27+ 此接口已废弃,目前版本暂时向下兼容,请及时更换为 SaStrategy </h1>
- * <p> Sa-Token 逻辑代理接口 [默认实现类]  </p> 
- * @author kong
- *
- */
-public class SaTokenActionDefaultImpl implements SaTokenAction {
-
-	/**
-	 * 创建一个Token 
-	 */
-	@Override
-	public String createToken(Object loginId, String loginType) {
-		// 根据配置的tokenStyle生成不同风格的token 
-		String tokenStyle = SaManager.getConfig().getTokenStyle();
-		// uuid 
-		if(SaTokenConsts.TOKEN_STYLE_UUID.equals(tokenStyle)) {
-			return UUID.randomUUID().toString();
-		}
-		// 简单uuid (不带下划线)
-		if(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID.equals(tokenStyle)) {
-			return UUID.randomUUID().toString().replaceAll("-", "");
-		}
-		// 32位随机字符串
-		if(SaTokenConsts.TOKEN_STYLE_RANDOM_32.equals(tokenStyle)) {
-			return SaFoxUtil.getRandomString(32);
-		}
-		// 64位随机字符串
-		if(SaTokenConsts.TOKEN_STYLE_RANDOM_64.equals(tokenStyle)) {
-			return SaFoxUtil.getRandomString(64);
-		}
-		// 128位随机字符串
-		if(SaTokenConsts.TOKEN_STYLE_RANDOM_128.equals(tokenStyle)) {
-			return SaFoxUtil.getRandomString(128);
-		}
-		// tik风格 (2_14_16)
-		if(SaTokenConsts.TOKEN_STYLE_TIK.equals(tokenStyle)) {
-			return SaFoxUtil.getRandomString(2) + "_" + SaFoxUtil.getRandomString(14) + "_" + SaFoxUtil.getRandomString(16) + "__";
-		}
-		// 默认,还是uuid 
-		return UUID.randomUUID().toString();
-	}
-
-	/**
-	 * 创建一个Session 
-	 */
-	@Override
-	public SaSession createSession(String sessionId) {
-		return new SaSession(sessionId);
-	}
-
-	/**
-	 * 判断:集合中是否包含指定元素(模糊匹配) 
-	 */
-	@Override
-	public boolean hasElement(List<String> list, String element) {
-		
-		// 空集合直接返回false
-		if(list == null || list.size() == 0) {
-			return false;
-		}
-
-		// 先尝试一下简单匹配,如果可以匹配成功则无需继续模糊匹配 
-		if (list.contains(element)) {
-			return true;
-		}
-		
-		// 开始模糊匹配 
-		for (String patt : list) {
-			if(vagueMatch(patt, element)) {
-				return true;
-			}
-		}
-		
-		// 走出for循环说明没有一个元素可以匹配成功 
-		return false;
-	}
-
-	/**
-	 * 对一个Method对象进行注解检查(注解鉴权内部实现) 
-	 */
-	@Override
-	public void checkMethodAnnotation(Method method) {
-
-		// 先校验 Method 所属 Class 上的注解 
-		validateAnnotation(method.getDeclaringClass());
-		
-		// 再校验 Method 上的注解  
-		validateAnnotation(method);
-	}
-
-	/**
-	 * 从指定元素校验注解 
-	 * @param target see note 
-	 */
-	@Override
-	public void validateAnnotation(AnnotatedElement target) {
-
-		// 校验 @SaCheckLogin 注解 
-		SaCheckLogin checkLogin = (SaCheckLogin) SaStrategy.me.getAnnotation.apply(target, SaCheckLogin.class);
-		if(checkLogin != null) {
-			SaManager.getStpLogic(checkLogin.type()).checkByAnnotation(checkLogin);
-		}
-		
-		// 校验 @SaCheckRole 注解 
-		SaCheckRole checkRole = (SaCheckRole) SaStrategy.me.getAnnotation.apply(target, SaCheckRole.class);
-		if(checkRole != null) {
-			SaManager.getStpLogic(checkRole.type()).checkByAnnotation(checkRole);
-		}
-		
-		// 校验 @SaCheckPermission 注解
-		SaCheckPermission checkPermission = (SaCheckPermission) SaStrategy.me.getAnnotation.apply(target, SaCheckPermission.class);
-		if(checkPermission != null) {
-			String type= StrUtil.isBlankIfStr(checkPermission.type())?"login":checkPermission.type();
-			StpLogic stpLogic = SecurityUtil.getStpLogic();
-			if (!type.equals(stpLogic.getLoginType())) {
-				throw new NotPermissionException("无权限访问此体系接口");
-			}
-			SaManager.getStpLogic(checkPermission.type()).checkByAnnotation(checkPermission);
-		}
-
-		// 校验 @SaCheckSafe 注解
-		SaCheckSafe checkSafe = (SaCheckSafe) SaStrategy.me.getAnnotation.apply(target, SaCheckSafe.class);
-		if(checkSafe != null) {
-			SaManager.getStpLogic(checkSafe.type()).checkByAnnotation(checkSafe);
-		}
-		
-		// 校验 @SaCheckBasic 注解
-		SaCheckBasic checkBasic = (SaCheckBasic) SaStrategy.me.getAnnotation.apply(target, SaCheckBasic.class);
-		if(checkBasic != null) {
-			SaBasicUtil.check(checkBasic.realm(), checkBasic.account());
-		}
-		
-	}
-
-
-	/**
-	 * 字符串模糊匹配
-	 * <p>example:
-	 * <p> user-add user*    --  true
-	 * <p> art-add user*     --  false
-	 * @param patt 表达式
-	 * @param str 待匹配的字符串
-	 * @return 是否可以匹配
-	 */
-	public static boolean vagueMatch(String patt, String str) {
-		// 如果表达式不带有*号,则只需简单equals即可 (速度提升200倍)
-		if(!str.contains("*")&&!patt.contains("*")) {
-			return patt.equals(str);
-		}
-		return Pattern.matches(str.replaceAll("\\*", ".*"), patt)||Pattern.matches(patt.replaceAll("\\*", ".*"), str);
-	}
-}
+//package com.nb.auth.sa;
+//
+//import java.lang.reflect.AnnotatedElement;
+//import java.lang.reflect.Method;
+//import java.util.List;
+//import java.util.UUID;
+//import java.util.regex.Pattern;
+//
+//import cn.dev33.satoken.SaManager;
+//import cn.dev33.satoken.action.SaTokenAction;
+//import cn.dev33.satoken.annotation.SaCheckBasic;
+//import cn.dev33.satoken.annotation.SaCheckLogin;
+//import cn.dev33.satoken.annotation.SaCheckPermission;
+//import cn.dev33.satoken.annotation.SaCheckRole;
+//import cn.dev33.satoken.annotation.SaCheckSafe;
+//import cn.dev33.satoken.basic.SaBasicUtil;
+//import cn.dev33.satoken.exception.NotPermissionException;
+//import cn.dev33.satoken.session.SaSession;
+//import cn.dev33.satoken.stp.StpLogic;
+//import cn.dev33.satoken.strategy.SaStrategy;
+//import cn.dev33.satoken.util.SaFoxUtil;
+//import cn.dev33.satoken.util.SaTokenConsts;
+//import cn.hutool.core.util.StrUtil;
+//import com.nb.auth.utils.SecurityUtil;
+//
+///**
+// * <h1> v1.27+ 此接口已废弃,目前版本暂时向下兼容,请及时更换为 SaStrategy </h1>
+// * <p> Sa-Token 逻辑代理接口 [默认实现类]  </p>
+// * @author kong
+// *
+// */
+//public class SaTokenActionDefaultImpl implements SaTokenAction {
+//
+//	/**
+//	 * 创建一个Token
+//	 */
+//	@Override
+//	public String createToken(Object loginId, String loginType) {
+//		// 根据配置的tokenStyle生成不同风格的token
+//		String tokenStyle = SaManager.getConfig().getTokenStyle();
+//		// uuid
+//		if(SaTokenConsts.TOKEN_STYLE_UUID.equals(tokenStyle)) {
+//			return UUID.randomUUID().toString();
+//		}
+//		// 简单uuid (不带下划线)
+//		if(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID.equals(tokenStyle)) {
+//			return UUID.randomUUID().toString().replaceAll("-", "");
+//		}
+//		// 32位随机字符串
+//		if(SaTokenConsts.TOKEN_STYLE_RANDOM_32.equals(tokenStyle)) {
+//			return SaFoxUtil.getRandomString(32);
+//		}
+//		// 64位随机字符串
+//		if(SaTokenConsts.TOKEN_STYLE_RANDOM_64.equals(tokenStyle)) {
+//			return SaFoxUtil.getRandomString(64);
+//		}
+//		// 128位随机字符串
+//		if(SaTokenConsts.TOKEN_STYLE_RANDOM_128.equals(tokenStyle)) {
+//			return SaFoxUtil.getRandomString(128);
+//		}
+//		// tik风格 (2_14_16)
+//		if(SaTokenConsts.TOKEN_STYLE_TIK.equals(tokenStyle)) {
+//			return SaFoxUtil.getRandomString(2) + "_" + SaFoxUtil.getRandomString(14) + "_" + SaFoxUtil.getRandomString(16) + "__";
+//		}
+//		// 默认,还是uuid
+//		return UUID.randomUUID().toString();
+//	}
+//
+//	/**
+//	 * 创建一个Session
+//	 */
+//	@Override
+//	public SaSession createSession(String sessionId) {
+//		return new SaSession(sessionId);
+//	}
+//
+//	/**
+//	 * 判断:集合中是否包含指定元素(模糊匹配)
+//	 */
+//	@Override
+//	public boolean hasElement(List<String> list, String element) {
+//
+//		// 空集合直接返回false
+//		if(list == null || list.size() == 0) {
+//			return false;
+//		}
+//
+//		// 先尝试一下简单匹配,如果可以匹配成功则无需继续模糊匹配
+//		if (list.contains(element)) {
+//			return true;
+//		}
+//
+//		// 开始模糊匹配
+//		for (String patt : list) {
+//			if(vagueMatch(patt, element)) {
+//				return true;
+//			}
+//		}
+//
+//		// 走出for循环说明没有一个元素可以匹配成功
+//		return false;
+//	}
+//
+//	/**
+//	 * 对一个Method对象进行注解检查(注解鉴权内部实现)
+//	 */
+//	@Override
+//	public void checkMethodAnnotation(Method method) {
+//
+//		// 先校验 Method 所属 Class 上的注解
+//		validateAnnotation(method.getDeclaringClass());
+//
+//		// 再校验 Method 上的注解
+//		validateAnnotation(method);
+//	}
+//
+//	/**
+//	 * 从指定元素校验注解
+//	 * @param target see note
+//	 */
+//	@Override
+//	public void validateAnnotation(AnnotatedElement target) {
+//
+//		// 校验 @SaCheckLogin 注解
+//		SaCheckLogin checkLogin = (SaCheckLogin) SaStrategy.me.getAnnotation.apply(target, SaCheckLogin.class);
+//		if(checkLogin != null) {
+//			SaManager.getStpLogic(checkLogin.type()).checkByAnnotation(checkLogin);
+//		}
+//
+//		// 校验 @SaCheckRole 注解
+//		SaCheckRole checkRole = (SaCheckRole) SaStrategy.me.getAnnotation.apply(target, SaCheckRole.class);
+//		if(checkRole != null) {
+//			SaManager.getStpLogic(checkRole.type()).checkByAnnotation(checkRole);
+//		}
+//
+//		// 校验 @SaCheckPermission 注解
+//		SaCheckPermission checkPermission = (SaCheckPermission) SaStrategy.me.getAnnotation.apply(target, SaCheckPermission.class);
+//		if(checkPermission != null) {
+//			String type= StrUtil.isBlankIfStr(checkPermission.type())?"login":checkPermission.type();
+//			StpLogic stpLogic = SecurityUtil.getStpLogic();
+//			if (!type.equals(stpLogic.getLoginType())) {
+//				throw new NotPermissionException("无权限访问此体系接口");
+//			}
+//			SaManager.getStpLogic(checkPermission.type()).checkByAnnotation(checkPermission);
+//		}
+//
+//		// 校验 @SaCheckSafe 注解
+//		SaCheckSafe checkSafe = (SaCheckSafe) SaStrategy.me.getAnnotation.apply(target, SaCheckSafe.class);
+//		if(checkSafe != null) {
+//			SaManager.getStpLogic(checkSafe.type()).checkByAnnotation(checkSafe);
+//		}
+//
+//		// 校验 @SaCheckBasic 注解
+//		SaCheckBasic checkBasic = (SaCheckBasic) SaStrategy.me.getAnnotation.apply(target, SaCheckBasic.class);
+//		if(checkBasic != null) {
+//			SaBasicUtil.check(checkBasic.realm(), checkBasic.account());
+//		}
+//
+//	}
+//
+//
+//	/**
+//	 * 字符串模糊匹配
+//	 * <p>example:
+//	 * <p> user-add user*    --  true
+//	 * <p> art-add user*     --  false
+//	 * @param patt 表达式
+//	 * @param str 待匹配的字符串
+//	 * @return 是否可以匹配
+//	 */
+//	public static boolean vagueMatch(String patt, String str) {
+//		// 如果表达式不带有*号,则只需简单equals即可 (速度提升200倍)
+//		if(!str.contains("*")&&!patt.contains("*")) {
+//			return patt.equals(str);
+//		}
+//		return Pattern.matches(str.replaceAll("\\*", ".*"), patt)||Pattern.matches(patt.replaceAll("\\*", ".*"), str);
+//	}
+//}

+ 6 - 0
nb-common/delay-queue-common/src/main/java/com/nb/common/queue/delay/message/DelayMessage.java

@@ -53,6 +53,12 @@ public class DelayMessage implements Serializable {
         this.properties = properties;
     }
 
+    public DelayMessage(@NonNull Object body, @NonNull String handlerId, @NonNull DelayMessageProperties properties) {
+        this.msgId = UUID.randomUUID().toString();
+        this.body = Value.simple(body);
+        this.handlerId = handlerId;
+        this.properties = properties;
+    }
 
 
     public void check() {

+ 1 - 1
pom.xml

@@ -33,7 +33,7 @@
         <okhttp.version>4.9.3</okhttp.version>
         <velocity.version>2.3</velocity.version>
         <log4j2.version>2.17.1</log4j2.version>
-        <satoken.version>1.29.0</satoken.version>
+        <satoken.version>1.31.0</satoken.version>
         <springfox.version>3.0.0</springfox.version>
         <tio.version>3.6.0.v20200315-RELEASE</tio.version>
         <jython.version>2.7.1</jython.version>