Spring Security配置permitAll仍触发access-denied-handler问题排查
Spring Security 6.2.4 所有请求跳转到拒绝访问页面的原因解析
问题场景
我在applicationContext-security.xml里配置了<http>标签,设置允许所有请求路径通过,具体配置如下:
<global-method-security pre-post-annotations="enabled"> </global-method-security> <http auto-config="true" use-expressions="true"> <intercept-url pattern="/**" access="permitAll" /> <custom-filter position="PRE_AUTH_FILTER" ref="webSEALFilter" /> <custom-filter after="PRE_AUTH_FILTER" ref="myFilter"/> <access-denied-handler error-page="/error/abc"/> <logout invalidate-session="true" logout-success-url="/" logout-url="/logout"/> <session-management invalid-session-url="${${ENV}.login.url}"> <concurrency-control expired-url="${${ENV}.login.url}" /> </session-management> </http> <beans:bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
但实际所有请求(比如http://localhost:8080/SLIS/message/getNonExpiredMessage/0/1、http://localhost:8080/SLIS/adminAnnouncement)都会跳转到配置的access-denied-handler对应的页面,控制台还报出以下错误:
[org.springframework.web.servlet.PageNotFound] (default task-3) No mapping for POST /SLIS/error/abc
[org.springframework.web.servlet.PageNotFound] (default task-3) No endpoint POST /SLIS/error/abc.
使用的是Spring Security 6.2.4版本,这是什么原因?
补充信息
目前还没完全搞懂根因,但在<http>标签里加上这段配置后,问题就消失了:
<csrf disabled="true"/>
原因解析
其实核心原因是CSRF校验失败触发了访问拒绝,具体逻辑是这样的:
- Spring Security 6.x版本默认开启了CSRF防护,对于POST、PUT、DELETE这类非安全请求,会强制校验请求里的CSRF令牌是否有效。
- 你的请求(比如POST类型)没有携带合法的CSRF令牌,Spring Security直接判定请求非法,跳过后续的权限校验(哪怕你配置了
permitAll),直接触发访问拒绝逻辑,跳转到/error/abc。 - 而你并没有在项目里配置
/error/abc的POST请求映射,所以控制台才会出现找不到POST端点的报错。 - 当你添加
<csrf disabled="true"/>关闭CSRF防护后,这类校验被跳过,请求自然就能正常通过了。
内容的提问来源于stack exchange,提问作者user1169587
相关产品推荐
相关产品推荐

