From db5e70db6a4269e558ba4db5a200dd7fea82ed7f Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Thu, 27 Feb 2025 05:55:55 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E9=98=B2?= =?UTF-8?q?=E7=81=AB=E5=A2=99=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20hooks=20=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/FirewallCheckException.java | 43 +++++++++ .../RequestPathInvalidException.java | 2 +- ...=> SaFirewallCheckFailHandleFunction.java} | 19 ++-- ...tion.java => SaFirewallCheckFunction.java} | 16 ++-- .../satoken/strategy/SaFirewallStrategy.java | 96 ++++++------------- .../strategy/hooks/SaFirewallCheckHook.java | 39 ++++++++ .../SaFirewallCheckHookForBlackList.java | 58 +++++++++++ ...SaFirewallCheckHookForDangerCharacter.java | 66 +++++++++++++ .../SaFirewallCheckHookForWhiteList.java | 58 +++++++++++ sa-token-demo/sa-token-demo-test/pom.xml | 5 - .../filter/SaPathCheckFilterForReactor.java | 6 +- .../filter/SaPathCheckFilterForReactor.java | 6 +- ...a => SaFirewallCheckFilterForServlet.java} | 33 +++++-- .../spring/SaTokenContextRegister.java | 6 +- .../SaPathCheckFilterForJakartaServlet.java | 6 +- 15 files changed, 350 insertions(+), 109 deletions(-) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/exception/FirewallCheckException.java rename sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/{SaCheckRequestPathFunction.java => SaFirewallCheckFailHandleFunction.java} (59%) rename sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/{SaRequestPathInvalidHandleFunction.java => SaFirewallCheckFunction.java} (65%) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHook.java create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForBlackList.java create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForDangerCharacter.java create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForWhiteList.java rename sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/{SaPathCheckFilterForServlet.java => SaFirewallCheckFilterForServlet.java} (56%) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/FirewallCheckException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/FirewallCheckException.java new file mode 100644 index 00000000..810cd903 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/FirewallCheckException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.exception; + +/** + * 一个异常:代表防火墙检验未通过 + * + * @author click33 + * @since 1.41.0 + */ +public class FirewallCheckException extends SaTokenException { + + /** + * 序列化版本号 + */ + private static final long serialVersionUID = 8243974276159004739L; + + public FirewallCheckException(String message) { + super(message); + } + + public FirewallCheckException(Throwable e) { + super(e); + } + + public FirewallCheckException(String message, Throwable e) { + super(message, e); + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/RequestPathInvalidException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/RequestPathInvalidException.java index e09cf9e0..3f2b972d 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/RequestPathInvalidException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/RequestPathInvalidException.java @@ -21,7 +21,7 @@ package cn.dev33.satoken.exception; * @author click33 * @since 1.37.0 */ -public class RequestPathInvalidException extends SaTokenException { +public class RequestPathInvalidException extends FirewallCheckException { /** * 序列化版本号 diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaCheckRequestPathFunction.java b/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaFirewallCheckFailHandleFunction.java similarity index 59% rename from sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaCheckRequestPathFunction.java rename to sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaFirewallCheckFailHandleFunction.java index dcca032f..c77121e4 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaCheckRequestPathFunction.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaFirewallCheckFailHandleFunction.java @@ -15,25 +15,26 @@ */ package cn.dev33.satoken.fun.strategy; -import cn.dev33.satoken.exception.RequestPathInvalidException; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.exception.FirewallCheckException; /** - * 函数式接口:校验请求 path 的算法 - * - *

如果属于无效请求 path,则抛出异常 RequestPathInvalidException

+ * 函数式接口:当防火墙校验不通过时执行的函数 * * @author click33 * @since 1.37.0 */ @FunctionalInterface -public interface SaCheckRequestPathFunction { +public interface SaFirewallCheckFailHandleFunction { /** * 执行函数 - * @param path 请求 path - * @param extArg1 扩展参数1 - * @param extArg2 扩展参数2 + * @param e 防火墙校验异常 + * @param req 请求对象 + * @param res 响应对象 + * @param extArg 预留扩展参数 */ - void run(String path, Object extArg1, Object extArg2); + void run(FirewallCheckException e, SaRequest req, SaResponse res, Object extArg); } \ No newline at end of file diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaRequestPathInvalidHandleFunction.java b/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaFirewallCheckFunction.java similarity index 65% rename from sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaRequestPathInvalidHandleFunction.java rename to sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaFirewallCheckFunction.java index d3880465..bbb5aedc 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaRequestPathInvalidHandleFunction.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/fun/strategy/SaFirewallCheckFunction.java @@ -15,23 +15,25 @@ */ package cn.dev33.satoken.fun.strategy; -import cn.dev33.satoken.exception.RequestPathInvalidException; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; /** - * 函数式接口:当请求 path 校验不通过时处理方案的算法 + * 函数式接口:防火墙校验函数 * * @author click33 * @since 1.37.0 */ @FunctionalInterface -public interface SaRequestPathInvalidHandleFunction { +public interface SaFirewallCheckFunction { /** * 执行函数 - * @param e 请求 path 无效的异常对象 - * @param extArg1 扩展参数1 - * @param extArg2 扩展参数2 + * + * @param req 请求对象 + * @param res 响应对象 + * @param extArg 预留扩展参数 */ - void run(RequestPathInvalidException e, Object extArg1, Object extArg2); + void execute(SaRequest req, SaResponse res, Object extArg); } \ No newline at end of file diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaFirewallStrategy.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaFirewallStrategy.java index 55e4da5f..d81f2912 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaFirewallStrategy.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaFirewallStrategy.java @@ -15,9 +15,16 @@ */ package cn.dev33.satoken.strategy; -import cn.dev33.satoken.exception.RequestPathInvalidException; -import cn.dev33.satoken.fun.strategy.SaCheckRequestPathFunction; -import cn.dev33.satoken.fun.strategy.SaRequestPathInvalidHandleFunction; +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.fun.strategy.SaFirewallCheckFailHandleFunction; +import cn.dev33.satoken.fun.strategy.SaFirewallCheckFunction; +import cn.dev33.satoken.strategy.hooks.SaFirewallCheckHook; +import cn.dev33.satoken.strategy.hooks.SaFirewallCheckHookForBlackList; +import cn.dev33.satoken.strategy.hooks.SaFirewallCheckHookForDangerCharacter; +import cn.dev33.satoken.strategy.hooks.SaFirewallCheckHookForWhiteList; + +import java.util.ArrayList; +import java.util.List; /** * Sa-Token 防火墙策略 @@ -27,9 +34,6 @@ import cn.dev33.satoken.fun.strategy.SaRequestPathInvalidHandleFunction; */ public final class SaFirewallStrategy { - private SaFirewallStrategy() { - } - /** * 全局单例引用 */ @@ -38,76 +42,38 @@ public final class SaFirewallStrategy { // ----------------------- 所有策略 + public List checkHooks = new ArrayList<>(); + + private SaFirewallStrategy() { + checkHooks.add(SaFirewallCheckHookForWhiteList.instance); + checkHooks.add(SaFirewallCheckHookForBlackList.instance); + checkHooks.add(SaFirewallCheckHookForDangerCharacter.instance); + } + + // 注册一个防火墙校验 hook + public void registerCheckHook(SaFirewallCheckHook checkHook) { + SaManager.getLog().info("防火墙校验 hook 注册成功: " + checkHook.getClass()); + checkHooks.add(checkHook); + } /** - * 请求 path 黑名单 + * 防火墙校验函数 */ - public String[] blackPaths = {}; - - /** - * 请求 path 白名单 - */ - public String[] whitePaths = {}; - - /** - * 请求 path 不允许出现的字符 - */ - public String[] invalidCharacter = { - "//", // // - "\\", // \ - "%2e", "%2E", // . - "%2f", "%2F", // / - "%5c", "%5C", // \ - ";", "%3b", "%3B", // ; // 参考资料:https://mp.weixin.qq.com/s/77CIDZbgBwRunJeluofPTA - "%25" // 空格 + public SaFirewallCheckFunction check = (req, res, extArg) -> { + for (SaFirewallCheckHook checkHook : checkHooks) { + checkHook.execute(req, res, extArg); + } }; /** - * 校验请求 path 的算法 - */ - public SaCheckRequestPathFunction checkRequestPath = (requestPath, extArg1, extArg2) -> { - // 1、如果在白名单里,则直接放行 - for (String item : whitePaths) { - if (requestPath.equals(item)) { - return; - } - } - - // 2、如果在黑名单里,则抛出异常 - for (String item : blackPaths) { - if (requestPath.equals(item)) { - throw new RequestPathInvalidException("非法请求:" + requestPath, requestPath); - } - } - - // 3、检查是否包含非法字符 - - // 不允许为null - if(requestPath == null) { - throw new RequestPathInvalidException("非法请求:null", null); - } - // 不允许包含非法字符 - for (String item : invalidCharacter) { - if (requestPath.contains(item)) { - throw new RequestPathInvalidException("非法请求:" + requestPath, requestPath); - } - } - // 不允许出现跨目录字符 - if(requestPath.contains("/.") || requestPath.contains("\\.")) { - throw new RequestPathInvalidException("非法请求:" + requestPath, requestPath); - } - }; - - - /** - * 当请求 path 校验不通过时处理方案的算法,自定义示例: + * 当请求 path 校验不通过时地处理方案,自定义示例: *
-	 * 		SaFirewallStrategy.instance.requestPathInvalidHandle = (e, extArg1, extArg2) -> {
+	 * 		SaFirewallStrategy.instance.checkFailHandle = (e, req, res, extArg) -> {
 	 * 			// 自定义处理逻辑 ...
 	 *      };
 	 * 
*/ - public SaRequestPathInvalidHandleFunction requestPathInvalidHandle = null; + public SaFirewallCheckFailHandleFunction checkFailHandle = null; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHook.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHook.java new file mode 100644 index 00000000..53e7b2ed --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHook.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.strategy.hooks; + +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; + +/** + * 防火墙策略校验钩子函数 - 接口 + * + * @author click33 + * @since 1.41.0 + */ +@FunctionalInterface +public interface SaFirewallCheckHook { + + /** + * 执行的方法 + * + * @param req 请求对象 + * @param res 响应对象 + * @param extArg 预留扩展参数 + */ + void execute(SaRequest req, SaResponse res, Object extArg); + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForBlackList.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForBlackList.java new file mode 100644 index 00000000..1be62b83 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForBlackList.java @@ -0,0 +1,58 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.strategy.hooks; + +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.exception.RequestPathInvalidException; + +/** + * 防火墙策略校验钩子函数:黑名单校验 + * + * @author click33 + * @since 1.41.0 + */ +public class SaFirewallCheckHookForBlackList implements SaFirewallCheckHook { + + /** + * 默认实例 + */ + public static SaFirewallCheckHookForBlackList instance = new SaFirewallCheckHookForBlackList(); + + /** + * 请求 path 黑名单 + */ + public String[] blackPaths = {}; + + /** + * 执行的方法 + * + * @param req 请求对象 + * @param res 响应对象 + * @param extArg 扩展预留参数 + */ + @Override + public void execute(SaRequest req, SaResponse res, Object extArg) { + String requestPath = req.getRequestPath(); + for (String item : blackPaths) { + if (requestPath.equals(item)) { + throw new RequestPathInvalidException("非法请求:" + requestPath, requestPath); + } + } + + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForDangerCharacter.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForDangerCharacter.java new file mode 100644 index 00000000..d2fbac3e --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForDangerCharacter.java @@ -0,0 +1,66 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.strategy.hooks; + +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.exception.RequestPathInvalidException; + +/** + * 防火墙策略校验钩子函数:危险字符校验 + * + * @author click33 + * @since 1.41.0 + */ +public class SaFirewallCheckHookForDangerCharacter implements SaFirewallCheckHook { + + /** + * 默认实例 + */ + public static SaFirewallCheckHookForDangerCharacter instance = new SaFirewallCheckHookForDangerCharacter(); + + /** + * 请求 path 不允许出现的危险字符 + */ + public String[] dangerCharacter = { + "//", // // + "\\", // \ + "%2e", "%2E", // . + "%2f", "%2F", // / + "%5c", "%5C", // \ + ";", "%3b", "%3B", // ; // 参考资料:https://mp.weixin.qq.com/s/77CIDZbgBwRunJeluofPTA + "%25", // 空格 + "/.", "\\.", // /. \. 目录遍历符 + }; + + /** + * 执行的方法 + * + * @param req 请求对象 + * @param res 响应对象 + * @param extArg 预留扩展参数 + */ + @Override + public void execute(SaRequest req, SaResponse res, Object extArg) { + String requestPath = req.getRequestPath(); + for (String item : dangerCharacter) { + if (requestPath.contains(item)) { + throw new RequestPathInvalidException("非法请求:" + requestPath, requestPath); + } + } + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForWhiteList.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForWhiteList.java new file mode 100644 index 00000000..bfd08d13 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForWhiteList.java @@ -0,0 +1,58 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.strategy.hooks; + +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.context.model.SaResponse; +import cn.dev33.satoken.exception.StopMatchException; + +/** + * 防火墙策略校验钩子函数:白名单放行 + * + * @author click33 + * @since 1.41.0 + */ +public class SaFirewallCheckHookForWhiteList implements SaFirewallCheckHook { + + /** + * 默认实例 + */ + public static SaFirewallCheckHookForWhiteList instance = new SaFirewallCheckHookForWhiteList(); + + /** + * 请求 path 白名单 + */ + public String[] whitePaths = {}; + + /** + * 执行的方法 + * + * @param req 请求对象 + * @param res 响应对象 + * @param extArg 预留扩展参数 + */ + @Override + public void execute(SaRequest req, SaResponse res, Object extArg) { + String requestPath = req.getRequestPath(); + for (String item : whitePaths) { + if (requestPath.equals(item)) { + throw new StopMatchException(); + } + } + + } + +} diff --git a/sa-token-demo/sa-token-demo-test/pom.xml b/sa-token-demo/sa-token-demo-test/pom.xml index f310d333..64ff9c72 100644 --- a/sa-token-demo/sa-token-demo-test/pom.xml +++ b/sa-token-demo/sa-token-demo-test/pom.xml @@ -60,11 +60,6 @@ sa-token-redis-template ${sa-token.version} - - cn.dev33 - sa-token-fastjson2 - ${sa-token.version} - diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java index 55eeabcb..6a945133 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java @@ -38,13 +38,13 @@ public class SaPathCheckFilterForReactor implements WebFilter { // 校验本次请求 path 是否合法 try { - SaFirewallStrategy.instance.checkRequestPath.run(exchange.getRequest().getPath().toString(), exchange, null); + SaFirewallStrategy.instance.check.run(exchange.getRequest().getPath().toString(), exchange, null); } catch (RequestPathInvalidException e) { - if(SaFirewallStrategy.instance.requestPathInvalidHandle == null) { + if(SaFirewallStrategy.instance.checkFailHandle == null) { exchange.getResponse().getHeaders().set(SaTokenConsts.CONTENT_TYPE_KEY, SaTokenConsts.CONTENT_TYPE_TEXT_PLAIN); return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(e.getMessage().getBytes()))); } else { - SaFirewallStrategy.instance.requestPathInvalidHandle.run(e, exchange, null); + SaFirewallStrategy.instance.checkFailHandle.run(e, exchange, null); } return Mono.empty(); } diff --git a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java index 55eeabcb..6a945133 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java +++ b/sa-token-starter/sa-token-reactor-spring-boot3-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaPathCheckFilterForReactor.java @@ -38,13 +38,13 @@ public class SaPathCheckFilterForReactor implements WebFilter { // 校验本次请求 path 是否合法 try { - SaFirewallStrategy.instance.checkRequestPath.run(exchange.getRequest().getPath().toString(), exchange, null); + SaFirewallStrategy.instance.check.run(exchange.getRequest().getPath().toString(), exchange, null); } catch (RequestPathInvalidException e) { - if(SaFirewallStrategy.instance.requestPathInvalidHandle == null) { + if(SaFirewallStrategy.instance.checkFailHandle == null) { exchange.getResponse().getHeaders().set(SaTokenConsts.CONTENT_TYPE_KEY, SaTokenConsts.CONTENT_TYPE_TEXT_PLAIN); return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(e.getMessage().getBytes()))); } else { - SaFirewallStrategy.instance.requestPathInvalidHandle.run(e, exchange, null); + SaFirewallStrategy.instance.checkFailHandle.run(e, exchange, null); } return Mono.empty(); } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForServlet.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaFirewallCheckFilterForServlet.java similarity index 56% rename from sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForServlet.java rename to sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaFirewallCheckFilterForServlet.java index 13bdda90..77e60024 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForServlet.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaFirewallCheckFilterForServlet.java @@ -15,43 +15,56 @@ */ package cn.dev33.satoken.filter; -import cn.dev33.satoken.exception.RequestPathInvalidException; +import cn.dev33.satoken.exception.FirewallCheckException; +import cn.dev33.satoken.exception.StopMatchException; +import cn.dev33.satoken.servlet.model.SaRequestForServlet; +import cn.dev33.satoken.servlet.model.SaResponseForServlet; import cn.dev33.satoken.strategy.SaFirewallStrategy; import cn.dev33.satoken.util.SaTokenConsts; import org.springframework.core.annotation.Order; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** - * 校验请求 path 是否合法 + * 防火墙校验过滤器 * * @author click33 * @since 1.37.0 */ @Order(SaTokenConsts.PATH_CHECK_FILTER_ORDER) -public class SaPathCheckFilterForServlet implements Filter { +public class SaFirewallCheckFilterForServlet implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - // 校验本次请求 path 是否合法 + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; + SaRequestForServlet saRequest = new SaRequestForServlet(req); + SaResponseForServlet saResponse = new SaResponseForServlet(res); + try { - HttpServletRequest req = (HttpServletRequest) request; - SaFirewallStrategy.instance.checkRequestPath.run(req.getRequestURI(), request, response); - } catch (RequestPathInvalidException e) { - if(SaFirewallStrategy.instance.requestPathInvalidHandle == null) { + SaFirewallStrategy.instance.check.execute(saRequest, saResponse, null); + } + catch (StopMatchException e) { + // 如果是 StopMatchException 异常,代表通过了防火墙验证,进入 Controller + } + catch (FirewallCheckException e) { + // FirewallCheckException 异常则交由异常处理策略处理 + if(SaFirewallStrategy.instance.checkFailHandle == null) { response.setContentType("text/plain; charset=utf-8"); response.getWriter().print(e.getMessage()); response.getWriter().flush(); } else { - SaFirewallStrategy.instance.requestPathInvalidHandle.run(e, request, response); + SaFirewallStrategy.instance.checkFailHandle.run(e, saRequest, saResponse, null); } return; } + // 更多异常则不处理,交由 Web 框架处理 - // 向下执行 + // 向内执行 chain.doFilter(request, response); } 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 index fa24e0d9..fdc279d7 100644 --- 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 @@ -16,7 +16,7 @@ package cn.dev33.satoken.spring; import cn.dev33.satoken.context.SaTokenContext; -import cn.dev33.satoken.filter.SaPathCheckFilterForServlet; +import cn.dev33.satoken.filter.SaFirewallCheckFilterForServlet; import org.springframework.context.annotation.Bean; /** @@ -43,8 +43,8 @@ public class SaTokenContextRegister { * @return / */ @Bean - public SaPathCheckFilterForServlet saPathCheckFilterForServlet() { - return new SaPathCheckFilterForServlet(); + public SaFirewallCheckFilterForServlet saPathCheckFilterForServlet() { + return new SaFirewallCheckFilterForServlet(); } } diff --git a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForJakartaServlet.java b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForJakartaServlet.java index e13f13dd..8696c230 100644 --- a/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForJakartaServlet.java +++ b/sa-token-starter/sa-token-spring-boot3-starter/src/main/java/cn/dev33/satoken/filter/SaPathCheckFilterForJakartaServlet.java @@ -39,14 +39,14 @@ public class SaPathCheckFilterForJakartaServlet implements Filter { // 校验本次请求 path 是否合法 try { HttpServletRequest req = (HttpServletRequest) request; - SaFirewallStrategy.instance.checkRequestPath.run(req.getRequestURI(), request, response); + SaFirewallStrategy.instance.check.run(req.getRequestURI(), request, response); } catch (RequestPathInvalidException e) { - if(SaFirewallStrategy.instance.requestPathInvalidHandle == null) { + if(SaFirewallStrategy.instance.checkFailHandle == null) { response.setContentType("text/plain; charset=utf-8"); response.getWriter().print(e.getMessage()); response.getWriter().flush(); } else { - SaFirewallStrategy.instance.requestPathInvalidHandle.run(e, request, response); + SaFirewallStrategy.instance.checkFailHandle.run(e, request, response); } return; }