首页 > 解决方案 > 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 保护?

标签: javaspringspring-securitycsrf

解决方案


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 所说的那样,您无需担心。


推荐阅读