【问题标题】:Spring security: activating csrf protection breaks other functionalitySpring security:激活 csrf 保护会破坏其他功能
【发布时间】:2020-12-02 12:20:03
【问题描述】:

我正在使用 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 保护?

【问题讨论】:

    标签: java spring spring-security csrf


    【解决方案1】:

    根据Spring Security reference docs,可以修改Spring Security如何匹配/logout端点。默认情况下,它会查找POST /logout,但您可以将其配置为查找GET /logout

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) {
            http
                // ... other configs
                .logout(logout -> logout
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
                );
        }
    }
    

    没有通过&lt;logout&gt; 元素直接等效的XML,尽管您可以声明自己的LogoutFilterregister it 类型的&lt;bean&gt;。或者logging a ticket 可能是将其添加到&lt;logout&gt; 的选项。

    【讨论】:

    • 谢谢。 xml 配置等效项是什么?
    • 我已经用有关 XML 配置的详细信息编辑了我的答案。
    【解决方案2】:

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

    【讨论】:

    • 很遗憾,这并没有回答我的问题。正如我所说,我不能切换到 POST 方法,因为 GET 在其他地方使用。不过,我仍然希望能够保护登录表单。
    • 我该如何向您解释:a) 如果没有此信息,则无法使用 GET b) 发送信息(csrf 令牌)没有 CSRF 保护你不能坐在两把椅子上,你不能在 2 场婚礼上跳舞,你不能一边吃蛋糕一边吃,而且你不能只用 GET 请求来获得 CSRF 保护
    • 你没有理解这个问题。我有 2 个端点,登录和注销。目前,没有一个是安全的。我想保护登录端点,而不影响注销端点的动词。请再次阅读问题。
    猜你喜欢
    • 2016-01-12
    • 2020-05-09
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2016-09-01
    • 2014-09-15
    • 2015-03-28
    相关资源
    最近更新 更多