注册页PrimeFaces commandButton AJAX失败后Spring Security出现302重定向问题
问题排查与解决方案
问题根因
这个问题通常是以下原因叠加导致的:
- 首先确认页面上的CSRF隐藏字段是否正确渲染:右键查看注册页源码,确认
<input type="hidden">的name和value属性是否正确填充了CSRF参数名和令牌值,若EL表达式${_csrf.parameterName}、${_csrf.token}未解析,会导致首次提交就没有携带合法CSRF令牌,触发校验失败 - 若首次提交是业务逻辑报错导致的失败,Spring Security会刷新CSRF令牌,但你的AJAX更新逻辑没有更新页面上存储的CSRF令牌隐藏字段,导致第二次提交携带了已失效的旧令牌
- 旧令牌触发CSRF校验失败,结合你配置的form-login规则,未认证状态下的403错误会返回302重定向到登录页
具体修复方案
方案1:调整AJAX更新范围,包含CSRF字段
你当前的<p:commandButton>的update属性仅更新了表单内的表格区域,CSRF隐藏字段在form根节点下,不在更新范围内,修改update属性,将表单也纳入更新范围:
<p:commandButton id="btnSavePersonal" actionListener="#{applicantSignUpBean.signUpPersonal}" icon="fa fa-save" value="#{bundle.registration}" process=":form:applicantTab:PersonalGrid @this" <!-- 这里新增:form到update列表 --> update=":form:applicantTab:PersonalGrid :form" style="margin: 20px; width: 150px;" styleClass="button_save"> </p:commandButton>
也可以将CSRF隐藏字段套入一个单独的<p:outputPanel>,仅更新该区域即可,避免全表单更新带来的不必要性能消耗。
方案2:排查首次提交失败原因
在applicantSignUpBean.signUpPersonal方法中增加日志输出,确认是否是后端参数校验、业务逻辑报错导致的提交失败,修复后无需二次提交即可解决问题。
临时调试方案(不推荐用于生产)
如果需要快速验证是否是CSRF导致的问题,可以临时将注册页从CSRF校验规则中排除:
- 自定义请求匹配器,匹配注册页所有请求
- 修改Spring Security配置:
<csrf request-matcher-ref="excludeSignupCsrfMatcher"/>
验证步骤
修复后按以下顺序验证:
- 清空浏览器缓存,打开注册页
- 填写表单首次点击提交,查看后端日志是否正常执行注册逻辑
- 即使首次提交失败,第二次提交不会跳转登录页,仅返回对应业务错误提示即可。
内容的提问来源于stack exchange,提问作者Omid
相关产品推荐
相关产品推荐

