From 1feca73e2a70476137186de51e74a5a9db30108f Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Thu, 5 Jan 2023 19:20:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=20springboot3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/dev33/satoken/id/SaIdTemplate.java | 175 --------------- .../java/cn/dev33/satoken/id/SaIdUtil.java | 86 -------- .../sa-token-demo-alone-redis/pom.xml | 2 +- sa-token-demo/sa-token-demo-case/pom.xml | 2 +- .../sa-token-demo-dubbo-consumer/pom.xml | 3 +- .../sa-token-demo-dubbo-provider/pom.xml | 3 +- sa-token-demo/sa-token-demo-jwt/pom.xml | 2 +- .../sa-token-demo-oauth2-client/pom.xml | 2 +- .../sa-token-demo-oauth2-server/pom.xml | 2 +- .../sa-token-demo-quick-login/pom.xml | 2 +- sa-token-demo/sa-token-demo-solon/pom.xml | 2 + .../sa-token-demo-springboot-redis/pom.xml | 2 +- .../src/main/resources/application.yml | 4 +- .../sa-token-demo-springboot/pom.xml | 2 +- .../.gitignore | 12 ++ .../sa-token-demo-springboot3-redis/pom.xml | 71 ++++++ .../com/pj/SaTokenSpringBoot3Application.java | 21 ++ .../java/com/pj/current/GlobalException.java | 56 +++++ .../java/com/pj/current/NotFoundHandle.java | 26 +++ .../java/com/pj/satoken/SaTokenConfigure.java | 71 ++++++ .../java/com/pj/satoken/StpInterfaceImpl.java | 44 ++++ .../main/java/com/pj/test/AtController.java | 80 +++++++ .../java/com/pj/test/LoginController.java | 48 +++++ .../com/pj/test/StressTestController.java | 61 ++++++ .../main/java/com/pj/test/TestController.java | 30 +++ .../src/main/java/com/pj/util/AjaxJson.java | 162 ++++++++++++++ .../src/main/java/com/pj/util/Ttime.java | 63 ++++++ .../src/main/resources/application.yml | 50 +++++ .../sa-token-demo-sso-server/pom.xml | 2 +- .../sa-token-demo-sso1-client/pom.xml | 2 +- .../sa-token-demo-sso2-client/pom.xml | 2 +- .../sa-token-demo-sso3-client-nosdk/pom.xml | 2 +- .../sa-token-demo-sso3-client/pom.xml | 2 +- sa-token-demo/sa-token-demo-test/pom.xml | 2 +- sa-token-demo/sa-token-demo-thymeleaf/pom.xml | 2 +- .../.gitignore | 12 ++ .../sa-token-demo-webflux-springboot3/pom.xml | 72 +++++++ .../SaTokenWebfluxSpringboot3Application.java | 23 ++ .../java/com/pj/satoken/SaTokenConfigure.java | 41 ++++ .../java/com/pj/satoken/StpInterfaceImpl.java | 44 ++++ .../main/java/com/pj/test/DefineRoutes.java | 35 +++ .../java/com/pj/test/GlobalException.java | 52 +++++ .../main/java/com/pj/test/TestController.java | 80 +++++++ .../src/main/java/com/pj/util/AjaxJson.java | 154 +++++++++++++ .../src/main/resources/application.yml | 46 ++++ sa-token-demo/sa-token-demo-webflux/pom.xml | 4 +- ...on.java => SaTokenWebfluxApplication.java} | 4 +- .../src/main/resources/application.yml | 2 + .../sa-token-demo-websocket-spring/pom.xml | 2 +- sa-token-demo/sa-token-demo-websocket/pom.xml | 2 +- sa-token-dependencies/pom.xml | 30 ++- ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 4 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + sa-token-plugin/sa-token-quick-login/pom.xml | 2 + .../cn/dev33/satoken/quick/SaQuickInject.java | 2 +- .../dev33/satoken/quick/SaQuickRegister.java | 10 +- .../satoken/quick/web/SaQuickController.java | 7 +- .../main/resources/META-INF/spring.factories | 3 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../cn/dev33/satoken/aop/SaCheckAspect.java | 1 - ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + sa-token-starter/pom.xml | 4 + .../sa-token-jakarta-servlet/.gitignore | 12 ++ .../sa-token-jakarta-servlet/pom.xml | 35 +++ .../servlet/error/SaServletErrorCode.java | 17 ++ .../servlet/model/SaRequestForServlet.java | 117 ++++++++++ .../servlet/model/SaResponseForServlet.java | 79 +++++++ .../servlet/model/SaStorageForServlet.java | 60 ++++++ .../dev33/satoken/servlet/package-info.java | 4 + .../pom.xml | 41 ++-- .../satoken/reactor/spring/SaBeanInject.java | 186 ---------------- .../reactor/spring/SaBeanRegister.java | 50 ----- .../reactor/spring/SaPathMatcherHolder.java | 37 ---- .../SaTokenContextForSpringReactor.java | 1 + .../spring/SaTokenContextRegister.java | 25 +++ .../spring/json/SaJsonTemplateForJackson.java | 53 ----- .../spring/oauth2/SaOAuth2BeanInject.java | 40 ---- .../spring/oauth2/SaOAuth2BeanRegister.java | 28 --- .../reactor/spring/oauth2/package-info.java | 4 - .../reactor/spring/sso/SaSsoBeanInject.java | 40 ---- .../reactor/spring/sso/SaSsoBeanRegister.java | 28 --- .../reactor/spring/sso/package-info.java | 4 - .../main/resources/META-INF/spring.factories | 7 +- .../.gitignore | 12 ++ .../pom.xml | 118 ++++++++++ .../reactor/context/SaReactorHolder.java | 49 +++++ .../reactor/context/SaReactorSyncHolder.java | 63 ++++++ .../error/SaReactorSpringBootErrorCode.java | 20 ++ .../reactor/filter/SaReactorFilter.java | 203 ++++++++++++++++++ .../reactor/model/SaRequestForReactor.java | 113 ++++++++++ .../reactor/model/SaResponseForReactor.java | 77 +++++++ .../reactor/model/SaStorageForReactor.java | 61 ++++++ .../dev33/satoken/reactor/package-info.java | 4 + .../SaTokenContextForSpringReactor.java | 22 ++ .../spring/SaTokenContextRegister.java | 25 +++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + sa-token-starter/sa-token-servlet/pom.xml | 2 +- .../cn/dev33/satoken/solon/XPluginImp.java | 9 +- .../.gitignore | 12 ++ .../sa-token-spring-boot-autoconfig/pom.xml | 57 +++++ .../satoken/error/SaSpringBootErrorCode.java | 0 .../java/cn/dev33/satoken/package-info.java | 4 + .../cn/dev33/satoken/spring/SaBeanInject.java | 13 -- .../dev33/satoken/spring/SaBeanRegister.java | 11 - .../satoken/spring/SaPathMatcherHolder.java | 0 .../spring/json/SaJsonTemplateForJackson.java | 0 .../spring/oauth2/SaOAuth2BeanInject.java | 0 .../spring/oauth2/SaOAuth2BeanRegister.java | 0 .../satoken/spring/oauth2/package-info.java | 0 .../satoken/spring/sso/SaSsoBeanInject.java | 0 .../satoken/spring/sso/SaSsoBeanRegister.java | 0 .../satoken/spring/sso/package-info.java | 0 .../main/resources/META-INF/spring.factories | 7 + ...ot.autoconfigure.AutoConfiguration.imports | 6 + .../sa-token-spring-boot-starter/pom.xml | 17 +- .../interceptor/SaAnnotationInterceptor.java | 48 ----- .../interceptor/SaRouteInterceptor.java | 79 ------- .../spring/SaTokenContextRegister.java | 25 +++ .../main/resources/META-INF/spring.factories | 7 +- .../sa-token-spring-boot3-starter/.gitignore | 12 ++ .../sa-token-spring-boot3-starter/pom.xml | 77 +++++++ .../dev33/satoken/filter/SaServletFilter.java | 191 ++++++++++++++++ .../satoken/interceptor/SaInterceptor.java | 113 ++++++++++ .../java/cn/dev33/satoken/package-info.java | 4 + ...TokenContextForSpringInJakartaServlet.java | 59 +++++ .../spring/SaTokenContextRegister.java | 26 +++ .../dev33/satoken/spring/SpringMVCUtil.java | 53 +++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + 134 files changed, 3238 insertions(+), 974 deletions(-) delete mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java delete mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/.gitignore create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/pom.xml create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/SaTokenSpringBoot3Application.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/GlobalException.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/NotFoundHandle.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/SaTokenConfigure.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/StpInterfaceImpl.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/AtController.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/LoginController.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/StressTestController.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/TestController.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/AjaxJson.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/Ttime.java create mode 100644 sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/.gitignore create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/pom.xml create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/SaTokenWebfluxSpringboot3Application.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/SaTokenConfigure.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/StpInterfaceImpl.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/DefineRoutes.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/GlobalException.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/TestController.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/util/AjaxJson.java create mode 100644 sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml rename sa-token-demo/sa-token-demo-webflux/src/main/java/com/pj/{SaTokenWebfluxDemoApplication.java => SaTokenWebfluxApplication.java} (77%) create mode 100644 sa-token-plugin/sa-token-alone-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-context-grpc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-dao-redis-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-dao-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-spring-aop/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-starter/sa-token-jakarta-servlet/.gitignore create mode 100644 sa-token-starter/sa-token-jakarta-servlet/pom.xml create mode 100644 sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/error/SaServletErrorCode.java create mode 100644 sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java create mode 100644 sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java create mode 100644 sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java create mode 100644 sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/package-info.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanInject.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaBeanRegister.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaPathMatcherHolder.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextRegister.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/json/SaJsonTemplateForJackson.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/oauth2/SaOAuth2BeanInject.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/oauth2/SaOAuth2BeanRegister.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/oauth2/package-info.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/SaSsoBeanInject.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/SaSsoBeanRegister.java delete mode 100644 sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/spring/sso/package-info.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/.gitignore create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/pom.xml create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorHolder.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorSyncHolder.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/error/SaReactorSpringBootErrorCode.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/package-info.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextForSpringReactor.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextRegister.java create mode 100644 sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 sa-token-starter/sa-token-spring-boot-autoconfig/.gitignore create mode 100644 sa-token-starter/sa-token-spring-boot-autoconfig/pom.xml rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java (100%) create mode 100644 sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/package-info.java rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java (92%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java (79%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/SaPathMatcherHolder.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/oauth2/package-info.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanRegister.java (100%) rename sa-token-starter/{sa-token-spring-boot-starter => sa-token-spring-boot-autoconfig}/src/main/java/cn/dev33/satoken/spring/sso/package-info.java (100%) create mode 100644 sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring.factories create mode 100644 sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java delete mode 100644 sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java create mode 100644 sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/.gitignore create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/pom.xml create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/package-info.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextForSpringInJakartaServlet.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SpringMVCUtil.java create mode 100644 sa-token-starter/sa-token-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java deleted file mode 100644 index a3417aed..00000000 --- a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdTemplate.java +++ /dev/null @@ -1,175 +0,0 @@ -package cn.dev33.satoken.id; - -import cn.dev33.satoken.SaManager; -import cn.dev33.satoken.context.SaHolder; -import cn.dev33.satoken.exception.IdTokenInvalidException; -import cn.dev33.satoken.util.SaFoxUtil; - -/** - *

本类设计已过时,未来版本可能移除此类,请及时更换为 SaSameTemplate ,使用方式保持不变

- * - * Sa-Token-Id 身份凭证模块 - *

身份凭证的获取与校验,可用于微服务内部调用鉴权 - * @author kong - * - */ -@Deprecated -public class SaIdTemplate { - - /** - * 在 Request 上储存 Id-Token 时建议使用的key - */ - public static final String ID_TOKEN = "SA_ID_TOKEN"; - - // -------------------- 获取 & 校验 - - /** - * 获取当前Id-Token, 如果不存在,则立即创建并返回 - * @return 当前token - */ - public String getToken() { - String currentToken = getTokenNh(); - if(SaFoxUtil.isEmpty(currentToken)) { - // 注意这里的自刷新不能做到高并发可用 - currentToken = refreshToken(); - } - return currentToken; - } - - /** - * 判断一个Id-Token是否有效 - * @param token 要验证的token - * @return 这个token是否有效 - */ - public boolean isValid(String token) { - // 1、 如果传入的token未空,立即返回false - if(SaFoxUtil.isEmpty(token)) { - return false; - } - - // 2、 验证当前 Id-Token 及 Past-Id-Token - return token.equals(getToken()) || token.equals(getPastTokenNh()); - } - - /** - * 校验一个Id-Token是否有效 (如果无效则抛出异常) - * @param token 要验证的token - */ - public void checkToken(String token) { - if(isValid(token) == false) { - token = (token == null ? "" : token); - throw new IdTokenInvalidException("无效Id-Token:" + token); - } - } - - /** - * 校验当前Request提供的Id-Token是否有效 (如果无效则抛出异常) - */ - public void checkCurrentRequestToken() { - checkToken(SaHolder.getRequest().getHeader(ID_TOKEN)); - } - - /** - * 刷新一次Id-Token (注意集群环境中不要多个服务重复调用) - * @return 新Token - */ - public String refreshToken() { - - // 1. 先将当前 Id-Token 写入到 Past-Id-Token 中 - String idToken = getTokenNh(); - if(SaFoxUtil.isEmpty(idToken) == false) { - savePastToken(idToken, getTokenTimeout()); - } - - // 2. 再刷新当前Id-Token - String newIdToken = createToken(); - saveToken(newIdToken); - - // 3. 返回新的 Id-Token - return newIdToken; - } - - - // ------------------------------ 保存Token - - /** - * 保存Id-Token - * @param token token - */ - public void saveToken(String token) { - if(SaFoxUtil.isEmpty(token)) { - return; - } - SaManager.getSaTokenDao().set(splicingTokenSaveKey(), token, SaManager.getConfig().getIdTokenTimeout()); - } - - /** - * 保存Past-Id-Token - * @param token token - * @param timeout 有效期(单位:秒) - */ - public void savePastToken(String token, long timeout){ - if(SaFoxUtil.isEmpty(token)) { - return; - } - SaManager.getSaTokenDao().set(splicingPastTokenSaveKey(), token, timeout); - } - - - // -------------------- 获取Token - - /** - * 获取Id-Token,不做任何处理 - * @return token - */ - public String getTokenNh() { - return SaManager.getSaTokenDao().get(splicingTokenSaveKey()); - } - - /** - * 获取Past-Id-Token,不做任何处理 - * @return token - */ - public String getPastTokenNh() { - return SaManager.getSaTokenDao().get(splicingPastTokenSaveKey()); - } - - /** - * 获取Id-Token的剩余有效期 (单位:秒) - * @return token - */ - public long getTokenTimeout() { - return SaManager.getSaTokenDao().getTimeout(splicingTokenSaveKey()); - } - - - // -------------------- 创建Token - - /** - * 创建一个Id-Token - * @return Token - */ - public String createToken() { - return SaFoxUtil.getRandomString(64); - } - - - // -------------------- 拼接key - - /** - * 拼接key:Id-Token 的存储 key - * @return key - */ - public String splicingTokenSaveKey() { - return SaManager.getConfig().getTokenName() + ":var:id-token"; - } - - /** - * 拼接key:次级 Id-Token 的存储 key - * @return key - */ - public String splicingPastTokenSaveKey() { - return SaManager.getConfig().getTokenName() + ":var:past-id-token"; - } - -} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java deleted file mode 100644 index a9ca80a8..00000000 --- a/sa-token-core/src/main/java/cn/dev33/satoken/id/SaIdUtil.java +++ /dev/null @@ -1,86 +0,0 @@ -package cn.dev33.satoken.id; - -/** - *

本类设计已过时,未来版本可能移除此类,请及时更换为 SaSameUtil ,使用方式保持不变

- * - * Sa-Token-Id 身份凭证模块-工具类 - * @author kong - * - */ -@Deprecated -public class SaIdUtil { - - private SaIdUtil(){} - - /** - * 在 Request 上储存 Id-Token 时建议使用的key - */ - public static final String ID_TOKEN = SaIdTemplate.ID_TOKEN; - - /** - * 底层 SaIdTemplate 对象 - */ - public static SaIdTemplate saIdTemplate = new SaIdTemplate(); - - // -------------------- 获取 & 校验 - - /** - * 获取当前Id-Token, 如果不存在,则立即创建并返回 - * @return 当前token - */ - public static String getToken() { - return saIdTemplate.getToken(); - } - - /** - * 判断一个Id-Token是否有效 - * @param token 要验证的token - * @return 这个token是否有效 - */ - public static boolean isValid(String token) { - return saIdTemplate.isValid(token); - } - - /** - * 校验一个Id-Token是否有效 (如果无效则抛出异常) - * @param token 要验证的token - */ - public static void checkToken(String token) { - saIdTemplate.checkToken(token); - } - - /** - * 校验当前Request提供的Id-Token是否有效 (如果无效则抛出异常) - */ - public static void checkCurrentRequestToken() { - saIdTemplate.checkCurrentRequestToken(); - } - - /** - * 刷新一次Id-Token (注意集群环境中不要多个服务重复调用) - * @return 新Token - */ - public static String refreshToken() { - return saIdTemplate.refreshToken(); - } - - - // -------------------- 获取Token - - /** - * 获取Id-Token,不做任何处理 - * @return token - */ - public static String getTokenNh() { - return saIdTemplate.getTokenNh(); - } - - /** - * 获取Past-Id-Token,不做任何处理 - * @return token - */ - public static String getPastTokenNh() { - return saIdTemplate.getPastTokenNh(); - } - -} diff --git a/sa-token-demo/sa-token-demo-alone-redis/pom.xml b/sa-token-demo/sa-token-demo-alone-redis/pom.xml index 096a008e..3d28d1bb 100644 --- a/sa-token-demo/sa-token-demo-alone-redis/pom.xml +++ b/sa-token-demo/sa-token-demo-alone-redis/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-case/pom.xml b/sa-token-demo/sa-token-demo-case/pom.xml index 0046d20e..87b0c193 100644 --- a/sa-token-demo/sa-token-demo-case/pom.xml +++ b/sa-token-demo/sa-token-demo-case/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml b/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml index d21638bd..4c7cad6f 100644 --- a/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml +++ b/sa-token-demo/sa-token-demo-dubbo-consumer/pom.xml @@ -9,7 +9,8 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml b/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml index 22169f5d..23acfb59 100644 --- a/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml +++ b/sa-token-demo/sa-token-demo-dubbo-provider/pom.xml @@ -9,7 +9,8 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-jwt/pom.xml b/sa-token-demo/sa-token-demo-jwt/pom.xml index 27d49a84..2c4ce042 100644 --- a/sa-token-demo/sa-token-demo-jwt/pom.xml +++ b/sa-token-demo/sa-token-demo-jwt/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-oauth2-client/pom.xml b/sa-token-demo/sa-token-demo-oauth2-client/pom.xml index 7dfb0967..98437ef3 100644 --- a/sa-token-demo/sa-token-demo-oauth2-client/pom.xml +++ b/sa-token-demo/sa-token-demo-oauth2-client/pom.xml @@ -9,7 +9,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-oauth2-server/pom.xml b/sa-token-demo/sa-token-demo-oauth2-server/pom.xml index 1bee1ba9..e8b3f20d 100644 --- a/sa-token-demo/sa-token-demo-oauth2-server/pom.xml +++ b/sa-token-demo/sa-token-demo-oauth2-server/pom.xml @@ -9,7 +9,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-quick-login/pom.xml b/sa-token-demo/sa-token-demo-quick-login/pom.xml index ef783339..1c6d9b13 100644 --- a/sa-token-demo/sa-token-demo-quick-login/pom.xml +++ b/sa-token-demo/sa-token-demo-quick-login/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-solon/pom.xml b/sa-token-demo/sa-token-demo-solon/pom.xml index d41a0cef..508d085f 100644 --- a/sa-token-demo/sa-token-demo-solon/pom.xml +++ b/sa-token-demo/sa-token-demo-solon/pom.xml @@ -11,6 +11,8 @@ 1.33.0 1.10.13 + UTF-8 + UTF-8 diff --git a/sa-token-demo/sa-token-demo-springboot-redis/pom.xml b/sa-token-demo/sa-token-demo-springboot-redis/pom.xml index c4650656..f21e6453 100644 --- a/sa-token-demo/sa-token-demo-springboot-redis/pom.xml +++ b/sa-token-demo/sa-token-demo-springboot-redis/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml index cb63067a..3a41ae12 100644 --- a/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml @@ -17,13 +17,13 @@ sa-token: # token风格 token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true spring: # redis配置 redis: # Redis数据库索引(默认为0) - database: 0 + database: 1 # Redis服务器地址 host: 127.0.0.1 # Redis服务器连接端口 diff --git a/sa-token-demo/sa-token-demo-springboot/pom.xml b/sa-token-demo/sa-token-demo-springboot/pom.xml index 23690db6..d4646392 100644 --- a/sa-token-demo/sa-token-demo-springboot/pom.xml +++ b/sa-token-demo/sa-token-demo-springboot/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/.gitignore b/sa-token-demo/sa-token-demo-springboot3-redis/.gitignore new file mode 100644 index 00000000..99a6e767 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.idea/ + +.factorypath \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/pom.xml b/sa-token-demo/sa-token-demo-springboot3-redis/pom.xml new file mode 100644 index 00000000..11117170 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/pom.xml @@ -0,0 +1,71 @@ + + 4.0.0 + cn.dev33 + sa-token-demo-springboot3-redis + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 3.0.1 + + + + + + 1.33.0 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + + + cn.dev33 + sa-token-spring-boot3-starter + ${sa-token.version} + + + + + + + + cn.dev33 + sa-token-dao-redis-jackson + ${sa-token.version} + + + + + org.apache.commons + commons-pool2 + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/SaTokenSpringBoot3Application.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/SaTokenSpringBoot3Application.java new file mode 100644 index 00000000..6562ba2d --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/SaTokenSpringBoot3Application.java @@ -0,0 +1,21 @@ +package com.pj; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import cn.dev33.satoken.SaManager; + +/** + * Sa-Token 整合 SpringBoot3 示例,整合redis + * @author kong + * + */ +@SpringBootApplication +public class SaTokenSpringBoot3Application { + + public static void main(String[] args) { + SpringApplication.run(SaTokenSpringBoot3Application.class, args); + System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/GlobalException.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/GlobalException.java new file mode 100644 index 00000000..7fb1c563 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/GlobalException.java @@ -0,0 +1,56 @@ +package com.pj.current; + +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.exception.DisableServiceException; +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.exception.NotPermissionException; +import cn.dev33.satoken.exception.NotRoleException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * 全局异常处理 + */ +@RestControllerAdvice +public class GlobalException { + + // 全局异常拦截(拦截项目中的所有异常) + @ExceptionHandler + public AjaxJson handlerException(Exception e, HttpServletRequest request, HttpServletResponse response) + throws Exception { + + // 打印堆栈,以供调试 + System.out.println("全局异常---------------"); + e.printStackTrace(); + + // 不同异常返回不同状态码 + AjaxJson aj = null; + if (e instanceof NotLoginException) { // 如果是未登录异常 + NotLoginException ee = (NotLoginException) e; + aj = AjaxJson.getNotLogin().setMsg(ee.getMessage()); + } + else if(e instanceof NotRoleException) { // 如果是角色异常 + NotRoleException ee = (NotRoleException) e; + aj = AjaxJson.getNotJur("无此角色:" + ee.getRole()); + } + else if(e instanceof NotPermissionException) { // 如果是权限异常 + NotPermissionException ee = (NotPermissionException) e; + aj = AjaxJson.getNotJur("无此权限:" + ee.getPermission()); + } + else if(e instanceof DisableServiceException) { // 如果是被封禁异常 + DisableServiceException ee = (DisableServiceException) e; + aj = AjaxJson.getNotJur("当前账号 " + ee.getService() + " 服务已被封禁 (level=" + ee.getLevel() + "):" + ee.getDisableTime() + "秒后解封"); + } + else { // 普通异常, 输出:500 + 异常信息 + aj = AjaxJson.getError(e.getMessage()); + } + + // 返回给前端 + return aj; + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/NotFoundHandle.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/NotFoundHandle.java new file mode 100644 index 00000000..21ea1d72 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/current/NotFoundHandle.java @@ -0,0 +1,26 @@ +package com.pj.current; + +import java.io.IOException; + +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.dev33.satoken.util.SaResult; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * 处理 404 + * @author kong + */ +@RestController +public class NotFoundHandle implements ErrorController { + + @RequestMapping("/error") + public Object error(HttpServletRequest request, HttpServletResponse response) throws IOException { + response.setStatus(200); + return SaResult.get(404, "not found", null); + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/SaTokenConfigure.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/SaTokenConfigure.java new file mode 100644 index 00000000..07736e4e --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/SaTokenConfigure.java @@ -0,0 +1,71 @@ +package com.pj.satoken; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.filter.SaServletFilter; +import cn.dev33.satoken.interceptor.SaInterceptor; +import cn.dev33.satoken.util.SaResult; + + +/** + * [Sa-Token 权限认证] 配置类 + * @author kong + * + */ +@Configuration +public class SaTokenConfigure implements WebMvcConfigurer { + + /** + * 注册 Sa-Token 拦截器打开注解鉴权功能 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + // 注册 Sa-Token 拦截器打开注解鉴权功能 + registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**"); + } + + /** + * 注册 [Sa-Token 全局过滤器] + */ + @Bean + public SaServletFilter getSaServletFilter() { + return new SaServletFilter() + + // 指定 [拦截路由] 与 [放行路由] + .addInclude("/**")// .addExclude("/favicon.ico") + + // 认证函数: 每次请求执行 + .setAuth(obj -> { + // System.out.println("---------- sa全局认证 " + SaHolder.getRequest().getRequestPath()); + + }) + + // 异常处理函数:每次认证函数发生异常时执行此函数 + .setError(e -> { + System.out.println("---------- sa全局异常 "); + e.printStackTrace(); + return SaResult.error(e.getMessage()); + }) + + // 前置函数:在每次认证函数之前执行 + .setBeforeAuth(r -> { + // ---------- 设置一些安全响应头 ---------- + SaHolder.getResponse() + // 服务器名称 + .setServer("sa-server") + // 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以 + .setHeader("X-Frame-Options", "SAMEORIGIN") + // 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面 + .setHeader("X-XSS-Protection", "1; mode=block") + // 禁用浏览器内容嗅探 + .setHeader("X-Content-Type-Options", "nosniff") + ; + }) + ; + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/StpInterfaceImpl.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/StpInterfaceImpl.java new file mode 100644 index 00000000..b6cc79f7 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/satoken/StpInterfaceImpl.java @@ -0,0 +1,44 @@ +package com.pj.satoken; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Component; + +import cn.dev33.satoken.stp.StpInterface; + +/** + * 自定义权限验证接口扩展 + */ +@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展 +public class StpInterfaceImpl implements StpInterface { + + /** + * 返回一个账号所拥有的权限码集合 + */ + @Override + public List getPermissionList(Object loginId, String loginType) { + // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限 + List list = new ArrayList(); + list.add("101"); + list.add("user-add"); + list.add("user-delete"); + list.add("user-update"); + list.add("user-get"); + list.add("article-get"); + return list; + } + + /** + * 返回一个账号所拥有的角色标识集合 + */ + @Override + public List getRoleList(Object loginId, String loginType) { + // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色 + List list = new ArrayList(); + list.add("admin"); + list.add("super-admin"); + return list; + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/AtController.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/AtController.java new file mode 100644 index 00000000..dc7c6f95 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/AtController.java @@ -0,0 +1,80 @@ +package com.pj.test; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +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.annotation.SaMode; +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; + +/** + * 注解鉴权测试 + * @author kong + * + */ +@RestController +@RequestMapping("/at/") +public class AtController { + + // 登录认证,登录之后才可以进入方法 ---- http://localhost:8081/at/checkLogin + @SaCheckLogin + @RequestMapping("checkLogin") + public SaResult checkLogin() { + return SaResult.ok(); + } + + // 权限认证,具备user-add权限才可以进入方法 ---- http://localhost:8081/at/checkPermission + @SaCheckPermission("user-add") + @RequestMapping("checkPermission") + public SaResult checkPermission() { + return SaResult.ok(); + } + + // 权限认证,同时具备所有权限才可以进入 ---- http://localhost:8081/at/checkPermissionAnd + @SaCheckPermission({"user-add", "user-delete", "user-update"}) + @RequestMapping("checkPermissionAnd") + public SaResult checkPermissionAnd() { + return SaResult.ok(); + } + + // 权限认证,只要具备其中一个就可以进入 ---- http://localhost:8081/at/checkPermissionOr + @SaCheckPermission(value = {"user-add", "user-delete", "user-update"}, mode = SaMode.OR) + @RequestMapping("checkPermissionOr") + public SaResult checkPermissionOr() { + return SaResult.ok(); + } + + // 角色认证,只有具备admin角色才可以进入 ---- http://localhost:8081/at/checkRole + @SaCheckRole("admin") + @RequestMapping("checkRole") + public SaResult checkRole() { + return SaResult.ok(); + } + + // 完成二级认证 ---- http://localhost:8081/at/openSafe + @RequestMapping("openSafe") + public SaResult openSafe() { + StpUtil.openSafe(200); // 打开二级认证,有效期为200秒 + return SaResult.ok(); + } + + // 通过二级认证后才可以进入 ---- http://localhost:8081/at/checkSafe + @SaCheckSafe + @RequestMapping("checkSafe") + public SaResult checkSafe() { + return SaResult.ok(); + } + + // 通过Basic认证后才可以进入 ---- http://localhost:8081/at/checkBasic + @SaCheckBasic(account = "sa:123456") + @RequestMapping("checkBasic") + public SaResult checkBasic() { + return SaResult.ok(); + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/LoginController.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/LoginController.java new file mode 100644 index 00000000..ea94cfa7 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/LoginController.java @@ -0,0 +1,48 @@ +package com.pj.test; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; + +/** + * 登录测试 + * @author kong + * + */ +@RestController +@RequestMapping("/acc/") +public class LoginController { + + // 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456 + @RequestMapping("doLogin") + public SaResult doLogin(String name, String pwd) { + // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 + if("zhang".equals(name) && "123456".equals(pwd)) { + StpUtil.login(10001); + return SaResult.ok("登录成功"); + } + return SaResult.error("登录失败"); + } + + // 查询登录状态 ---- http://localhost:8081/acc/isLogin + @RequestMapping("isLogin") + public SaResult isLogin() { + return SaResult.ok("是否登录:" + StpUtil.isLogin()); + } + + // 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo + @RequestMapping("tokenInfo") + public SaResult tokenInfo() { + return SaResult.data(StpUtil.getTokenInfo()); + } + + // 测试注销 ---- http://localhost:8081/acc/logout + @RequestMapping("logout") + public SaResult logout() { + StpUtil.logout(); + return SaResult.ok(); + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/StressTestController.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/StressTestController.java new file mode 100644 index 00000000..a2384567 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/StressTestController.java @@ -0,0 +1,61 @@ +package com.pj.test; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.pj.util.Ttime; + +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; + +/** + * 压力测试 + * @author kong + * + */ +@RestController +@RequestMapping("/s-test/") +public class StressTestController { + + // 测试 浏览器访问: http://localhost:8081/s-test/login + // 测试前,请先将 is-read-cookie 配置为 false + @RequestMapping("login") + public SaResult login() { +// StpUtil.getTokenSession().logout(); +// StpUtil.logoutByLoginId(10001); + + int count = 10; // 循环多少轮 + int loginCount = 10000; // 每轮循环多少次 + + // 循环10次 取平均时间 + List list = new ArrayList<>(); + for (int i = 1; i <= count; i++) { + System.out.println("\n---------------------第" + i + "轮---------------------"); + Ttime t = new Ttime().start(); + // 每次登录的次数 + for (int j = 1; j <= loginCount; j++) { + StpUtil.login("1000" + j, "PC-" + j); + if(j % 1000 == 0) { + System.out.println("已登录:" + j); + } + } + t.end(); + list.add((t.returnMs() + 0.0) / 1000); + System.out.println("第" + i + "轮" + "用时:" + t.toString()); + } +// System.out.println(((SaTokenDaoDefaultImpl)SaTokenManager.getSaTokenDao()).dataMap.size()); + + System.out.println("\n---------------------测试结果---------------------"); + System.out.println(list.size() + "次测试: " + list); + double ss = 0; + for (int i = 0; i < list.size(); i++) { + ss += list.get(i); + } + System.out.println("平均用时: " + ss / list.size()); + return SaResult.ok(); + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/TestController.java new file mode 100644 index 00000000..d0aa2580 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/test/TestController.java @@ -0,0 +1,30 @@ +package com.pj.test; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.dev33.satoken.util.SaResult; + +/** + * 测试专用Controller + * @author kong + * + */ +@RestController +@RequestMapping("/test/") +public class TestController { + + // 测试 浏览器访问: http://localhost:8081/test/test + @RequestMapping("test") + public SaResult test() { + System.out.println("------------进来了"); + return SaResult.ok(); + } + + // 测试 浏览器访问: http://localhost:8081/test/test2 + @RequestMapping("test2") + public SaResult test2() { + return SaResult.ok(); + } + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/AjaxJson.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/AjaxJson.java new file mode 100644 index 00000000..768d0578 --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/AjaxJson.java @@ -0,0 +1,162 @@ +package com.pj.util; + +import java.io.Serializable; +import java.util.List; + + +/** + * ajax请求返回Json格式数据的封装 + */ +public class AjaxJson implements Serializable{ + + private static final long serialVersionUID = 1L; // 序列化版本号 + + public static final int CODE_SUCCESS = 200; // 成功状态码 + public static final int CODE_ERROR = 500; // 错误状态码 + public static final int CODE_WARNING = 501; // 警告状态码 + public static final int CODE_NOT_JUR = 403; // 无权限状态码 + public static final int CODE_NOT_LOGIN = 401; // 未登录状态码 + public static final int CODE_INVALID_REQUEST = 400; // 无效请求状态码 + + public int code; // 状态码 + public String msg; // 描述信息 + public Object data; // 携带对象 + public Long dataCount; // 数据总数,用于分页 + + /** + * 返回code + * @return + */ + public int getCode() { + return this.code; + } + + /** + * 给msg赋值,连缀风格 + */ + public AjaxJson setMsg(String msg) { + this.msg = msg; + return this; + } + public String getMsg() { + return this.msg; + } + + /** + * 给data赋值,连缀风格 + */ + public AjaxJson setData(Object data) { + this.data = data; + return this; + } + + /** + * 将data还原为指定类型并返回 + */ + @SuppressWarnings("unchecked") + public T getData(Class cs) { + return (T) data; + } + + // ============================ 构建 ================================== + + public AjaxJson(int code, String msg, Object data, Long dataCount) { + this.code = code; + this.msg = msg; + this.data = data; + this.dataCount = dataCount; + } + + // 返回成功 + public static AjaxJson getSuccess() { + return new AjaxJson(CODE_SUCCESS, "ok", null, null); + } + public static AjaxJson getSuccess(String msg) { + return new AjaxJson(CODE_SUCCESS, msg, null, null); + } + public static AjaxJson getSuccess(String msg, Object data) { + return new AjaxJson(CODE_SUCCESS, msg, data, null); + } + public static AjaxJson getSuccessData(Object data) { + return new AjaxJson(CODE_SUCCESS, "ok", data, null); + } + public static AjaxJson getSuccessArray(Object... data) { + return new AjaxJson(CODE_SUCCESS, "ok", data, null); + } + + // 返回失败 + public static AjaxJson getError() { + return new AjaxJson(CODE_ERROR, "error", null, null); + } + public static AjaxJson getError(String msg) { + return new AjaxJson(CODE_ERROR, msg, null, null); + } + + // 返回警告 + public static AjaxJson getWarning() { + return new AjaxJson(CODE_ERROR, "warning", null, null); + } + public static AjaxJson getWarning(String msg) { + return new AjaxJson(CODE_WARNING, msg, null, null); + } + + // 返回未登录 + public static AjaxJson getNotLogin() { + return new AjaxJson(CODE_NOT_LOGIN, "未登录,请登录后再次访问", null, null); + } + + // 返回没有权限的 + public static AjaxJson getNotJur(String msg) { + return new AjaxJson(CODE_NOT_JUR, msg, null, null); + } + + // 返回一个自定义状态码的 + public static AjaxJson get(int code, String msg){ + return new AjaxJson(code, msg, null, null); + } + + // 返回分页和数据的 + public static AjaxJson getPageData(Long dataCount, Object data){ + return new AjaxJson(CODE_SUCCESS, "ok", data, dataCount); + } + + // 返回,根据受影响行数的(大于0=ok,小于0=error) + public static AjaxJson getByLine(int line){ + if(line > 0){ + return getSuccess("ok", line); + } + return getError("error").setData(line); + } + + // 返回,根据布尔值来确定最终结果的 (true=ok,false=error) + public static AjaxJson getByBoolean(boolean b){ + return b ? getSuccess("ok") : getError("error"); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @SuppressWarnings("rawtypes") + @Override + public String toString() { + String data_string = null; + if(data == null){ + + } else if(data instanceof List){ + data_string = "List(length=" + ((List)data).size() + ")"; + } else { + data_string = data.toString(); + } + return "{" + + "\"code\": " + this.getCode() + + ", \"msg\": \"" + this.getMsg() + "\"" + + ", \"data\": " + data_string + + ", \"dataCount\": " + dataCount + + "}"; + } + + + + + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/Ttime.java b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/Ttime.java new file mode 100644 index 00000000..cb17dcaa --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/java/com/pj/util/Ttime.java @@ -0,0 +1,63 @@ +package com.pj.util; + + +/** + * 用于测试用时 + * @author kong + * + */ +public class Ttime { + + private long start=0; //开始时间 + private long end=0; //结束时间 + + public static Ttime t = new Ttime(); //static快捷使用 + + /** + * 开始计时 + * @return + */ + public Ttime start() { + start=System.currentTimeMillis(); + return this; + } + + + /** + * 结束计时 + */ + public Ttime end() { + end=System.currentTimeMillis(); + return this; + } + + + /** + * 返回所用毫秒数 + */ + public long returnMs() { + return end-start; + } + + /** + * 格式化输出结果 + */ + public void outTime() { + System.out.println(this.toString()); + } + + /** + * 结束并格式化输出结果 + */ + public void endOutTime() { + this.end().outTime(); + } + + @Override + public String toString() { + return (returnMs() + 0.0) / 1000 + "s"; // 格式化为:0.01s + } + + + +} diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml new file mode 100644 index 00000000..0ea7252c --- /dev/null +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml @@ -0,0 +1,50 @@ +# 端口 +server: + port: 8081 + +# sa-token配置 +sa-token: + # token名称 (同时也是cookie名称) + token-name: satoken + # token有效期,单位s 默认30天, -1代表永不过期 + timeout: 2592000 + # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 + activity-timeout: -1 + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: true + # token风格 + token-style: uuid + # 是否输出操作日志 + is-log: true + +spring: + data: + # redis配置 + redis: + # Redis数据库索引(默认为0) + database: 1 + # Redis服务器地址 + host: 127.0.0.1 + # Redis服务器连接端口 + port: 6379 + # Redis服务器连接密码(默认为空) + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池最大连接数 + max-active: 200 + # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + # 连接池中的最大空闲连接 + max-idle: 10 + # 连接池中的最小空闲连接 + min-idle: 0 + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-sso-server/pom.xml b/sa-token-demo/sa-token-demo-sso-server/pom.xml index 66aca870..75c55347 100644 --- a/sa-token-demo/sa-token-demo-sso-server/pom.xml +++ b/sa-token-demo/sa-token-demo-sso-server/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-sso1-client/pom.xml b/sa-token-demo/sa-token-demo-sso1-client/pom.xml index 49ffb2ac..51df0c9b 100644 --- a/sa-token-demo/sa-token-demo-sso1-client/pom.xml +++ b/sa-token-demo/sa-token-demo-sso1-client/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-sso2-client/pom.xml b/sa-token-demo/sa-token-demo-sso2-client/pom.xml index 494a4bcf..9e74388c 100644 --- a/sa-token-demo/sa-token-demo-sso2-client/pom.xml +++ b/sa-token-demo/sa-token-demo-sso2-client/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-sso3-client-nosdk/pom.xml b/sa-token-demo/sa-token-demo-sso3-client-nosdk/pom.xml index ef053044..c7b4b311 100644 --- a/sa-token-demo/sa-token-demo-sso3-client-nosdk/pom.xml +++ b/sa-token-demo/sa-token-demo-sso3-client-nosdk/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-sso3-client/pom.xml b/sa-token-demo/sa-token-demo-sso3-client/pom.xml index 15ef734c..ccad4404 100644 --- a/sa-token-demo/sa-token-demo-sso3-client/pom.xml +++ b/sa-token-demo/sa-token-demo-sso3-client/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-test/pom.xml b/sa-token-demo/sa-token-demo-test/pom.xml index 3df84ad1..41ae25d0 100644 --- a/sa-token-demo/sa-token-demo-test/pom.xml +++ b/sa-token-demo/sa-token-demo-test/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-thymeleaf/pom.xml b/sa-token-demo/sa-token-demo-thymeleaf/pom.xml index 5b74f392..32743ba8 100644 --- a/sa-token-demo/sa-token-demo-thymeleaf/pom.xml +++ b/sa-token-demo/sa-token-demo-thymeleaf/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/.gitignore b/sa-token-demo/sa-token-demo-webflux-springboot3/.gitignore new file mode 100644 index 00000000..99a6e767 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.idea/ + +.factorypath \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/pom.xml b/sa-token-demo/sa-token-demo-webflux-springboot3/pom.xml new file mode 100644 index 00000000..8278a15c --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/pom.xml @@ -0,0 +1,72 @@ + + 4.0.0 + cn.dev33 + sa-token-demo-webflux-springboot3 + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 3.0.1 + + + + + + 1.33.0 + + + + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-aop + + + + + cn.dev33 + sa-token-reactor-spring-boot3-starter + ${sa-token.version} + + + + + + + + + + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/SaTokenWebfluxSpringboot3Application.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/SaTokenWebfluxSpringboot3Application.java new file mode 100644 index 00000000..2f1fc607 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/SaTokenWebfluxSpringboot3Application.java @@ -0,0 +1,23 @@ +package com.pj; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import cn.dev33.satoken.SaManager; + +/** + * Sa-Token整合webflux 示例 (springboot3) + * + * @author kong + * @since 2023年1月3日 + * + */ +@SpringBootApplication +public class SaTokenWebfluxSpringboot3Application { + + public static void main(String[] args) { + SpringApplication.run(SaTokenWebfluxSpringboot3Application.class, args); + System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); + } + +} \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/SaTokenConfigure.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/SaTokenConfigure.java new file mode 100644 index 00000000..7dfe7b7c --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/SaTokenConfigure.java @@ -0,0 +1,41 @@ +package com.pj.satoken; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.reactor.filter.SaReactorFilter; + +/** + * [Sa-Token 权限认证] 配置类 + * @author kong + * + */ +@Configuration +public class SaTokenConfigure { + + /** + * 注册 [sa-token全局过滤器] + */ + @Bean + public SaReactorFilter getSaReactorFilter() { + return new SaReactorFilter() + // 指定 [拦截路由] + .addInclude("/**") + // 指定 [放行路由] + .addExclude("/favicon.ico") + // 指定[认证函数]: 每次请求执行 + .setAuth(r -> { + System.out.println("---------- sa全局认证"); + // SaRouter.match("/test/test", () -> StpUtil.checkLogin()); + }) + // 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数 + .setError(e -> { + System.out.println("---------- sa全局异常 "); + return AjaxJson.getError(e.getMessage()); + }) + ; + } + +} diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/StpInterfaceImpl.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/StpInterfaceImpl.java new file mode 100644 index 00000000..b6cc79f7 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/satoken/StpInterfaceImpl.java @@ -0,0 +1,44 @@ +package com.pj.satoken; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Component; + +import cn.dev33.satoken.stp.StpInterface; + +/** + * 自定义权限验证接口扩展 + */ +@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展 +public class StpInterfaceImpl implements StpInterface { + + /** + * 返回一个账号所拥有的权限码集合 + */ + @Override + public List getPermissionList(Object loginId, String loginType) { + // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限 + List list = new ArrayList(); + list.add("101"); + list.add("user-add"); + list.add("user-delete"); + list.add("user-update"); + list.add("user-get"); + list.add("article-get"); + return list; + } + + /** + * 返回一个账号所拥有的角色标识集合 + */ + @Override + public List getRoleList(Object loginId, String loginType) { + // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色 + List list = new ArrayList(); + list.add("admin"); + list.add("super-admin"); + return list; + } + +} diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/DefineRoutes.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/DefineRoutes.java new file mode 100644 index 00000000..729957f5 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/DefineRoutes.java @@ -0,0 +1,35 @@ +package com.pj.test; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.stp.StpUtil; + +@Configuration +public class DefineRoutes { + + /** + * 函数式编程,初始化路由表 + * @return 路由表 + */ + @SuppressWarnings("deprecation") + @Bean + public RouterFunction getRoutes() { + return RouterFunctions.route(RequestPredicates.GET("/fun"), req -> { + // 测试打印 + System.out.println("是否登录:" + StpUtil.isLogin()); + + // 返回结果 + AjaxJson aj = AjaxJson.getSuccessData(StpUtil.getTokenInfo()); + return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).syncBody(aj); + }); + } + +} diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/GlobalException.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/GlobalException.java new file mode 100644 index 00000000..09acf538 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/GlobalException.java @@ -0,0 +1,52 @@ +package com.pj.test; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.exception.DisableServiceException; +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.exception.NotPermissionException; +import cn.dev33.satoken.exception.NotRoleException; + +/** + * 全局异常处理 + */ +@ControllerAdvice // 可指定包前缀,比如:(basePackages = "com.pj.admin") +public class GlobalException { + + // 全局异常拦截(拦截项目中的所有异常) + @ResponseBody + @ExceptionHandler + public AjaxJson handlerException(Exception e) + throws Exception { + + // 打印堆栈,以供调试 + System.out.println("全局异常---------------"); + e.printStackTrace(); + + // 不同异常返回不同状态码 + AjaxJson aj = null; + if (e instanceof NotLoginException) { // 如果是未登录异常 + NotLoginException ee = (NotLoginException) e; + aj = AjaxJson.getNotLogin().setMsg(ee.getMessage()); + } else if(e instanceof NotRoleException) { // 如果是角色异常 + NotRoleException ee = (NotRoleException) e; + aj = AjaxJson.getNotJur("无此角色:" + ee.getRole()); + } else if(e instanceof NotPermissionException) { // 如果是权限异常 + NotPermissionException ee = (NotPermissionException) e; + aj = AjaxJson.getNotJur("无此权限:" + ee.getPermission()); + } else if(e instanceof DisableServiceException) { // 如果是被封禁异常 + DisableServiceException ee = (DisableServiceException) e; + aj = AjaxJson.getNotJur("账号被封禁:" + ee.getDisableTime() + "秒后解封"); + } else { // 普通异常, 输出:500 + 异常信息 + aj = AjaxJson.getError(e.getMessage()); + } + + // 返回给前端 + return aj; + } + +} diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/TestController.java new file mode 100644 index 00000000..d678cb08 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/test/TestController.java @@ -0,0 +1,80 @@ +package com.pj.test; + +import java.time.Duration; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.reactor.context.SaReactorHolder; +import cn.dev33.satoken.stp.StpUtil; +import reactor.core.publisher.Mono; + +/** + * 测试专用Controller + * @author kong + * + */ +@RestController +@RequestMapping("/test/") +public class TestController { + + // 测试登录接口 [同步模式], 浏览器访问: http://localhost:8081/test/login + @RequestMapping("login") + public AjaxJson login(@RequestParam(defaultValue="10001") String id) { + StpUtil.login(id); + return AjaxJson.getSuccess("登录成功"); + } + + // API测试 [同步模式], 浏览器访问: http://localhost:8081/test/isLogin + @RequestMapping("isLogin") + public AjaxJson isLogin() { + System.out.println("当前会话是否登录:" + StpUtil.isLogin()); + return AjaxJson.getSuccessData(StpUtil.getTokenInfo()); + } + + // API测试 [异步模式], 浏览器访问: http://localhost:8081/test/isLogin2 + @RequestMapping("isLogin2") + public Mono isLogin2() { + System.out.println("当前会话是否登录:" + StpUtil.isLogin()); + AjaxJson aj = AjaxJson.getSuccessData(StpUtil.getTokenInfo()); + return Mono.just(aj); + } + + // API测试 [异步模式, 同一线程], 浏览器访问: http://localhost:8081/test/isLogin3 + @RequestMapping("isLogin3") + public Mono isLogin3() { + System.out.println("当前会话是否登录:" + StpUtil.isLogin()); + // 异步方式 + return SaReactorHolder.getContext().map(e -> { + System.out.println("当前会话是否登录2:" + StpUtil.isLogin()); + return AjaxJson.getSuccessData(StpUtil.getTokenInfo()); + }); + } + + // API测试 [异步模式, 不同线程], 浏览器访问: http://localhost:8081/test/isLogin4 + @RequestMapping("isLogin4") + public Mono isLogin4() { + System.out.println("当前会话是否登录:" + StpUtil.isLogin()); + System.out.println("线程id-----" + Thread.currentThread().getId()); + return Mono.delay(Duration.ofSeconds(1)).flatMap(r->{ + return SaReactorHolder.getContext().map(rr->{ + System.out.println("线程id---内--" + Thread.currentThread().getId()); + System.out.println("当前会话是否登录2:" + StpUtil.isLogin()); + return AjaxJson.getSuccessData(StpUtil.getTokenInfo()); + }); + }); + } + + // 测试 浏览器访问: http://localhost:8081/test/test + @RequestMapping("test") + public AjaxJson test() { + System.out.println("线程id-----------Controller--" + Thread.currentThread().getId() + "\t\t"); + System.out.println("当前会话是否登录:" + StpUtil.isLogin()); + return AjaxJson.getSuccessData(StpUtil.getTokenInfo()); + } + + +} diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/util/AjaxJson.java b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/util/AjaxJson.java new file mode 100644 index 00000000..3f481a59 --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/java/com/pj/util/AjaxJson.java @@ -0,0 +1,154 @@ +package com.pj.util; + +import java.io.Serializable; + +import com.fasterxml.jackson.databind.ObjectMapper; + + +/** + * ajax请求返回Json格式数据的封装 + */ +public class AjaxJson implements Serializable{ + + private static final long serialVersionUID = 1L; // 序列化版本号 + + public static final int CODE_SUCCESS = 200; // 成功状态码 + public static final int CODE_ERROR = 500; // 错误状态码 + public static final int CODE_WARNING = 501; // 警告状态码 + public static final int CODE_NOT_JUR = 403; // 无权限状态码 + public static final int CODE_NOT_LOGIN = 401; // 未登录状态码 + public static final int CODE_INVALID_REQUEST = 400; // 无效请求状态码 + + public int code; // 状态码 + public String msg; // 描述信息 + public Object data; // 携带对象 + public Long dataCount; // 数据总数,用于分页 + + /** + * 返回code + * @return + */ + public int getCode() { + return this.code; + } + + /** + * 给msg赋值,连缀风格 + */ + public AjaxJson setMsg(String msg) { + this.msg = msg; + return this; + } + public String getMsg() { + return this.msg; + } + + /** + * 给data赋值,连缀风格 + */ + public AjaxJson setData(Object data) { + this.data = data; + return this; + } + + /** + * 将data还原为指定类型并返回 + */ + @SuppressWarnings("unchecked") + public T getData(Class cs) { + return (T) data; + } + + // ============================ 构建 ================================== + + public AjaxJson(int code, String msg, Object data, Long dataCount) { + this.code = code; + this.msg = msg; + this.data = data; + this.dataCount = dataCount; + } + + // 返回成功 + public static AjaxJson getSuccess() { + return new AjaxJson(CODE_SUCCESS, "ok", null, null); + } + public static AjaxJson getSuccess(String msg) { + return new AjaxJson(CODE_SUCCESS, msg, null, null); + } + public static AjaxJson getSuccess(String msg, Object data) { + return new AjaxJson(CODE_SUCCESS, msg, data, null); + } + public static AjaxJson getSuccessData(Object data) { + return new AjaxJson(CODE_SUCCESS, "ok", data, null); + } + public static AjaxJson getSuccessArray(Object... data) { + return new AjaxJson(CODE_SUCCESS, "ok", data, null); + } + + // 返回失败 + public static AjaxJson getError() { + return new AjaxJson(CODE_ERROR, "error", null, null); + } + public static AjaxJson getError(String msg) { + return new AjaxJson(CODE_ERROR, msg, null, null); + } + + // 返回警告 + public static AjaxJson getWarning() { + return new AjaxJson(CODE_ERROR, "warning", null, null); + } + public static AjaxJson getWarning(String msg) { + return new AjaxJson(CODE_WARNING, msg, null, null); + } + + // 返回未登录 + public static AjaxJson getNotLogin() { + return new AjaxJson(CODE_NOT_LOGIN, "未登录,请登录后再次访问", null, null); + } + + // 返回没有权限的 + public static AjaxJson getNotJur(String msg) { + return new AjaxJson(CODE_NOT_JUR, msg, null, null); + } + + // 返回一个自定义状态码的 + public static AjaxJson get(int code, String msg){ + return new AjaxJson(code, msg, null, null); + } + + // 返回分页和数据的 + public static AjaxJson getPageData(Long dataCount, Object data){ + return new AjaxJson(CODE_SUCCESS, "ok", data, dataCount); + } + + // 返回,根据受影响行数的(大于0=ok,小于0=error) + public static AjaxJson getByLine(int line){ + if(line > 0){ + return getSuccess("ok", line); + } + return getError("error").setData(line); + } + + // 返回,根据布尔值来确定最终结果的 (true=ok,false=error) + public static AjaxJson getByBoolean(boolean b){ + return b ? getSuccess("ok") : getError("error"); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + // 转JSON格式输出 + try { + return new ObjectMapper().writeValueAsString(this); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + + + +} diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml new file mode 100644 index 00000000..3e644c7f --- /dev/null +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml @@ -0,0 +1,46 @@ +# 端口 +server: + port: 8081 + +# sa-token配置 +sa-token: + # token名称 (同时也是cookie名称) + token-name: satoken + # token有效期,单位s 默认30天, -1代表永不过期 + timeout: 2592000 + # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 + activity-timeout: -1 + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: true + # token风格 + token-style: uuid + # 日志 + is-log: true + +spring: + # redis配置 + redis: + # Redis数据库索引(默认为0) + database: 0 + # Redis服务器地址 + host: 127.0.0.1 + # Redis服务器连接端口 + port: 6379 + # Redis服务器连接密码(默认为空) + password: + # 连接超时时间(毫秒) + timeout: 10000ms + lettuce: + pool: + # 连接池最大连接数 + max-active: 200 + # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + # 连接池中的最大空闲连接 + max-idle: 10 + # 连接池中的最小空闲连接 + min-idle: 0 + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-webflux/pom.xml b/sa-token-demo/sa-token-demo-webflux/pom.xml index de257f7e..ca81cd35 100644 --- a/sa-token-demo/sa-token-demo-webflux/pom.xml +++ b/sa-token-demo/sa-token-demo-webflux/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 @@ -37,7 +37,7 @@ sa-token-reactor-spring-boot-starter ${sa-token.version} - + diff --git a/sa-token-demo/sa-token-demo-websocket/pom.xml b/sa-token-demo/sa-token-demo-websocket/pom.xml index b90c4c9f..42095221 100644 --- a/sa-token-demo/sa-token-demo-websocket/pom.xml +++ b/sa-token-demo/sa-token-demo-websocket/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.12 + 2.5.14 diff --git a/sa-token-dependencies/pom.xml b/sa-token-dependencies/pom.xml index f172bbd8..6eda12cd 100644 --- a/sa-token-dependencies/pom.xml +++ b/sa-token-dependencies/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 cn.dev33 @@ -15,11 +15,13 @@ 1.33.0 - 2.5.12 + 2.5.14 + 3.0.1 3.1.4.RELEASE 2.13.4.1 2.11.2 3.1.0 + 6.0.0 3.0.9.RELEASE 1.12.0 1.4.4 @@ -45,6 +47,13 @@ ${servlet-api.version} + + + jakarta.servlet + jakarta.servlet-api + ${jakarta-servlet-api.version} + + org.springframework.boot @@ -246,16 +255,31 @@ sa-token-servlet ${revision} + + cn.dev33 + sa-token-jakarta-servlet + ${revision} + cn.dev33 sa-token-solon-plugin ${revision} + + cn.dev33 + sa-token-spring-boot-autoconfig + ${revision} + cn.dev33 sa-token-spring-boot-starter ${revision} + + cn.dev33 + sa-token-spring-boot3-starter + ${revision} + diff --git a/sa-token-plugin/sa-token-alone-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-alone-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..0d10a399 --- /dev/null +++ b/sa-token-plugin/sa-token-alone-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.dao.alone.SaAloneRedisInject \ No newline at end of file diff --git a/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..1560a6f6 --- /dev/null +++ b/sa-token-plugin/sa-token-context-dubbo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.context.dubbo.SaTokenSecondContextCreatorForDubbo \ No newline at end of file diff --git a/sa-token-plugin/sa-token-context-grpc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-context-grpc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..cf5cba50 --- /dev/null +++ b/sa-token-plugin/sa-token-context-grpc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +cn.dev33.satoken.context.grpc.interceptor.SaTokenGrpcClientInterceptor +cn.dev33.satoken.context.grpc.interceptor.SaTokenContextGrpcServerInterceptor +cn.dev33.satoken.context.grpc.interceptor.SaTokenGrpcServerInterceptor +cn.dev33.satoken.context.grpc.SaTokenSecondContextCreatorForGrpc \ No newline at end of file diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..55cfbd45 --- /dev/null +++ b/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.dao.SaTokenDaoRedisFastjson \ No newline at end of file diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..c15b81e2 --- /dev/null +++ b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.dao.SaTokenDaoRedisFastjson2 \ No newline at end of file diff --git a/sa-token-plugin/sa-token-dao-redis-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-dao-redis-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..40e2ed0b --- /dev/null +++ b/sa-token-plugin/sa-token-dao-redis-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.dao.SaTokenDaoRedisJackson \ No newline at end of file diff --git a/sa-token-plugin/sa-token-dao-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-dao-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..225469e7 --- /dev/null +++ b/sa-token-plugin/sa-token-dao-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.dao.SaTokenDaoRedis \ No newline at end of file diff --git a/sa-token-plugin/sa-token-quick-login/pom.xml b/sa-token-plugin/sa-token-quick-login/pom.xml index 1e2d94e1..d303d8f4 100644 --- a/sa-token-plugin/sa-token-quick-login/pom.xml +++ b/sa-token-plugin/sa-token-quick-login/pom.xml @@ -21,7 +21,9 @@ cn.dev33 sa-token-spring-boot-starter + true + org.springframework.boot diff --git a/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickInject.java b/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickInject.java index a5dca2f8..b73c9da4 100644 --- a/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickInject.java +++ b/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickInject.java @@ -22,7 +22,7 @@ public class SaQuickInject { * * @param saQuickConfig 配置对象 */ - @Autowired + @Autowired(required = false) public void setSaQuickConfig(SaQuickConfig saQuickConfig) { SaQuickManager.setConfig(saQuickConfig); } diff --git a/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickRegister.java b/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickRegister.java index 83f92840..a5d407c4 100644 --- a/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickRegister.java +++ b/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/SaQuickRegister.java @@ -28,18 +28,18 @@ public class SaQuickRegister { */ @Bean @ConfigurationProperties(prefix = "sa") - public SaQuickConfig getSaQuickConfig() { + SaQuickConfig getSaQuickConfig() { return new SaQuickConfig(); } - + /** - * 注册 [sa-token全局过滤器] + * 注册 Sa-Token 全局过滤器 * - * @return see note + * @return / */ @Bean @Order(SaTokenConsts.ASSEMBLY_ORDER - 1) - public SaServletFilter getSaServletFilter() { + SaServletFilter getSaServletFilterForQuickLogin() { return new SaServletFilter() // 拦截路由 .addInclude("/**") diff --git a/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/web/SaQuickController.java b/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/web/SaQuickController.java index aac4a853..99826d00 100644 --- a/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/web/SaQuickController.java +++ b/sa-token-plugin/sa-token-quick-login/src/main/java/cn/dev33/satoken/quick/web/SaQuickController.java @@ -1,8 +1,7 @@ package cn.dev33.satoken.quick.web; -import javax.servlet.http.HttpServletRequest; - import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -27,8 +26,8 @@ public class SaQuickController { * @return see note */ @GetMapping("/saLogin") - public String saLogin(HttpServletRequest request) { - request.setAttribute("cfg", SaQuickManager.getConfig()); + public String saLogin(Model model) { + model.addAttribute("cfg", SaQuickManager.getConfig()); return "sa-login.html"; } diff --git a/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring.factories b/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring.factories index 6c905371..6e313347 100644 --- a/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring.factories +++ b/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring.factories @@ -1 +1,2 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.quick.SaQuickInject \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +cn.dev33.satoken.quick.SaQuickInject \ No newline at end of file diff --git a/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..517a45c5 --- /dev/null +++ b/sa-token-plugin/sa-token-quick-login/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.quick.SaQuickInject \ No newline at end of file diff --git a/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java b/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java index b377c393..415d8b59 100644 --- a/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java +++ b/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java @@ -70,7 +70,6 @@ public class SaCheckAspect { SaStrategy.me.checkMethodAnnotation.accept(method); } - try { // 执行原有逻辑 Object obj = joinPoint.proceed(); diff --git a/sa-token-plugin/sa-token-spring-aop/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-spring-aop/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..9579b4e2 --- /dev/null +++ b/sa-token-plugin/sa-token-spring-aop/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.aop.SaCheckAspect \ No newline at end of file diff --git a/sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..e7b03e0c --- /dev/null +++ b/sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.temp.jwt.SaTempForJwt \ No newline at end of file diff --git a/sa-token-starter/pom.xml b/sa-token-starter/pom.xml index dd42372f..3db85c8d 100644 --- a/sa-token-starter/pom.xml +++ b/sa-token-starter/pom.xml @@ -19,8 +19,12 @@ sa-token-servlet + sa-token-jakarta-servlet + sa-token-spring-boot-autoconfig sa-token-spring-boot-starter + sa-token-spring-boot3-starter sa-token-reactor-spring-boot-starter + sa-token-reactor-spring-boot3-starter sa-token-solon-plugin sa-token-jboot-plugin sa-token-jfinal-plugin diff --git a/sa-token-starter/sa-token-jakarta-servlet/.gitignore b/sa-token-starter/sa-token-jakarta-servlet/.gitignore new file mode 100644 index 00000000..f56feec7 --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.factorypath + +.idea/ \ No newline at end of file diff --git a/sa-token-starter/sa-token-jakarta-servlet/pom.xml b/sa-token-starter/sa-token-jakarta-servlet/pom.xml new file mode 100644 index 00000000..8950b889 --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + cn.dev33 + sa-token-starter + ${revision} + ../pom.xml + + jar + + sa-token-jakarta-servlet + sa-token-jakarta-servlet + sa-token authentication by Jakarta Servlet API + + + + + cn.dev33 + sa-token-core + + + + + jakarta.servlet + jakarta.servlet-api + + + + + + diff --git a/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/error/SaServletErrorCode.java b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/error/SaServletErrorCode.java new file mode 100644 index 00000000..5298f39a --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/error/SaServletErrorCode.java @@ -0,0 +1,17 @@ +package cn.dev33.satoken.servlet.error; + +/** + * 定义 sa-token-servlet 所有异常细分状态码 + * + * @author kong + * @since: 2022-10-30 + */ +public interface SaServletErrorCode { + + /** 转发失败 */ + public static final int CODE_20001 = 20001; + + /** 重定向失败 */ + public static final int CODE_20002 = 20002; + +} diff --git a/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java new file mode 100644 index 00000000..77d2e102 --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java @@ -0,0 +1,117 @@ +package cn.dev33.satoken.servlet.model; + +import java.io.IOException; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.servlet.error.SaServletErrorCode; +import cn.dev33.satoken.util.SaFoxUtil; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Request for Jakarta Servlet + * @author kong + * + */ +public class SaRequestForServlet implements SaRequest { + + /** + * 底层Request对象 + */ + protected HttpServletRequest request; + + /** + * 实例化 + * @param request request对象 + */ + public SaRequestForServlet(HttpServletRequest request) { + this.request = request; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return request; + } + + /** + * 在 [请求体] 里获取一个值 + */ + @Override + public String getParam(String name) { + return request.getParameter(name); + } + + /** + * 在 [请求头] 里获取一个值 + */ + @Override + public String getHeader(String name) { + return request.getHeader(name); + } + + /** + * 在 [Cookie作用域] 里获取一个值 + */ + @Override + public String getCookieValue(String name) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie != null && name.equals(cookie.getName())) { + return cookie.getValue(); + } + } + } + return null; + } + + /** + * 返回当前请求path (不包括上下文名称) + */ + @Override + public String getRequestPath() { + return request.getServletPath(); + } + + /** + * 返回当前请求的url,例:http://xxx.com/test + * @return see note + */ + public String getUrl() { + String currDomain = SaManager.getConfig().getCurrDomain(); + if(SaFoxUtil.isEmpty(currDomain) == false) { + return currDomain + this.getRequestPath(); + } + return request.getRequestURL().toString(); + } + + /** + * 返回当前请求的类型 + */ + @Override + public String getMethod() { + return request.getMethod(); + } + + /** + * 转发请求 + */ + @Override + public Object forward(String path) { + try { + HttpServletResponse response = (HttpServletResponse)SaManager.getSaTokenContextOrSecond().getResponse().getSource(); + request.getRequestDispatcher(path).forward(request, response); + return null; + } catch (ServletException | IOException e) { + throw new SaTokenException(e).setCode(SaServletErrorCode.CODE_20001); + } + } + +} diff --git a/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java new file mode 100644 index 00000000..47c3def0 --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java @@ -0,0 +1,79 @@ +package cn.dev33.satoken.servlet.model; + +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.servlet.error.SaServletErrorCode; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Response for Jakarta Servlet + * @author kong + * + */ +public class SaResponseForServlet implements SaResponse { + + /** + * 底层Request对象 + */ + protected HttpServletResponse response; + + /** + * 实例化 + * @param response response对象 + */ + public SaResponseForServlet(HttpServletResponse response) { + this.response = response; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return response; + } + + /** + * 设置响应状态码 + */ + @Override + public SaResponse setStatus(int sc) { + response.setStatus(sc); + return this; + } + + /** + * 在响应头里写入一个值 + */ + @Override + public SaResponse setHeader(String name, String value) { + response.setHeader(name, value); + return this; + } + + /** + * 在响应头里添加一个值 + * @param name 名字 + * @param value 值 + * @return 对象自身 + */ + public SaResponse addHeader(String name, String value) { + response.addHeader(name, value); + return this; + } + + /** + * 重定向 + */ + @Override + public Object redirect(String url) { + try { + response.sendRedirect(url); + } catch (Exception e) { + throw new SaTokenException(e).setCode(SaServletErrorCode.CODE_20002); + } + return null; + } + + +} diff --git a/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java new file mode 100644 index 00000000..e529c0b0 --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java @@ -0,0 +1,60 @@ +package cn.dev33.satoken.servlet.model; + +import cn.dev33.satoken.context.model.SaStorage; +import jakarta.servlet.http.HttpServletRequest; + +/** + * Storage for Jakarta Servlet + * @author kong + * + */ +public class SaStorageForServlet implements SaStorage { + + /** + * 底层Request对象 + */ + protected HttpServletRequest request; + + /** + * 实例化 + * @param request request对象 + */ + public SaStorageForServlet(HttpServletRequest request) { + this.request = request; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return request; + } + + /** + * 在 [Request作用域] 里写入一个值 + */ + @Override + public SaStorageForServlet set(String key, Object value) { + request.setAttribute(key, value); + return this; + } + + /** + * 在 [Request作用域] 里获取一个值 + */ + @Override + public Object get(String key) { + return request.getAttribute(key); + } + + /** + * 在 [Request作用域] 里删除一个值 + */ + @Override + public SaStorageForServlet delete(String key) { + request.removeAttribute(key); + return this; + } + +} diff --git a/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/package-info.java b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/package-info.java new file mode 100644 index 00000000..306aeb69 --- /dev/null +++ b/sa-token-starter/sa-token-jakarta-servlet/src/main/java/cn/dev33/satoken/servlet/package-info.java @@ -0,0 +1,4 @@ +/** + * Sa-Token对接ServletAPI容器所需要的实现类接口包 + */ +package cn.dev33.satoken.servlet; \ No newline at end of file diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml b/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml index 841e23e1..72101e93 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/pom.xml @@ -17,12 +17,6 @@ springboot reactor integrate sa-token - - - cn.dev33 - sa-token-core - - org.springframework.boot @@ -34,7 +28,6 @@ org.springframework spring-web - 6.0.0 true @@ -59,20 +52,18 @@ true - + - cn.dev33 - sa-token-oauth2 - true - - - + cn.dev33 + sa-token-core + + + - cn.dev33 - sa-token-sso - true - - + cn.dev33 + sa-token-spring-boot-autoconfig + + + + org.springframework.boot + spring-boot-starter + true + + + + + org.springframework + spring-web + + true + + + + + io.projectreactor + reactor-core + true + + + + + com.fasterxml.jackson.core + jackson-databind + true + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + cn.dev33 + sa-token-core + + + + + cn.dev33 + sa-token-spring-boot-autoconfig + + + + + + + + + + + org.springframework.boot + spring-boot-starter + ${springboot3.version} + + + + org.springframework + spring-web + 6.0.0 + + + + io.projectreactor + reactor-core + 3.5.1 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.1 + + + + + org.springframework.boot + spring-boot-configuration-processor + ${springboot3.version} + + + + + + diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorHolder.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorHolder.java new file mode 100644 index 00000000..abd1e0eb --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorHolder.java @@ -0,0 +1,49 @@ +package cn.dev33.satoken.reactor.context; + +import org.springframework.web.server.ServerWebExchange; + +import reactor.core.publisher.Mono; + +/** + * Reactor上下文操作 [异步] + * @author kong + * + */ +public class SaReactorHolder { + + /** + * key + */ + public static final Class CONTEXT_KEY = ServerWebExchange.class; + + /** + * chain_key + */ + public static final String CHAIN_KEY = "WEB_FILTER_CHAIN_KEY"; + + /** + * 获取上下文对象 + * @return see note + */ + public static Mono getContext() { + // 从全局 Mono 获取 + return Mono.deferContextual(Mono::just).map(ctx -> ctx.get(CONTEXT_KEY)); + } + + /** + * 获取上下文对象, 并设置到同步上下文中 + * @return see note + */ + public static Mono getContextAndSetSync() { + // 从全局 Mono 获取 + return Mono.deferContextual(Mono::just).map(ctx -> { + // 设置到sync中 + SaReactorSyncHolder.setContext(ctx.get(CONTEXT_KEY)); + return ctx.get(CONTEXT_KEY); + }).doFinally(r->{ + // 从sync中清除 + SaReactorSyncHolder.clearContext(); + }); + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorSyncHolder.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorSyncHolder.java new file mode 100644 index 00000000..1c418946 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/context/SaReactorSyncHolder.java @@ -0,0 +1,63 @@ +package cn.dev33.satoken.reactor.context; + +import org.springframework.web.server.ServerWebExchange; + +import cn.dev33.satoken.context.SaTokenContextForThreadLocalStorage; +import cn.dev33.satoken.context.SaTokenContextForThreadLocalStorage.Box; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.context.model.SaStorage; +import cn.dev33.satoken.fun.SaFunction; +import cn.dev33.satoken.reactor.model.SaRequestForReactor; +import cn.dev33.satoken.reactor.model.SaResponseForReactor; +import cn.dev33.satoken.reactor.model.SaStorageForReactor; + +/** + * Reactor上下文操作 [同步] + * @author kong + * + */ +public class SaReactorSyncHolder { + + /** + * 写入上下文对象 + * @param exchange see note + */ + public static void setContext(ServerWebExchange exchange) { + SaRequest request = new SaRequestForReactor(exchange.getRequest()); + SaResponse response = new SaResponseForReactor(exchange.getResponse()); + SaStorage storage = new SaStorageForReactor(exchange); + SaTokenContextForThreadLocalStorage.setBox(request, response, storage); + } + + /** + * 获取上下文对象 + * @return see note + */ + public static ServerWebExchange getContext() { + Box box = SaTokenContextForThreadLocalStorage.getBoxNotNull(); + return (ServerWebExchange)box.getStorage().getSource(); + } + + /** + * 清除上下文对象 + */ + public static void clearContext() { + SaTokenContextForThreadLocalStorage.clearBox(); + } + + /** + * 写入上下文对象, 并在执行函数后将其清除 + * @param exchange see note + * @param fun see note + */ + public static void setContext(ServerWebExchange exchange, SaFunction fun) { + try { + setContext(exchange); + fun.run(); + } finally { + clearContext(); + } + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/error/SaReactorSpringBootErrorCode.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/error/SaReactorSpringBootErrorCode.java new file mode 100644 index 00000000..3f631387 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/error/SaReactorSpringBootErrorCode.java @@ -0,0 +1,20 @@ +package cn.dev33.satoken.reactor.error; + +/** + * 定义 sa-token-reactor-spring-boot-starter 所有异常细分状态码 + * + * @author kong + * @since: 2022-10-30 + */ +public interface SaReactorSpringBootErrorCode { + + /** 对象转 JSON 字符串失败 */ + public static final int CODE_20203 = 20203; + + /** JSON 字符串转 Map 失败 */ + public static final int CODE_20204 = 20204; + + /** 默认的 Filter 异常处理函数 */ + public static final int CODE_20205 = 20205; + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java new file mode 100644 index 00000000..e03c8888 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java @@ -0,0 +1,203 @@ +package cn.dev33.satoken.reactor.filter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.core.annotation.Order; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import cn.dev33.satoken.exception.BackResultException; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.exception.StopMatchException; +import cn.dev33.satoken.filter.SaFilterAuthStrategy; +import cn.dev33.satoken.filter.SaFilterErrorStrategy; +import cn.dev33.satoken.reactor.context.SaReactorHolder; +import cn.dev33.satoken.reactor.context.SaReactorSyncHolder; +import cn.dev33.satoken.reactor.error.SaReactorSpringBootErrorCode; +import cn.dev33.satoken.router.SaRouter; +import cn.dev33.satoken.util.SaTokenConsts; +import reactor.core.publisher.Mono; + +/** + * Reactor全局过滤器 + * @author kong + * + */ +@Order(SaTokenConsts.ASSEMBLY_ORDER) +public class SaReactorFilter implements WebFilter { + + // ------------------------ 设置此过滤器 拦截 & 放行 的路由 + + /** + * 拦截路由 + */ + private List includeList = new ArrayList<>(); + + /** + * 放行路由 + */ + private List excludeList = new ArrayList<>(); + + /** + * 添加 [拦截路由] + * @param paths 路由 + * @return 对象自身 + */ + public SaReactorFilter addInclude(String... paths) { + includeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 添加 [放行路由] + * @param paths 路由 + * @return 对象自身 + */ + public SaReactorFilter addExclude(String... paths) { + excludeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 写入 [拦截路由] 集合 + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaReactorFilter setIncludeList(List pathList) { + includeList = pathList; + return this; + } + + /** + * 写入 [放行路由] 集合 + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaReactorFilter setExcludeList(List pathList) { + excludeList = pathList; + return this; + } + + /** + * 获取 [拦截路由] 集合 + * @return see note + */ + public List getIncludeList() { + return includeList; + } + + /** + * 获取 [放行路由] 集合 + * @return see note + */ + public List getExcludeList() { + return excludeList; + } + + + // ------------------------ 钩子函数 + + /** + * 认证函数:每次请求执行 + */ + public SaFilterAuthStrategy auth = r -> {}; + + /** + * 异常处理函数:每次[认证函数]发生异常时执行此函数 + */ + public SaFilterErrorStrategy error = e -> { + throw new SaTokenException(e).setCode(SaReactorSpringBootErrorCode.CODE_20205); + }; + + /** + * 前置函数:在每次[认证函数]之前执行 + */ + public SaFilterAuthStrategy beforeAuth = r -> {}; + + /** + * 写入[认证函数]: 每次请求执行 + * @param auth see note + * @return 对象自身 + */ + public SaReactorFilter setAuth(SaFilterAuthStrategy auth) { + this.auth = auth; + return this; + } + + /** + * 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数 + * @param error see note + * @return 对象自身 + */ + public SaReactorFilter setError(SaFilterErrorStrategy error) { + this.error = error; + return this; + } + + /** + * 写入[前置函数]:在每次[认证函数]之前执行 + * @param beforeAuth see note + * @return 对象自身 + */ + public SaReactorFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) { + this.beforeAuth = beforeAuth; + return this; + } + + + // ------------------------ filter + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + + // 写入WebFilterChain对象 + exchange.getAttributes().put(SaReactorHolder.CHAIN_KEY, chain); + + // ---------- 全局认证处理 + try { + // 写入全局上下文 (同步) + SaReactorSyncHolder.setContext(exchange); + + // 执行全局过滤器 + SaRouter.match(includeList).notMatch(excludeList).check(r -> { + beforeAuth.run(null); + auth.run(null); + }); + + } catch (StopMatchException e) { + + } catch (Throwable e) { + // 1. 获取异常处理策略结果 + String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e)); + + // 2. 写入输出流 + if(exchange.getResponse().getHeaders().getFirst("Content-Type") == null) { + exchange.getResponse().getHeaders().set("Content-Type", "text/plain; charset=utf-8"); + } + return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(result.getBytes()))); + + } finally { + // 清除上下文 + SaReactorSyncHolder.clearContext(); + } + + // ---------- 执行 + + // 写入全局上下文 (同步) + SaReactorSyncHolder.setContext(exchange); + + // 执行 + return chain.filter(exchange).contextWrite(ctx -> { + // 写入全局上下文 (异步) + ctx = ctx.put(SaReactorHolder.CONTEXT_KEY, exchange); + return ctx; + }).doFinally(r -> { + // 清除上下文 + SaReactorSyncHolder.clearContext(); + }); + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java new file mode 100644 index 00000000..da98532e --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java @@ -0,0 +1,113 @@ +package cn.dev33.satoken.reactor.model; + + +import org.springframework.http.HttpCookie; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilterChain; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.reactor.context.SaReactorHolder; +import cn.dev33.satoken.reactor.context.SaReactorSyncHolder; +import cn.dev33.satoken.util.SaFoxUtil; + +/** + * Request for Reactor + * @author kong + * + */ +public class SaRequestForReactor implements SaRequest { + + /** + * 底层Request对象 + */ + protected ServerHttpRequest request; + + /** + * 实例化 + * @param request request对象 + */ + public SaRequestForReactor(ServerHttpRequest request) { + this.request = request; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return request; + } + + /** + * 在 [请求体] 里获取一个值 + */ + @Override + public String getParam(String name) { + return request.getQueryParams().getFirst(name); + } + + /** + * 在 [请求头] 里获取一个值 + */ + @Override + public String getHeader(String name) { + return request.getHeaders().getFirst(name); + } + + /** + * 在 [Cookie作用域] 里获取一个值 + */ + @Override + public String getCookieValue(String name) { + HttpCookie cookie = request.getCookies().getFirst(name); + if(cookie == null) { + return null; + } + return cookie.getValue(); + } + + /** + * 返回当前请求path (不包括上下文名称) + */ + @Override + public String getRequestPath() { + return request.getURI().getPath(); + } + + /** + * 返回当前请求的url,例:http://xxx.com/test + * @return see note + */ + public String getUrl() { + String currDomain = SaManager.getConfig().getCurrDomain(); + if(SaFoxUtil.isEmpty(currDomain) == false) { + return currDomain + this.getRequestPath(); + } + return request.getURI().toString(); + } + + /** + * 返回当前请求的类型 + */ + @Override + public String getMethod() { + return request.getMethod().name(); + } + + /** + * 转发请求 + */ + @Override + public Object forward(String path) { + ServerWebExchange exchange = SaReactorSyncHolder.getContext(); + WebFilterChain chain = exchange.getAttribute(SaReactorHolder.CHAIN_KEY); + + ServerHttpRequest newRequest = request.mutate().path(path).build(); + ServerWebExchange newExchange = exchange.mutate().request(newRequest).build(); + + return chain.filter(newExchange); + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java new file mode 100644 index 00000000..3bd6a28b --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java @@ -0,0 +1,77 @@ +package cn.dev33.satoken.reactor.model; + +import java.net.URI; + +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpResponse; + +import cn.dev33.satoken.context.model.SaResponse; + +/** + * Response for Reactor + * @author kong + * + */ +public class SaResponseForReactor implements SaResponse { + + /** + * 底层Response对象 + */ + protected ServerHttpResponse response; + + /** + * 实例化 + * @param response response对象 + */ + public SaResponseForReactor(ServerHttpResponse response) { + this.response = response; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return response; + } + + /** + * 设置响应状态码 + */ + @Override + public SaResponse setStatus(int sc) { + response.setStatusCode(HttpStatus.valueOf(sc)); + return this; + } + + /** + * 在响应头里写入一个值 + */ + @Override + public SaResponse setHeader(String name, String value) { + response.getHeaders().set(name, value); + return this; + } + + /** + * 在响应头里添加一个值 + * @param name 名字 + * @param value 值 + * @return 对象自身 + */ + public SaResponse addHeader(String name, String value) { + response.getHeaders().add(name, value); + return this; + } + + /** + * 重定向 + */ + @Override + public Object redirect(String url) { + response.setStatusCode(HttpStatus.FOUND); + response.getHeaders().setLocation(URI.create(url)); + return null; + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java new file mode 100644 index 00000000..5cfc080a --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java @@ -0,0 +1,61 @@ +package cn.dev33.satoken.reactor.model; + +import org.springframework.web.server.ServerWebExchange; + +import cn.dev33.satoken.context.model.SaStorage; + +/** + * Storage for Reactor + * @author kong + * + */ +public class SaStorageForReactor implements SaStorage { + + /** + * 底层Request对象 + */ + protected ServerWebExchange exchange; + + /** + * 实例化 + * @param exchange exchange对象 + */ + public SaStorageForReactor(ServerWebExchange exchange) { + this.exchange = exchange; + } + + /** + * 获取底层源对象 + */ + @Override + public Object getSource() { + return exchange; + } + + /** + * 在 [Request作用域] 里写入一个值 + */ + @Override + public SaStorageForReactor set(String key, Object value) { + exchange.getAttributes().put(key, value); + return this; + } + + /** + * 在 [Request作用域] 里获取一个值 + */ + @Override + public Object get(String key) { + return exchange.getAttributes().get(key); + } + + /** + * 在 [Request作用域] 里删除一个值 + */ + @Override + public SaStorageForReactor delete(String key) { + exchange.getAttributes().remove(key); + return this; + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/package-info.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/package-info.java new file mode 100644 index 00000000..bfccfbad --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/package-info.java @@ -0,0 +1,4 @@ +/** + * sa-token集成Reactor响应式编程的各个组件 + */ +package cn.dev33.satoken.reactor; \ No newline at end of file diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextForSpringReactor.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextForSpringReactor.java new file mode 100644 index 00000000..97912591 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextForSpringReactor.java @@ -0,0 +1,22 @@ +package cn.dev33.satoken.reactor.spring; + +import cn.dev33.satoken.context.SaTokenContextForThreadLocal; +import cn.dev33.satoken.spring.SaPathMatcherHolder; + +/** + * Sa-Token 上下文处理器 [ Spring Reactor 版本实现 ] + * + * @author kong + * + */ +public class SaTokenContextForSpringReactor extends SaTokenContextForThreadLocal { + + /** + * 重写路由匹配方法 + */ + @Override + public boolean matchPath(String pattern, String path) { + return SaPathMatcherHolder.getPathMatcher().match(pattern, path); + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextRegister.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextRegister.java new file mode 100644 index 00000000..3f8ab4f9 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/spring/SaTokenContextRegister.java @@ -0,0 +1,25 @@ +package cn.dev33.satoken.reactor.spring; + +import org.springframework.context.annotation.Bean; + +import cn.dev33.satoken.context.SaTokenContext; + +/** + * 注册Sa-Token所需要的Bean + *

Bean 的注册与注入应该分开在两个文件中,否则在某些场景下会造成循环依赖 + * @author kong + * + */ +public class SaTokenContextRegister { + + /** + * 获取容器交互Bean (ThreadLocal版) + * + * @return 容器交互Bean (ThreadLocal版) + */ + @Bean + public SaTokenContext getSaTokenContextForSpringReactor() { + return new SaTokenContextForSpringReactor(); + } + +} diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..32577197 --- /dev/null +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.reactor.spring.SaTokenContextRegister \ No newline at end of file diff --git a/sa-token-starter/sa-token-servlet/pom.xml b/sa-token-starter/sa-token-servlet/pom.xml index e3fb2ca7..df2a68c8 100644 --- a/sa-token-starter/sa-token-servlet/pom.xml +++ b/sa-token-starter/sa-token-servlet/pom.xml @@ -14,7 +14,7 @@ sa-token-servlet sa-token-servlet - sa-token authentication by Sservlet API + sa-token authentication by Servlet API diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java index 7adaabe6..c00126a6 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java @@ -10,8 +10,6 @@ import cn.dev33.satoken.basic.SaBasicUtil; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.context.second.SaTokenSecondContextCreator; import cn.dev33.satoken.dao.SaTokenDao; -import cn.dev33.satoken.id.SaIdTemplate; -import cn.dev33.satoken.id.SaIdUtil; import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenListener; @@ -28,7 +26,6 @@ import cn.dev33.satoken.temp.SaTempInterface; * @author noear * @since 1.4 */ -@SuppressWarnings("deprecation") public class XPluginImp implements Plugin { @Override @@ -90,11 +87,6 @@ public class XPluginImp implements Plugin { SaManager.setSaTemp(bean); }); - // Sa-Token-Id 身份凭证模块 Bean - context.getBeanAsync(SaIdTemplate.class, bean -> { - SaIdUtil.saIdTemplate = bean; - }); - // Sa-Token Same-Token 模块 Bean context.getBeanAsync(SaSameTemplate.class, bean -> { SaManager.setSaSameTemplate(bean); @@ -120,4 +112,5 @@ public class XPluginImp implements Plugin { StpUtil.setStpLogic(bean); }); } + } \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/.gitignore b/sa-token-starter/sa-token-spring-boot-autoconfig/.gitignore new file mode 100644 index 00000000..f56feec7 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.factorypath + +.idea/ \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/pom.xml b/sa-token-starter/sa-token-spring-boot-autoconfig/pom.xml new file mode 100644 index 00000000..4ab74948 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + + cn.dev33 + sa-token-starter + ${revision} + ../pom.xml + + jar + + sa-token-spring-boot-autoconfig + sa-token-spring-boot-autoconfig + sa-token-spring-boot-autoconfig + + + + + + org.springframework.boot + spring-boot-starter + true + + + com.fasterxml.jackson.core + jackson-databind + true + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + cn.dev33 + sa-token-oauth2 + true + + + + + cn.dev33 + sa-token-sso + true + + + + + + diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/package-info.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/package-info.java new file mode 100644 index 00000000..56ef7301 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/package-info.java @@ -0,0 +1,4 @@ +/** + * sa-token集成SpringBoot的各个组件 + */ +package cn.dev33.satoken; \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java similarity index 92% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java index 6011c2ab..cdfdffc5 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaBeanInject.java @@ -13,8 +13,6 @@ import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.context.second.SaTokenSecondContextCreator; import cn.dev33.satoken.dao.SaTokenDao; -import cn.dev33.satoken.id.SaIdTemplate; -import cn.dev33.satoken.id.SaIdUtil; import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenListener; @@ -32,7 +30,6 @@ import cn.dev33.satoken.temp.SaTempInterface; * @author kong * */ -@SuppressWarnings("deprecation") public class SaBeanInject { /** @@ -113,16 +110,6 @@ public class SaBeanInject { SaManager.setSaTemp(saTemp); } - /** - * 注入 Sa-Id-Token 模块 Bean - * - * @param saIdTemplate saIdTemplate对象 - */ - @Autowired(required = false) - public void setSaIdTemplate(SaIdTemplate saIdTemplate) { - SaIdUtil.saIdTemplate = saIdTemplate; - } - /** * 注入 Same-Token 模块 Bean * diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java similarity index 79% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java index 125d76ff..5b7ffb1e 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaBeanRegister.java @@ -4,7 +4,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import cn.dev33.satoken.config.SaTokenConfig; -import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.json.SaJsonTemplate; import cn.dev33.satoken.spring.json.SaJsonTemplateForJackson; @@ -27,16 +26,6 @@ public class SaBeanRegister { return new SaTokenConfig(); } - /** - * 获取上下文Bean (Spring版) - * - * @return 容器交互Bean (Spring版) - */ - @Bean - public SaTokenContext getSaTokenContext() { - return new SaTokenContextForSpring(); - } - /** * 获取 json 转换器 Bean (Jackson版) * diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaPathMatcherHolder.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaPathMatcherHolder.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaPathMatcherHolder.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/SaPathMatcherHolder.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/oauth2/package-info.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/package-info.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/oauth2/package-info.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/package-info.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanInject.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanRegister.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanRegister.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanRegister.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/sso/SaSsoBeanRegister.java diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/package-info.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/sso/package-info.java similarity index 100% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/sso/package-info.java rename to sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/sso/package-info.java diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring.factories b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..d092a911 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +cn.dev33.satoken.spring.SaBeanRegister,\ +cn.dev33.satoken.spring.SaBeanInject,\ +cn.dev33.satoken.spring.sso.SaSsoBeanRegister,\ +cn.dev33.satoken.spring.sso.SaSsoBeanInject,\ +cn.dev33.satoken.spring.oauth2.SaOAuth2BeanRegister,\ +cn.dev33.satoken.spring.oauth2.SaOAuth2BeanInject \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..7ea52e5f --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,6 @@ +cn.dev33.satoken.spring.SaBeanRegister +cn.dev33.satoken.spring.SaBeanInject +cn.dev33.satoken.spring.sso.SaSsoBeanRegister +cn.dev33.satoken.spring.sso.SaSsoBeanInject +cn.dev33.satoken.spring.oauth2.SaOAuth2BeanRegister +cn.dev33.satoken.spring.oauth2.SaOAuth2BeanInject \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot-starter/pom.xml b/sa-token-starter/sa-token-spring-boot-starter/pom.xml index a05bf634..14939051 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/pom.xml +++ b/sa-token-starter/sa-token-spring-boot-starter/pom.xml @@ -17,12 +17,6 @@ springboot integrate sa-token - - - cn.dev33 - sa-token-servlet - - org.springframework.boot @@ -36,19 +30,18 @@ true - + cn.dev33 - sa-token-oauth2 - true + sa-token-servlet - + cn.dev33 - sa-token-sso - true + sa-token-spring-boot-autoconfig + diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java deleted file mode 100644 index afa7fa3b..00000000 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaAnnotationInterceptor.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.dev33.satoken.interceptor; - -import java.lang.reflect.Method; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerInterceptor; - -import cn.dev33.satoken.strategy.SaStrategy; - -/** - * Sa-Token 注解式鉴权 - 拦截器 - *

[ 当前拦截器写法已过期,可能将在以后的版本删除,推荐升级为 SaInterceptor ]

- * - * @author kong - */ -@Deprecated -public class SaAnnotationInterceptor implements HandlerInterceptor { - - /** - * 构建: 注解式鉴权 - 拦截器 - */ - public SaAnnotationInterceptor() { - } - - /** - * 每次请求之前触发的方法 - */ - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { - - // 获取处理 Method - if (handler instanceof HandlerMethod == false) { - return true; - } - Method method = ((HandlerMethod) handler).getMethod(); - - // 进行验证 - SaStrategy.me.checkMethodAnnotation.accept(method); - - // 通过验证 - return true; - } - -} diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java deleted file mode 100644 index 4ce53f11..00000000 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java +++ /dev/null @@ -1,79 +0,0 @@ -package cn.dev33.satoken.interceptor; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.web.servlet.HandlerInterceptor; - -import cn.dev33.satoken.exception.BackResultException; -import cn.dev33.satoken.exception.StopMatchException; -import cn.dev33.satoken.router.SaRouteFunction; -import cn.dev33.satoken.servlet.model.SaRequestForServlet; -import cn.dev33.satoken.servlet.model.SaResponseForServlet; -import cn.dev33.satoken.stp.StpUtil; - -/** - * Sa-Token 拦截式鉴权 - 拦截器 - *

[ 当前拦截器写法已过期,可能将在以后的版本删除,推荐升级为 SaInterceptor ]

- * - * @author kong - */ -@Deprecated -public class SaRouteInterceptor implements HandlerInterceptor { - - /** - * 每次进入拦截器的[执行函数],默认为登录校验 - */ - public SaRouteFunction function = (req, res, handler) -> StpUtil.checkLogin(); - - /** - * 创建一个路由拦截器 - */ - public SaRouteInterceptor() { - } - - /** - * 创建, 并指定[执行函数] - * @param function [执行函数] - */ - public SaRouteInterceptor(SaRouteFunction function) { - this.function = function; - } - - /** - * 静态方法快速构建一个 - * @param function 自定义模式下的执行函数 - * @return sa路由拦截器 - */ - public static SaRouteInterceptor newInstance(SaRouteFunction function) { - return new SaRouteInterceptor(function); - } - - - // ----------------- 验证方法 ----------------- - - /** - * 每次请求之前触发的方法 - */ - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { - - try { - function.run(new SaRequestForServlet(request), new SaResponseForServlet(response), handler); - } catch (StopMatchException e) { - // 停止匹配,进入Controller - } catch (BackResultException e) { - // 停止匹配,向前端输出结果 - if(response.getContentType() == null) { - response.setContentType("text/plain; charset=utf-8"); - } - response.getWriter().print(e.getMessage()); - return false; - } - - // 通过验证 - return true; - } - -} diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java new file mode 100644 index 00000000..38fb19b7 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java @@ -0,0 +1,25 @@ +package cn.dev33.satoken.spring; + +import org.springframework.context.annotation.Bean; + +import cn.dev33.satoken.context.SaTokenContext; + +/** + * 注册Sa-Token所需要的Bean + *

Bean 的注册与注入应该分开在两个文件中,否则在某些场景下会造成循环依赖 + * @author kong + * + */ +public class SaTokenContextRegister { + + /** + * 获取上下文Bean (Spring版) + * + * @return 容器交互Bean (Spring版) + */ + @Bean + public SaTokenContext getSaTokenContextForSpring() { + return new SaTokenContextForSpring(); + } + +} diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/resources/META-INF/spring.factories b/sa-token-starter/sa-token-spring-boot-starter/src/main/resources/META-INF/spring.factories index d092a911..05745ef3 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,7 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -cn.dev33.satoken.spring.SaBeanRegister,\ -cn.dev33.satoken.spring.SaBeanInject,\ -cn.dev33.satoken.spring.sso.SaSsoBeanRegister,\ -cn.dev33.satoken.spring.sso.SaSsoBeanInject,\ -cn.dev33.satoken.spring.oauth2.SaOAuth2BeanRegister,\ -cn.dev33.satoken.spring.oauth2.SaOAuth2BeanInject \ No newline at end of file +cn.dev33.satoken.spring.SaTokenContextRegister \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot3-starter/.gitignore b/sa-token-starter/sa-token-spring-boot3-starter/.gitignore new file mode 100644 index 00000000..f56feec7 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.factorypath + +.idea/ \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot3-starter/pom.xml b/sa-token-starter/sa-token-spring-boot3-starter/pom.xml new file mode 100644 index 00000000..436e9ad1 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + + cn.dev33 + sa-token-starter + ${revision} + ../pom.xml + + jar + + sa-token-spring-boot3-starter + sa-token-spring-boot3-starter + springboot3 integrate sa-token + + + 3.0.1 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + cn.dev33 + sa-token-jakarta-servlet + + + + + cn.dev33 + sa-token-spring-boot-autoconfig + + + + + + + + + + org.springframework.boot + spring-boot-starter + ${springboot3.version} + + + + org.springframework.boot + spring-boot-starter-web + ${springboot3.version} + + + + org.springframework.boot + spring-boot-configuration-processor + ${springboot3.version} + + + + + + + diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java new file mode 100644 index 00000000..3c6b40e6 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java @@ -0,0 +1,191 @@ +package cn.dev33.satoken.filter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.core.annotation.Order; + +import cn.dev33.satoken.error.SaSpringBootErrorCode; +import cn.dev33.satoken.exception.BackResultException; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.exception.StopMatchException; +import cn.dev33.satoken.router.SaRouter; +import cn.dev33.satoken.util.SaTokenConsts; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; + +/** + * Servlet全局过滤器 + * @author kong + * + */ +@Order(SaTokenConsts.ASSEMBLY_ORDER) +public class SaServletFilter implements Filter { + + // ------------------------ 设置此过滤器 拦截 & 放行 的路由 + + /** + * 拦截路由 + */ + private List includeList = new ArrayList<>(); + + /** + * 放行路由 + */ + private List excludeList = new ArrayList<>(); + + /** + * 添加 [拦截路由] + * @param paths 路由 + * @return 对象自身 + */ + public SaServletFilter addInclude(String... paths) { + includeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 添加 [放行路由] + * @param paths 路由 + * @return 对象自身 + */ + public SaServletFilter addExclude(String... paths) { + excludeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 写入 [拦截路由] 集合 + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaServletFilter setIncludeList(List pathList) { + includeList = pathList; + return this; + } + + /** + * 写入 [放行路由] 集合 + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaServletFilter setExcludeList(List pathList) { + excludeList = pathList; + return this; + } + + /** + * 获取 [拦截路由] 集合 + * @return see note + */ + public List getIncludeList() { + return includeList; + } + + /** + * 获取 [放行路由] 集合 + * @return see note + */ + public List getExcludeList() { + return excludeList; + } + + + // ------------------------ 钩子函数 + + /** + * 认证函数:每次请求执行 + */ + public SaFilterAuthStrategy auth = r -> {}; + + /** + * 异常处理函数:每次[认证函数]发生异常时执行此函数 + */ + public SaFilterErrorStrategy error = e -> { + throw new SaTokenException(e).setCode(SaSpringBootErrorCode.CODE_20105); + }; + + /** + * 前置函数:在每次[认证函数]之前执行 + */ + public SaFilterAuthStrategy beforeAuth = r -> {}; + + /** + * 写入[认证函数]: 每次请求执行 + * @param auth see note + * @return 对象自身 + */ + public SaServletFilter setAuth(SaFilterAuthStrategy auth) { + this.auth = auth; + return this; + } + + /** + * 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数 + * @param error see note + * @return 对象自身 + */ + public SaServletFilter setError(SaFilterErrorStrategy error) { + this.error = error; + return this; + } + + /** + * 写入[前置函数]:在每次[认证函数]之前执行 + * @param beforeAuth see note + * @return 对象自身 + */ + public SaServletFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) { + this.beforeAuth = beforeAuth; + return this; + } + + + // ------------------------ doFilter + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + try { + // 执行全局过滤器 + SaRouter.match(includeList).notMatch(excludeList).check(r -> { + beforeAuth.run(null); + auth.run(null); + }); + + } catch (StopMatchException e) { + + } catch (Throwable e) { + // 1. 获取异常处理策略结果 + String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e)); + + // 2. 写入输出流 + if(response.getContentType() == null) { + response.setContentType("text/plain; charset=utf-8"); + } + response.getWriter().print(result); + return; + } + + // 执行 + chain.doFilter(request, response); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void destroy() { + } + + + +} diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java new file mode 100644 index 00000000..e00450ce --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java @@ -0,0 +1,113 @@ +package cn.dev33.satoken.interceptor; + +import java.lang.reflect.Method; + +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import cn.dev33.satoken.annotation.SaIgnore; +import cn.dev33.satoken.exception.BackResultException; +import cn.dev33.satoken.exception.StopMatchException; +import cn.dev33.satoken.fun.SaParamFunction; +import cn.dev33.satoken.strategy.SaStrategy; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Sa-Token 综合拦截器,提供注解鉴权和路由拦截鉴权能力 + * + * @author kong + * @since: 2022-8-21 + */ +public class SaInterceptor implements HandlerInterceptor { + + /** + * 是否打开注解鉴权 + */ + public boolean isAnnotation = true; + + /** + * 认证函数:每次请求执行 + *

参数:路由处理函数指针 + */ + public SaParamFunction auth = handler -> {}; + + /** + * 创建一个 Sa-Token 综合拦截器,默认带有注解鉴权能力 + */ + public SaInterceptor() { + } + + /** + * 创建一个 Sa-Token 综合拦截器,默认带有注解鉴权能力 + * @param auth 认证函数,每次请求执行 + */ + public SaInterceptor(SaParamFunction auth) { + this.auth = auth; + } + + /** + * 设置是否打开注解鉴权 + * @param isAnnotation / + * @return 对象自身 + */ + public SaInterceptor isAnnotation(boolean isAnnotation) { + this.isAnnotation = isAnnotation; + return this; + } + + /** + * 写入[认证函数]: 每次请求执行 + * @param auth / + * @return 对象自身 + */ + public SaInterceptor setAuth(SaParamFunction auth) { + this.auth = auth; + return this; + } + + + // ----------------- 验证方法 ----------------- + + /** + * 每次请求之前触发的方法 + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + + try { + + if(isAnnotation && handler instanceof HandlerMethod) { + + // 获取此请求对应的 Method 处理函数 + Method method = ((HandlerMethod) handler).getMethod(); + + // 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权 + if(SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class)) { + return true; + } + + // 注解校验 + SaStrategy.me.checkMethodAnnotation.accept(method); + } + + // Auth 校验 + auth.run(handler); + + } catch (StopMatchException e) { + // 停止匹配,进入Controller + } catch (BackResultException e) { + // 停止匹配,向前端输出结果 + if(response.getContentType() == null) { + response.setContentType("text/plain; charset=utf-8"); + } + response.getWriter().print(e.getMessage()); + return false; + } + + // 通过验证 + return true; + } + +} diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/package-info.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/package-info.java new file mode 100644 index 00000000..56ef7301 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/package-info.java @@ -0,0 +1,4 @@ +/** + * sa-token集成SpringBoot的各个组件 + */ +package cn.dev33.satoken; \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextForSpringInJakartaServlet.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextForSpringInJakartaServlet.java new file mode 100644 index 00000000..c07b4a6d --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextForSpringInJakartaServlet.java @@ -0,0 +1,59 @@ +package cn.dev33.satoken.spring; + +import cn.dev33.satoken.context.SaTokenContext; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.context.model.SaStorage; +import cn.dev33.satoken.servlet.model.SaRequestForServlet; +import cn.dev33.satoken.servlet.model.SaResponseForServlet; +import cn.dev33.satoken.servlet.model.SaStorageForServlet; + +/** + * Sa-Token 上下文处理器 [ SpringBoot3 Jakarta Servlet 版 ] + * + * @author kong + * + */ +public class SaTokenContextForSpringInJakartaServlet implements SaTokenContext { + + /** + * 获取当前请求的Request对象 + */ + @Override + public SaRequest getRequest() { + return new SaRequestForServlet(SpringMVCUtil.getRequest()); + } + + /** + * 获取当前请求的Response对象 + */ + @Override + public SaResponse getResponse() { + return new SaResponseForServlet(SpringMVCUtil.getResponse()); + } + + /** + * 获取当前请求的 [存储器] 对象 + */ + @Override + public SaStorage getStorage() { + return new SaStorageForServlet(SpringMVCUtil.getRequest()); + } + + /** + * 校验指定路由匹配符是否可以匹配成功指定路径 + */ + @Override + public boolean matchPath(String pattern, String path) { + return SaPathMatcherHolder.getPathMatcher().match(pattern, path); + } + + /** + * 此上下文是否有效 + */ + @Override + public boolean isValid() { + return SpringMVCUtil.isWeb(); + } + +} diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java new file mode 100644 index 00000000..7b43b505 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SaTokenContextRegister.java @@ -0,0 +1,26 @@ +package cn.dev33.satoken.spring; + +import org.springframework.context.annotation.Bean; + +import cn.dev33.satoken.context.SaTokenContext; + +/** + * SaTokenContext 上下文注册 + * + * @author kong + * @since 2023年1月1日 + * + */ +public class SaTokenContextRegister { + + /** + * 获取上下文Bean [ SpringBoot3 Jakarta Servlet 版 ] + * + * @return / + */ + @Bean + public SaTokenContext getSaTokenContextForSpringInJakartaServlet() { + return new SaTokenContextForSpringInJakartaServlet(); + } + +} diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SpringMVCUtil.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SpringMVCUtil.java new file mode 100644 index 00000000..a015a8d2 --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/spring/SpringMVCUtil.java @@ -0,0 +1,53 @@ +package cn.dev33.satoken.spring; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import cn.dev33.satoken.error.SaSpringBootErrorCode; +import cn.dev33.satoken.exception.NotWebContextException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * SpringMVC相关操作 + * @author kong + * + */ +public class SpringMVCUtil { + + private SpringMVCUtil() { + } + + /** + * 获取当前会话的 request + * @return request + */ + public static HttpServletRequest getRequest() { + ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if(servletRequestAttributes == null) { + throw new NotWebContextException("非Web上下文无法获取Request").setCode(SaSpringBootErrorCode.CODE_20101); + } + return servletRequestAttributes.getRequest(); + } + + /** + * 获取当前会话的 response + * @return response + */ + public static HttpServletResponse getResponse() { + ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if(servletRequestAttributes == null) { + throw new NotWebContextException("非Web上下文无法获取Response").setCode(SaSpringBootErrorCode.CODE_20101); + } + return servletRequestAttributes.getResponse(); + } + + /** + * 判断当前是否处于 Web 上下文中 + * @return request + */ + public static boolean isWeb() { + return RequestContextHolder.getRequestAttributes() != null; + } + +} diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-starter/sa-token-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..6a35303e --- /dev/null +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +cn.dev33.satoken.spring.SaTokenContextRegister \ No newline at end of file