refactor: 重构相关 starter 包的防火墙过滤器代价

This commit is contained in:
click33 2025-02-27 06:15:54 +08:00
parent db5e70db6a
commit 59823fd3cd
9 changed files with 82 additions and 47 deletions

View File

@ -187,9 +187,9 @@ public class SaTokenConsts {
public static final int ASSEMBLY_ORDER = -100; public static final int ASSEMBLY_ORDER = -100;
/** /**
* 请求 path 校验过滤器的注册顺序 * 防火墙校验过滤器的注册顺序
*/ */
public static final int PATH_CHECK_FILTER_ORDER = -1000; public static final int FIREWALL_CHECK_FILTER_ORDER = -1000;
/** /**
* Content-Type key * Content-Type key

View File

@ -15,7 +15,10 @@
*/ */
package cn.dev33.satoken.reactor.filter; package cn.dev33.satoken.reactor.filter;
import cn.dev33.satoken.exception.RequestPathInvalidException; import cn.dev33.satoken.exception.FirewallCheckException;
import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.reactor.model.SaRequestForReactor;
import cn.dev33.satoken.reactor.model.SaResponseForReactor;
import cn.dev33.satoken.strategy.SaFirewallStrategy; import cn.dev33.satoken.strategy.SaFirewallStrategy;
import cn.dev33.satoken.util.SaTokenConsts; import cn.dev33.satoken.util.SaTokenConsts;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
@ -25,29 +28,37 @@ import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
/** /**
* 校验请求 path 是否合法 * 防火墙校验过滤器 (Reactor版)
* *
* @author click33 * @author click33
* @since 1.37.0 * @since 1.37.0
*/ */
@Order(SaTokenConsts.PATH_CHECK_FILTER_ORDER) @Order(SaTokenConsts.FIREWALL_CHECK_FILTER_ORDER)
public class SaPathCheckFilterForReactor implements WebFilter { public class SaFirewallCheckFilterForReactor implements WebFilter {
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
// 校验本次请求 path 是否合法 SaRequestForReactor saRequest = new SaRequestForReactor(exchange.getRequest());
SaResponseForReactor saResponse = new SaResponseForReactor(exchange.getResponse());
try { try {
SaFirewallStrategy.instance.check.run(exchange.getRequest().getPath().toString(), exchange, null); SaFirewallStrategy.instance.check.execute(saRequest, saResponse, exchange);
} catch (RequestPathInvalidException e) { }
catch (StopMatchException e) {
// 如果是 StopMatchException 异常代表通过了防火墙验证进入 Controller
}
catch (FirewallCheckException e) {
// FirewallCheckException 异常则交由异常处理策略处理
if(SaFirewallStrategy.instance.checkFailHandle == null) { if(SaFirewallStrategy.instance.checkFailHandle == null) {
exchange.getResponse().getHeaders().set(SaTokenConsts.CONTENT_TYPE_KEY, SaTokenConsts.CONTENT_TYPE_TEXT_PLAIN); 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()))); return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(e.getMessage().getBytes())));
} else { } else {
SaFirewallStrategy.instance.checkFailHandle.run(e, exchange, null); SaFirewallStrategy.instance.checkFailHandle.run(e, saRequest, saResponse, null);
return Mono.empty();
} }
return Mono.empty();
} }
// 更多异常则不处理交由 Web 框架处理
// 向下执行 // 向下执行
return chain.filter(exchange); return chain.filter(exchange);

View File

@ -15,7 +15,7 @@
*/ */
package cn.dev33.satoken.reactor.spring; package cn.dev33.satoken.reactor.spring;
import cn.dev33.satoken.reactor.filter.SaPathCheckFilterForReactor; import cn.dev33.satoken.reactor.filter.SaFirewallCheckFilterForReactor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.context.SaTokenContext;
@ -44,8 +44,8 @@ public class SaTokenContextRegister {
* @return / * @return /
*/ */
@Bean @Bean
public SaPathCheckFilterForReactor saPathCheckFilterForReactor() { public SaFirewallCheckFilterForReactor saFirewallCheckFilterForReactor() {
return new SaPathCheckFilterForReactor(); return new SaFirewallCheckFilterForReactor();
} }
} }

View File

@ -15,7 +15,10 @@
*/ */
package cn.dev33.satoken.reactor.filter; package cn.dev33.satoken.reactor.filter;
import cn.dev33.satoken.exception.RequestPathInvalidException; import cn.dev33.satoken.exception.FirewallCheckException;
import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.reactor.model.SaRequestForReactor;
import cn.dev33.satoken.reactor.model.SaResponseForReactor;
import cn.dev33.satoken.strategy.SaFirewallStrategy; import cn.dev33.satoken.strategy.SaFirewallStrategy;
import cn.dev33.satoken.util.SaTokenConsts; import cn.dev33.satoken.util.SaTokenConsts;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
@ -25,29 +28,37 @@ import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
/** /**
* 校验请求 path 是否合法 * 防火墙校验过滤器 (Reactor版)
* *
* @author click33 * @author click33
* @since 1.37.0 * @since 1.37.0
*/ */
@Order(SaTokenConsts.PATH_CHECK_FILTER_ORDER) @Order(SaTokenConsts.FIREWALL_CHECK_FILTER_ORDER)
public class SaPathCheckFilterForReactor implements WebFilter { public class SaFirewallCheckFilterForReactor implements WebFilter {
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
// 校验本次请求 path 是否合法 SaRequestForReactor saRequest = new SaRequestForReactor(exchange.getRequest());
SaResponseForReactor saResponse = new SaResponseForReactor(exchange.getResponse());
try { try {
SaFirewallStrategy.instance.check.run(exchange.getRequest().getPath().toString(), exchange, null); SaFirewallStrategy.instance.check.execute(saRequest, saResponse, exchange);
} catch (RequestPathInvalidException e) { }
catch (StopMatchException e) {
// 如果是 StopMatchException 异常代表通过了防火墙验证进入 Controller
}
catch (FirewallCheckException e) {
// FirewallCheckException 异常则交由异常处理策略处理
if(SaFirewallStrategy.instance.checkFailHandle == null) { if(SaFirewallStrategy.instance.checkFailHandle == null) {
exchange.getResponse().getHeaders().set(SaTokenConsts.CONTENT_TYPE_KEY, SaTokenConsts.CONTENT_TYPE_TEXT_PLAIN); 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()))); return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(e.getMessage().getBytes())));
} else { } else {
SaFirewallStrategy.instance.checkFailHandle.run(e, exchange, null); SaFirewallStrategy.instance.checkFailHandle.run(e, saRequest, saResponse, null);
return Mono.empty();
} }
return Mono.empty();
} }
// 更多异常则不处理交由 Web 框架处理
// 向下执行 // 向下执行
return chain.filter(exchange); return chain.filter(exchange);

