java - Spring security:激活 csrf 保护会破坏其他功能
问题描述
我正在使用 Spring Security 5.0.13,我想为登录页面激活 csrf 保护。我正在使用 xml 配置,我从
<http>
...
<csrf disabled="true"/>
</http>
至
<bean id="csrfMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg name="pattern" value="/j_spring_security_check"/>
<constructor-arg name="httpMethod" value="POST"/>
</bean>
<csrf request-matcher-ref="csrfMatcher" />
然而, j_spring_security_logout
端点现在需要一个POST
请求,而它曾经接受一个GET
请求。我知道请求注销按钮会更好POST
,但我不能破坏这个功能,因为它在我控制之外的其他地方使用。
如何在不影响注销 url 动词的情况下激活登录页面的 csrf 保护?
解决方案
CSRF 保护要求您为所有导致更改的请求发送包含 CRSF 属性值的隐藏输入。这就是保护你的东西——这个 CSRF 属性是由你的服务器生成的,因此不能通过从你网站之外的其他地方发送请求来伪造。
您只能在带有post
请求的表单内发送隐藏的输入,因此如果您想要 csrf,您将需要使用post
. 好消息是 - 这很容易,大多数模板引擎会自动为您设置一切。
使用 Thymeleaf,您甚至不需要更改任何内容,它会自动在您的发布请求中生成此属性。
使用 Mustache,您需要添加以下属性:
spring.mustache.expose-request-attributes=true
然后使用以下形式:
<form id="logoutForm" method="POST" action="/logout">
<input type="hidden" name="_csrf" value="{{_csrf.token}}"/>
<button type=submit>Logout</button>
</form>
正如您所看到的,这确实相对容易,但是您必须将隐藏的 crsf.token 值添加到每个发布请求中,具体实现取决于您的模板引擎,就像我对 thymeleaf 所说的那样,您无需担心。