如何让pac4j的CSRF等匹配器作用于Play框架v3所有请求
解决Pac4j v6 + Play v3中CSRF匹配器仅在/auth路径生效的问题
以下是针对性的排查和修复步骤:
1. 全局绑定CSRF匹配器与授权器
确保在SecurityConfig类中,将CSRF相关的匹配器/授权器应用到所有请求路径,而非仅回调路径:
public class SecurityConfig extends PlaySecurityConfigFactory { @Override protected void configureClients() { // 注册你的客户端(FormClient等) var formClient = new FormClient("/login", new SimpleTestUsernamePasswordAuthenticator()); addClient(formClient); // 注册CSRF匹配器和授权器 addMatcher("csrf", CsrfMatcher.INSTANCE); addAuthorizer("csrf", CsrfAuthorizer.INSTANCE); } @Override protected void configureSecurity() { // 对所有路径应用CSRF规则,优先级高于客户端特定规则 securityRule("/**", SecurityRule.ALL, "csrf,csrf"); // 保留原有的登录/注册/登出路径规则(如果需要) securityRule("/login", SecurityRule.ALL, "formClient"); securityRule("/logout", SecurityRule.ALL, "logout"); } @Override protected void configure(HttpActionAdapter httpActionAdapter) { setHttpActionAdapter(new CustomHttpActionAdapter()); } }
2. 确保Play过滤器全局生效
检查application.conf中的过滤器配置,确保SecurityFilter无路径限制且优先级正确:
# 启用Pac4j安全过滤器 play.filters.enabled += org.pac4j.play.filter.SecurityFilter # 不要设置路径限制,确保过滤器拦截所有请求 # 移除类似 play.filters.securityFilter.paths = ["/auth/*"] 的配置
3. 修复自定义HttpActionAdapter的响应处理
自定义的HttpActionAdapter需要正确处理CSRF相关的HTTP动作,确保所有请求都能返回CSRF响应头:
public class CustomHttpActionAdapter implements HttpActionAdapter<Result, PlayWebContext> { @Override public Result adapt(HttpAction action, PlayWebContext context) { // 处理CSRF错误动作,返回包含CSRF Token的响应头 if (action instanceof CsrfErrorAction) { String csrfToken = CsrfTokenGenerator.getInstance().getToken(context); return Results.badRequest() .withHeader("X-CSRF-Token", csrfToken) .withHeader("Content-Type", "application/json") .body("{\"error\": \"CSRF token invalid or missing\"}"); } // 处理其他动作(如登录成功、权限不足等) if (action instanceof RedirectAction redirectAction) { return Results.redirect(redirectAction.getLocation()); } // 兜底调用默认处理逻辑 return new DefaultHttpActionAdapter().adapt(action, context); } }
4. 验证匹配器执行流程
- 调高Pac4j日志级别到DEBUG,查看匹配器是否在所有请求中触发:
在logback.xml中添加:<logger name="org.pac4j.core.matcher" level="DEBUG"/> <logger name="org.pac4j.play.filter" level="DEBUG"/> - 检查日志输出,确认每个请求都有
CsrfMatcher的执行记录,而非仅回调路径。
5. 排除路径排除规则
检查是否在安全配置中不小心排除了某些路径,比如使用excludePath()方法导致部分请求跳过CSRF验证:
// 确保没有类似以下的排除规则 // excludePath("/api/**");
内容的提问来源于stack exchange,提问作者Mohammad Asy
相关产品推荐
相关产品推荐

