ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Sa-Token 全局过滤器:用 SaServletFilter 实现全站路由拦截鉴权

Sa-Token 全局过滤器:用 SaServletFilter 实现全站路由拦截鉴权 Sa-Token 全局过滤器用 SaServletFilter 实现全站路由拦截鉴权【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token导读在掌握了路由拦截鉴权的拦截器方案之后Sa-Token 还提供了一套基于 Java 标准 Filter 机制的全局过滤器SaServletFilter/SaReactorFilter可以在更底层、更前置的执行时机上完成登录校验、权限校验、安全响应头注入等能力也是 Spring WebFlux 等无拦截器框架中唯一的路由鉴权手段。读完本文你将掌握过滤器的注册方式、四大钩子函数setAuth/setError/setBeforeAuth/addInclude/addExclude的用法、异常处理与响应格式定制、执行顺序调整以及过滤器与拦截器两种方案的选型依据。为什么还需要一个全局过滤器既然拦截器SaInterceptor已经可以实现路由鉴权为什么 Sa-Token 还要提供一套过滤器实现核心原因在于两者所处的执行层次不同各有不可替代的场景执行时机更靠前过滤器位于 Servlet 容器层比 Spring MVC 的拦截器Interceptor更底层、执行时机更靠前有利于在请求进入业务链路之前完成防护防渗透扫描更有效。可以拦截静态资源过滤器天然覆盖静态资源请求方便统一做权限控制而拦截器通常只作用于 Spring MVC 映射的 Handler。普适性更强部分 Web 框架典型如 Spring WebFlux根本没有提供拦截器机制但几乎所有的 Web 框架都会提供过滤器机制因此过滤器是这些框架下的唯一选择。同时过滤器也有其固有缺点需要在使用时心中有数由于太过底层过滤器无法率先拿到HandlerMethod对象无法据此直接做基于方法签名的额外处理如注解鉴权。拦截范围过于全面导致需要对/favicon.ico等特殊路由做额外放行处理。在 Spring 中过滤器中抛出的异常不会进入全局ExceptionHandler必须额外编写异常处理逻辑。Sa-Token 同时提供过滤器和拦截器机制目的不是让谁替代谁而是让开发者根据实际业务框架类型、拦截粒度、静态资源需求合理选择。在 SpringBoot 中注册 SaServletFilter与拦截器一样为了避免不必要的性能浪费Sa-Token 全局过滤器默认处于关闭状态需要显式注册为 Spring Bean 才会生效。在 SpringBoot 中新建配置类并注册SaServletFilter即可/** * [Sa-Token 权限认证] 配置类 */ Configuration public class SaTokenConfigure { /** * 注册 [Sa-Token全局过滤器] */ Bean public SaServletFilter getSaServletFilter() { return new SaServletFilter() // 指定 拦截路由 与 放行路由 .addInclude(/**).addExclude(/favicon.ico) /* 排除掉 /favicon.ico */ // 认证函数: 每次请求执行 .setAuth(obj - { System.out.println(---------- 进入Sa-Token全局认证 -----------); // 登录认证 -- 拦截所有路由并排除/user/doLogin 用于开放登录 SaRouter.match(/**, /user/doLogin, () - StpUtil.checkLogin()); // 更多拦截处理方式请参考“路由拦截式鉴权”章节 }) // 异常处理函数每次认证函数发生异常时执行此函数 .setError(e - { System.out.println(---------- 进入Sa-Token异常处理 -----------); return SaResult.error(e.getMessage()); }) // 前置函数在每次认证函数之前执行BeforeAuth 不受 includeList 与 excludeList 的限制所有请求都会进入 .setBeforeAuth(r - { // ---------- 设置一些安全响应头 ---------- SaHolder.getResponse() // 服务器名称 .setServer(sa-server) // 是否可以在iframe显示视图 DENY不可以 | SAMEORIGIN同域下可以 | ALLOW-FROM uri指定域名下可以 .setHeader(X-Frame-Options, SAMEORIGIN) // 是否启用浏览器默认XSS防护 0禁用 | 1启用 | 1; modeblock 启用, 并在检查到XSS攻击时停止渲染页面 .setHeader(X-XSS-Protection, 1; modeblock) // 禁用浏览器内容嗅探 .setHeader(X-Content-Type-Options, nosniff) ; }) ; } }这段配置的完整可运行示例可在 sa-token-demo-case 的 SaTokenConfigure.java 中找到其中演示了在过滤器内按路由模块划分权限校验如/admin/**校验admin权限、/goods/**校验goods权限的写法。四个核心链式方法说明addInclude(String... paths)/setIncludeList(ListString)指定过滤器要拦截的路由支持 Ant 风格通配符例如/**、/api/**。addExclude(String... paths)/setExcludeList(ListString)指定放行路由命中放行路由的请求会跳过认证函数例如/favicon.ico、/user/doLogin。setAuth(...)认证函数命中拦截路由的每个请求都会执行是路由鉴权的主体逻辑。setError(...)异常处理函数认证函数抛出异常时执行其返回值将作为响应体字符串输出到前端。setBeforeAuth(...)前置函数在认证函数之前执行且不受 includeList 与 excludeList 的限制所有请求都会进入适合统一设置安全响应头、CORS 头等全局性操作。底层执行流程doFilter从源码看SaServletFilter实现了标准jakarta.servlet.Filter接口其doFilter核心逻辑见 SaServletFilter.java依次为无条件执行beforeAuth.run(null)前置函数全路由生效通过SaRouter.match(includeList).notMatch(excludeList).check(...)判断请求是否命中拦截范围命中则执行auth.run(null)异常分流处理StopMatchException静默吞掉继续放行对应SaRouter的停止匹配继续执行语义BackResultException直接把其中的消息作为响应体写回前端并中断过滤器链其它Throwable执行error策略把其返回值String.valueOf(...)写回前端一切通过后调用chain.doFilter(request, response)放行到后续链路。SaReactorFilterWebFlux 版本的执行流程与之一致见 SaReactorFilter.java区别在于基于WebFilter接口、返回MonoVoid并通过SaReactorSyncHolder在反应式上下文中同步存取ServerWebExchangefinally中清理上下文。测试用例佐证SaServletFilterTest.java 覆盖了过滤器的关键行为分支可帮助你快速验证上述机制doFilter_authPass_continueChainauth 通过时继续走 FilterChaindoFilter_stopMatch_continueChainauth 抛StopMatchException时吞掉异常并继续走链doFilter_backResult_writeResponseauth 抛BackResultException(blocked)时写回 blocked 并中断链路doFilter_authError_useErrorStrategyauth 抛普通异常时走setError策略写回响应doFilter_pathNotIncluded_skipAuth未命中 include 路由时跳过 auth 直接放行doFilter_pathExcluded_skipAuthButRunBeforeAuth命中 exclude 路由时跳过 auth但beforeAuth仍会执行印证前置函数不受拦截/放行限制的注释。注意事项与 setError 响应格式定制使用过滤器时有三个必须注意的点在[认证函数]里可以写与拦截器一致的代码进行路由匹配鉴权参考路由拦截鉴权拦截器中的SaRouter.match系列写法可原样搬入setAuth。由于过滤器中抛出的异常不会进入 Spring 全局异常处理组件你必须提供[异常处理函数]来处理[认证函数]里抛出的异常否则异常会以默认方式向外传播。在[异常处理函数]里的返回值会作为字符串直接输出到前端如果需要定制化返回数据如统一的 JSON 格式请注意其中的格式转换。改写setError返回 JSON 格式的示例.setError(e - { // 设置响应头 SaHolder.getResponse().setHeader(Content-Type, application/json;charsetUTF-8); // 使用封装的 JSON 工具类转换数据格式 return JSONUtil.toJsonStr( SaResult.error(e.getMessage()) ); })这里用JSONUtilHutool 的 JSON 工具类将SaResult.error(...)序列化为 JSON 字符串输出。实际项目中也可以使用 Fastjson、Jackson 等任意 JSON 序列化工具只需保证setError返回一个符合前端约定的字符串即可。自定义过滤器执行顺序SaServletFilter类上标注了Order(SaTokenConsts.ASSEMBLY_ORDER)即默认执行顺序为-100该常量定义在 SaTokenConsts.java源码注释明确说明这样设计是为了尽量保证在其它过滤器之前执行。如果你需要调整执行顺序可以使用 Spring 的FilterRegistrationBean手动注册/** * 注册 [Sa-Token 全局过滤器] */ Bean public FilterRegistrationBeanSaServletFilter getSaServletFilter() { FilterRegistrationBeanSaServletFilter frBean new FilterRegistrationBean(); frBean.setFilter( new SaServletFilter() .addInclude(/**) .setAuth(obj - { // .... }) // 等等其它代码 ... ); frBean.setOrder(-101); // 更改顺序为 -101 return frBean; }在 SpringBoot 中Order 值越小执行时机越靠前。需要根据业务调整过滤器链顺序例如希望 Sa-Token 鉴权在某个自定义过滤器之后执行时可以据此灵活配置。在 WebFlux 中注册过滤器SaReactorFilterSpring WebFlux中不提供拦截器机制因此如果你的响应式项目需要路由鉴权功能过滤器是唯一的选择。在Spring WebFlux注册过滤器的流程与上述流程几乎完全一致只需要将过滤器类名由SaServletFilter更换为SaReactorFilter其它步骤addInclude/addExclude/setAuth/setError/setBeforeAuth均可参考前面的示例/** * [Sa-Token 权限认证] 配置类 */ Configuration public class SaTokenConfigure { /** * 注册 [Sa-Token全局过滤器] */ Bean public SaReactorFilter getSaReactorFilter() { return new SaReactorFilter() // 其它代码... ; } }SaReactorFilter在源码中实现了org.springframework.web.server.WebFilter接口并同样带有Order(SaTokenConsts.ASSEMBLY_ORDER)默认-100注解。关于 WebFlux 环境下的更多接入细节可参考 sa-token-reactor-spring-boot-starter 模块及其测试 SaReactorFilterTest.java。小结Sa-Token 全局过滤器是拦截器方案之外的另一条路由鉴权路径SaServletFilterServlet 体系与SaReactorFilterWebFlux 体系都遵循拦截/放行路由 前置函数 认证函数 异常处理函数的统一模型默认执行顺序-100保证鉴权尽可能前置。选择建议需要拦截静态资源、要求执行时机最靠前或框架本身没有拦截器如 WebFlux时优先使用过滤器需要基于HandlerMethod做方法级处理或希望异常进入全局ExceptionHandler时则使用拦截器路由拦截鉴权。两种机制可以共存Sa-Token 的设计是让开发者按实际业务自由组合。【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表