mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-10-07 23:24:24 +08:00
refactor: 重构防火墙模块,增加 hooks 机制
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 {
|
||||
|
||||
/**
|
||||
* 序列化版本号
|
||||
|
@@ -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 的算法
|
||||
*
|
||||
* <p> 如果属于无效请求 path,则抛出异常 RequestPathInvalidException </p>
|
||||
* 函数式接口:当防火墙校验不通过时执行的函数
|
||||
*
|
||||
* @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);
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
@@ -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<SaFirewallCheckHook> 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 校验不通过时地处理方案,自定义示例:
|
||||
* <pre>
|
||||
* SaFirewallStrategy.instance.requestPathInvalidHandle = (e, extArg1, extArg2) -> {
|
||||
* SaFirewallStrategy.instance.checkFailHandle = (e, req, res, extArg) -> {
|
||||
* // 自定义处理逻辑 ...
|
||||
* };
|
||||
* </pre>
|
||||
*/
|
||||
public SaRequestPathInvalidHandleFunction requestPathInvalidHandle = null;
|
||||
public SaFirewallCheckFailHandleFunction checkFailHandle = null;
|
||||
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -60,11 +60,6 @@
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-fastjson2</artifactId>
|
||||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 提供Redis连接池 -->
|
||||
<dependency>
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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 是否合法
|
||||
try {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
SaFirewallStrategy.instance.checkRequestPath.run(req.getRequestURI(), request, response);
|
||||
} catch (RequestPathInvalidException e) {
|
||||
if(SaFirewallStrategy.instance.requestPathInvalidHandle == null) {
|
||||
HttpServletResponse res = (HttpServletResponse) response;
|
||||
SaRequestForServlet saRequest = new SaRequestForServlet(req);
|
||||
SaResponseForServlet saResponse = new SaResponseForServlet(res);
|
||||
|
||||
try {
|
||||
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);
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user