From 9b9de79245d99adaf9317b5da2bb6c3ae2efe904 Mon Sep 17 00:00:00 2001 From: noear Date: Fri, 13 Jan 2023 09:11:23 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E8=B0=83=E6=95=B4=20sa-token-demo-solon?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E7=94=A8=20SaTokenInterceptor=20=E6=9B=BF?= =?UTF-8?q?=E4=BB=A3=E4=B9=8B=E5=89=8D=E7=9A=84=20SaTokenPathInterceptor?= =?UTF-8?q?=EF=BC=88=E6=97=A7=E7=9A=84=E6=A0=87=E4=B8=BA=E5=BC=83=E7=94=A8?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/pj/satoken/SaTokenConfigure.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/satoken/SaTokenConfigure.java b/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/satoken/SaTokenConfigure.java index 2d0ba777..cc483108 100644 --- a/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/satoken/SaTokenConfigure.java +++ b/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/satoken/SaTokenConfigure.java @@ -22,9 +22,9 @@ public class SaTokenConfigure { /** * 注册 [sa-token全局过滤器] */ - @Bean - public void tokenPathFilter() { - Solon.app().before(new SaTokenPathInterceptor() + @Bean(index = -100) + public SaTokenInterceptor tokenPathFilter() { + return new SaTokenInterceptor() // 指定 [拦截路由] 与 [放行路由] .addInclude("/**").addExclude("/favicon.ico") @@ -55,7 +55,6 @@ public class SaTokenConfigure { // 禁用浏览器内容嗅探 .setHeader("X-Content-Type-Options", "nosniff") ; - }) - ); + }); } } From 27ea84c5a68a710893a7e19f47d3fcb68dec18bd Mon Sep 17 00:00:00 2001 From: noear Date: Fri, 13 Jan 2023 09:12:56 +0800 Subject: [PATCH 2/3] =?UTF-8?q?sa-token-solon-plugin=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=20solon=20=E4=B8=BA=201.12.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sa-token-dependencies/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sa-token-dependencies/pom.xml b/sa-token-dependencies/pom.xml index 0039ebf5..bf8b6ab2 100644 --- a/sa-token-dependencies/pom.xml +++ b/sa-token-dependencies/pom.xml @@ -23,7 +23,7 @@ 3.1.0 6.0.0 3.0.9.RELEASE - 1.12.0 + 1.12.2 1.4.4 4.9.17 3.14.4 From 7d9c556e2d6eefaa9de55857926101db2ea524c1 Mon Sep 17 00:00:00 2001 From: noear Date: Fri, 13 Jan 2023 09:13:40 +0800 Subject: [PATCH 3/3] =?UTF-8?q?sa-token-solon-plugin=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E6=8B=A6=E6=88=AA=E9=80=82=E9=85=8D=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E6=97=A7=E7=9A=84=E6=A0=87=E4=B8=BA=E5=BC=83?= =?UTF-8?q?=E7=94=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/dev33/satoken/solon/XPluginImp.java | 4 +- .../solon/integration/SaTokenFilter.java | 219 ++++++++++++++++++ .../solon/integration/SaTokenInterceptor.java | 217 +++++++++++++++++ .../solon/integration/SaTokenPathFilter.java | 1 + .../integration/SaTokenPathInterceptor.java | 1 + 5 files changed, 440 insertions(+), 2 deletions(-) create mode 100644 sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenFilter.java create mode 100644 sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenInterceptor.java 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 c00126a6..9d103e41 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 @@ -107,8 +107,8 @@ public class XPluginImp implements Plugin { SaManager.setSaSignTemplate(bean); }); - // 自定义 StpLogic 对象(可以有多个) - context.subBeansOfType(StpLogic.class, bean -> { + // 自定义 StpLogic 对象 //容器层面只能有一个;要多个得自己在Util上处理 + context.getBeanAsync(StpLogic.class, bean -> { StpUtil.setStpLogic(bean); }); } diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenFilter.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenFilter.java new file mode 100644 index 00000000..5d7d0f25 --- /dev/null +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenFilter.java @@ -0,0 +1,219 @@ +package cn.dev33.satoken.solon.integration; + +import cn.dev33.satoken.annotation.SaIgnore; +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.router.SaRouter; +import cn.dev33.satoken.strategy.SaStrategy; +import org.noear.solon.Solon; +import org.noear.solon.core.handle.*; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * sa-token 基于路由的过滤式鉴权(增加了注解的处理);使用优先级要低些 + * + * 对静态文件有处理效果 + * + * order: -100 (SaTokenInterceptor 和 SaTokenFilter 二选一;不要同时用) + * + * @author noear + * @since 1.10 + */ +public class SaTokenFilter implements Filter { //之所以改名,为了跟 SaTokenInterceptor 形成一对 + /** + * 是否打开注解鉴权 + */ + public boolean isAnnotation = true; + + // ------------------------ 设置此过滤器 拦截 & 放行 的路由 + + /** + * 拦截路由 + */ + protected List includeList = new ArrayList<>(); + + /** + * 放行路由 + */ + protected List excludeList = new ArrayList<>(); + + /** + * 添加 [拦截路由] + * + * @param paths 路由 + * @return 对象自身 + */ + public SaTokenFilter addInclude(String... paths) { + includeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 添加 [放行路由] + * + * @param paths 路由 + * @return 对象自身 + */ + public SaTokenFilter addExclude(String... paths) { + excludeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 写入 [拦截路由] 集合 + * + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaTokenFilter setIncludeList(List pathList) { + includeList = pathList; + return this; + } + + /** + * 写入 [放行路由] 集合 + * + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaTokenFilter setExcludeList(List pathList) { + excludeList = pathList; + return this; + } + + /** + * 获取 [拦截路由] 集合 + * + * @return see note + */ + public List getIncludeList() { + return includeList; + } + + /** + * 获取 [放行路由] 集合 + * + * @return see note + */ + public List getExcludeList() { + return excludeList; + } + + + // ------------------------ 钩子函数 + + /** + * 认证函数:每次请求执行 + */ + protected SaFilterAuthStrategy auth = r -> { + }; + + /** + * 异常处理函数:每次[认证函数]发生异常时执行此函数 + */ + protected SaFilterErrorStrategy error = e -> { + if (e instanceof SaTokenException) { + throw (SaTokenException) e; + } else { + throw new SaTokenException(e); + } + }; + + /** + * 前置函数:在每次[认证函数]之前执行 + */ + protected SaFilterAuthStrategy beforeAuth = r -> { + }; + + /** + * 写入[认证函数]: 每次请求执行 + * + * @param auth see note + * @return 对象自身 + */ + public SaTokenFilter setAuth(SaFilterAuthStrategy auth) { + this.auth = auth; + return this; + } + + /** + * 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数 + * + * @param error see note + * @return 对象自身 + */ + public SaTokenFilter setError(SaFilterErrorStrategy error) { + this.error = error; + return this; + } + + /** + * 写入[前置函数]:在每次[认证函数]之前执行 + * + * @param beforeAuth see note + * @return 对象自身 + */ + public SaTokenFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) { + this.beforeAuth = beforeAuth; + return this; + } + + + @Override + public void doFilter(Context ctx, FilterChain chain) throws Throwable { + try { + //查找当前主处理 + Handler mainHandler = Solon.app().router().matchMain(ctx); + + //如果是静态文件,则不处理(静态文件,不在路由中) + if (mainHandler != null) { + Action action = (mainHandler instanceof Action ? (Action) mainHandler : null); + + if (isAnnotation && action != null) { + // 获取此请求对应的 Method 处理函数 + Method method = action.method().getMethod(); + + // 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权 + if (SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class)) { + return; + } + + // 注解校验 + SaStrategy.me.checkMethodAnnotation.accept(method); + } + + //路径规则处理 + SaRouter.match(includeList).notMatch(excludeList).check(r -> { + beforeAuth.run(mainHandler); + auth.run(mainHandler); + }); + } + } catch (StopMatchException e) { + + } catch (SaTokenException e) { + // 1. 获取异常处理策略结果 + Object result; + if (e instanceof BackResultException) { + result = e.getMessage(); + } else { + result = error.run(e); + } + + // 2. 写入输出流 + if (result != null) { + ctx.render(result); + } + ctx.setHandled(true); + return; + } + + chain.doFilter(ctx); + } +} diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenInterceptor.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenInterceptor.java new file mode 100644 index 00000000..f16bd2a1 --- /dev/null +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenInterceptor.java @@ -0,0 +1,217 @@ +package cn.dev33.satoken.solon.integration; + +import cn.dev33.satoken.annotation.SaIgnore; +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.router.SaRouter; +import cn.dev33.satoken.strategy.SaStrategy; +import org.noear.solon.core.handle.*; +import org.noear.solon.core.route.RouterInterceptor; +import org.noear.solon.core.route.RouterInterceptorChain; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * sa-token 基于路由的过滤式鉴权(增加了注解的处理);使用优先级要低些 + * + * 对静态文件无处理效果 + * + * order: -100 (SaTokenInterceptor 和 SaTokenFilter 二选一;不要同时用) + * + * @author noear + * @since 1.12 + */ +public class SaTokenInterceptor implements RouterInterceptor { + /** + * 是否打开注解鉴权 + */ + public boolean isAnnotation = true; + + // ------------------------ 设置此过滤器 拦截 & 放行 的路由 + + /** + * 拦截路由 + */ + protected List includeList = new ArrayList<>(); + + /** + * 放行路由 + */ + protected List excludeList = new ArrayList<>(); + + /** + * 添加 [拦截路由] + * + * @param paths 路由 + * @return 对象自身 + */ + public SaTokenInterceptor addInclude(String... paths) { + includeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 添加 [放行路由] + * + * @param paths 路由 + * @return 对象自身 + */ + public SaTokenInterceptor addExclude(String... paths) { + excludeList.addAll(Arrays.asList(paths)); + return this; + } + + /** + * 写入 [拦截路由] 集合 + * + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaTokenInterceptor setIncludeList(List pathList) { + includeList = pathList; + return this; + } + + /** + * 写入 [放行路由] 集合 + * + * @param pathList 路由集合 + * @return 对象自身 + */ + public SaTokenInterceptor setExcludeList(List pathList) { + excludeList = pathList; + return this; + } + + /** + * 获取 [拦截路由] 集合 + * + * @return see note + */ + public List getIncludeList() { + return includeList; + } + + /** + * 获取 [放行路由] 集合 + * + * @return see note + */ + public List getExcludeList() { + return excludeList; + } + + + // ------------------------ 钩子函数 + + /** + * 认证函数:每次请求执行 + */ + protected SaFilterAuthStrategy auth = r -> { + }; + + /** + * 异常处理函数:每次[认证函数]发生异常时执行此函数 + */ + protected SaFilterErrorStrategy error = e -> { + if (e instanceof SaTokenException) { + throw (SaTokenException) e; + } else { + throw new SaTokenException(e); + } + }; + + /** + * 前置函数:在每次[认证函数]之前执行 + */ + protected SaFilterAuthStrategy beforeAuth = r -> { + }; + + /** + * 写入[认证函数]: 每次请求执行 + * + * @param auth see note + * @return 对象自身 + */ + public SaTokenInterceptor setAuth(SaFilterAuthStrategy auth) { + this.auth = auth; + return this; + } + + /** + * 写入[异常处理函数]:每次[认证函数]发生异常时执行此函数 + * + * @param error see note + * @return 对象自身 + */ + public SaTokenInterceptor setError(SaFilterErrorStrategy error) { + this.error = error; + return this; + } + + /** + * 写入[前置函数]:在每次[认证函数]之前执行 + * + * @param beforeAuth see note + * @return 对象自身 + */ + public SaTokenInterceptor setBeforeAuth(SaFilterAuthStrategy beforeAuth) { + this.beforeAuth = beforeAuth; + return this; + } + + + @Override + public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable { + try { + //如果是静态文件,则不处理(静态文件,不在路由中) + if (mainHandler != null) { + Action action = (mainHandler instanceof Action ? (Action) mainHandler : null); + + if (isAnnotation && action != null) { + // 获取此请求对应的 Method 处理函数 + Method method = action.method().getMethod(); + + // 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权 + if (SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class)) { + return; + } + + // 注解校验 + SaStrategy.me.checkMethodAnnotation.accept(method); + } + + //路径规则处理 + SaRouter.match(includeList).notMatch(excludeList).check(r -> { + beforeAuth.run(mainHandler); + auth.run(mainHandler); + }); + } + } catch (StopMatchException e) { + + } catch (SaTokenException e) { + // 1. 获取异常处理策略结果 + Object result; + if (e instanceof BackResultException) { + result = e.getMessage(); + } else { + result = error.run(e); + } + + // 2. 写入输出流 + if (result != null) { + ctx.render(result); + } + ctx.setHandled(true); + return; + } + + chain.doIntercept(ctx, mainHandler); + } +} diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java index 6dba3370..b48bd23a 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java @@ -28,6 +28,7 @@ import cn.dev33.satoken.strategy.SaStrategy; * @author noear * @since 1.10 */ +@Deprecated public class SaTokenPathFilter implements Filter { /** * 是否打开注解鉴权 diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java index 56767702..2e5fb944 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathInterceptor.java @@ -24,6 +24,7 @@ import java.util.List; * @author noear * @since 1.10 */ +@Deprecated public class SaTokenPathInterceptor implements Handler { /** * 是否打开注解鉴权