View File

@ -16,7 +16,7 @@
package cn.dev33.satoken.reactor.spring; package cn.dev33.satoken.reactor.spring;
import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.context.SaTokenContext;
import cn.dev33.satoken.reactor.filter.SaPathCheckFilterForReactor; import cn.dev33.satoken.reactor.filter.SaFirewallCheckFilterForReactor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
/** /**
@ -43,8 +43,8 @@ public class SaTokenContextRegister {
* @return / * @return /
*/ */
@Bean @Bean
public SaPathCheckFilterForReactor saPathCheckFilterForReactor() { public SaFirewallCheckFilterForReactor saFirewallCheckFilterForReactor() {
return new SaPathCheckFilterForReactor(); return new SaFirewallCheckFilterForReactor();
} }
} }

View File

@ -29,12 +29,12 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
/** /**
* 防火墙校验过滤器 * 防火墙校验过滤器 (基于 Servlet)
* *
* @author click33 * @author click33
* @since 1.37.0 * @since 1.37.0
*/ */
@Order(SaTokenConsts.PATH_CHECK_FILTER_ORDER) @Order(SaTokenConsts.FIREWALL_CHECK_FILTER_ORDER)
public class SaFirewallCheckFilterForServlet implements Filter { public class SaFirewallCheckFilterForServlet implements Filter {
@Override @Override

View File

@ -43,7 +43,7 @@ public class SaTokenContextRegister {
* @return / * @return /
*/ */
@Bean @Bean
public SaFirewallCheckFilterForServlet saPathCheckFilterForServlet() { public SaFirewallCheckFilterForServlet saFirewallCheckFilterForServlet() {
return new SaFirewallCheckFilterForServlet(); return new SaFirewallCheckFilterForServlet();
} }

View File

@ -15,43 +15,56 @@
*/ */
package cn.dev33.satoken.filter; 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.strategy.SaFirewallStrategy;
import cn.dev33.satoken.util.SaTokenConsts; import cn.dev33.satoken.util.SaTokenConsts;
import jakarta.servlet.*; import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import java.io.IOException; import java.io.IOException;
/** /**
* 校验请求 path 是否合法 * 防火墙校验过滤器 (基于 Jakarta-Servlet)
* *
* @author click33 * @author click33
* @since 1.37.0 * @since 1.37.0
*/ */
@Order(SaTokenConsts.PATH_CHECK_FILTER_ORDER) @Order(SaTokenConsts.FIREWALL_CHECK_FILTER_ORDER)
public class SaPathCheckFilterForJakartaServlet implements Filter { public class SaFirewallCheckFilterForJakartaServlet implements Filter {
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 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 { try {
HttpServletRequest req = (HttpServletRequest) request; SaFirewallStrategy.instance.check.execute(saRequest, saResponse, null);
SaFirewallStrategy.instance.check.run(req.getRequestURI(), request, response); }
} catch (RequestPathInvalidException e) { catch (StopMatchException e) {
// 如果是 StopMatchException 异常代表通过了防火墙验证进入 Controller
}
catch (FirewallCheckException e) {
// FirewallCheckException 异常则交由异常处理策略处理
if(SaFirewallStrategy.instance.checkFailHandle == null) { if(SaFirewallStrategy.instance.checkFailHandle == null) {
response.setContentType("text/plain; charset=utf-8"); response.setContentType("text/plain; charset=utf-8");
response.getWriter().print(e.getMessage()); response.getWriter().print(e.getMessage());
response.getWriter().flush(); response.getWriter().flush();
} else { } else {
SaFirewallStrategy.instance.checkFailHandle.run(e, request, response); SaFirewallStrategy.instance.checkFailHandle.run(e, saRequest, saResponse, null);
} }
return; return;
} }
// 更多异常则不处理交由 Web 框架处理
// 执行 // 执行
chain.doFilter(request, response); chain.doFilter(request, response);
} }

View File

@ -16,7 +16,7 @@
package cn.dev33.satoken.spring; package cn.dev33.satoken.spring;
import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.context.SaTokenContext;
import cn.dev33.satoken.filter.SaPathCheckFilterForJakartaServlet; import cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
/** /**
@ -43,8 +43,8 @@ public class SaTokenContextRegister {
* @return / * @return /
*/ */
@Bean @Bean
public SaPathCheckFilterForJakartaServlet saPathCheckFilterForJakartaServlet() { public SaFirewallCheckFilterForJakartaServlet saFirewallCheckFilterForJakartaServlet() {
return new SaPathCheckFilterForJakartaServlet(); return new SaFirewallCheckFilterForJakartaServlet();
} }
} }