Files
sa-token/sa-token-doc/fun/firewall.md

118 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 防火墙
Sa-Token 内置防火墙组件 `SaFirewallStrategy`,用于拦截一些可能造成攻击的危险请求。
例如当前端提交的 path 为 `/test//login` 时,框架将会强制截断请求,响应以下内容:
``` txt
非法请求:/test//login
```
因为包含双斜杠的 path 请求通常被用于鉴权绕行攻击。类似的拦截规则还有很多, `SaFirewallStrategy` 采用 hooks 机制,允许开发者自由扩展拦截规则,
框架默认具有以下 hook 拦截规则:
- `SaFirewallCheckHookForWhitePath`:请求 path 白名单放行。
- `SaFirewallCheckHookForBlackPath`:请求 path 黑名单校验。
- `SaFirewallCheckHookForPathDangerCharacter`:请求 path 危险字符校。
- `SaFirewallCheckHookForPathBannedCharacter`:请求 path 禁止字符校验。
- `SaFirewallCheckHookForDirectoryTraversal`:请求 path 目录遍历符检测。
- `SaFirewallCheckHookForHost`Host 检测。
- `SaFirewallCheckHookForHttpMethod`:请求 Method 检测。
- `SaFirewallCheckHookForHeader`:请求头检测。
- `SaFirewallCheckHookForParameter`:请求参数检测。
### 1、默认 hook 配置:
假设我们想要增加请求 path 黑名单,可以使用如下代码:
``` java
@Configuration
public class SaTokenConfigure {
@PostConstruct
public void saTokenPostConstruct() {
SaFirewallCheckHookForBlackPath.instance.resetConfig("/abc");
}
}
```
现在从浏览器访问 `/abc`,将会被防火墙组件直接拦截:
``` txt
非法请求:/abc
```
除了 `SaFirewallCheckHookForBlackPath` 以外,其它所有 hook 均可通过此方式重载配置,在此暂不冗余演示。
### 2、注册新的 hook 规则:
你可以使用如下代码注册新的 hook 规则:
``` java
@PostConstruct
public void saTokenPostConstruct() {
// 注册新 hook 演示,拦截所有带有 pwd 参数的请求,拒绝响应
SaFirewallStrategy.instance.registerHook((req, res, extArg)->{
if(req.getParam("pwd") != null) {
throw new FirewallCheckException("请求中不可包含 pwd 参数");
}
});
}
```
除了注册新 hook 规则,你还可以移除默认 hook ,来删减你认为不必要存在的校验规则:
``` java
// 移除指定类型的 hook 验证
SaFirewallStrategy.instance.removeHook(SaFirewallCheckHookForHost.class);
```
### 3、利用自动注入特性注册 hook
如果你的项目属于 IOC 环境(例如 SpringBoot 项目),还可以这样注册 hook
``` java
// 自定义防火墙校验 hook
@Component
public class SaFirewallCheckHookForXxx implements SaFirewallCheckHook {
@Override
public void execute(SaRequest req, SaResponse res, Object extArg) {
System.out.println("----------- 自定义防火墙校验 hook ");
}
}
```
### 4、指定异常处理
被防火墙拦截的请求不会做出格式化响应,因为通常这些请求为非正常业务请求,只需阻断即可,无需前端依照响应做出页面提示。
如果你的业务切实需要对防火墙拦截做出格式化响应,可以通过以下代码完成:
``` java
@PostConstruct
public void saTokenPostConstruct() {
// 指定防火墙校验不通过时的处理方案
SaFirewallStrategy.instance.checkFailHandle = (e, req, res, extArg) -> {
System.out.println("防火墙校验不通过:" + e.getMessage());
try {
HttpServletResponse response = (HttpServletResponse)res.getSource();
response.setContentType("application/json;charset=UTF-8");
String resJson = SaResult.error(e.getMessage()).toString();
response.getWriter().print(resJson);
response.getWriter().flush();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
};
}
```
浏览器将得到以下 json 格式响应:
``` js
{
"code": 500,
"msg": "非法请求:/abc",
"data": null
}