如何禁用我网站中特定页面的 csrf 保护?

Posted

技术标签:

【中文标题】如何禁用我网站中特定页面的 csrf 保护?【英文标题】:How to disable csrf protection for particular pages in my website? 【发布时间】:2019-11-25 03:56:45 【问题描述】:

使用了 CSRF 保护,因此来自其他网站的任何请求都不会影响我的网站造成伤害。 spring security csrf文档中说csrf是用于put post patch delete请求的。

但据我了解,登录/注册表单不需要 csrf 保护,因为它们已经需要用户名和密码形式的凭据,即使这样的请求是从另一个网站发出的,也不会有任何危害,因为用户将刚刚登录。

但是由于登录通常是一个post请求,所以spring默认会在这里自动应用csrf。这意味着我需要将 csrf 令牌生成参数作为隐藏输入字段添加到我的表单中,如下所示:

<form th:action="@/login" method="post">    
    <fieldset>
        <input type="hidden" 
             th:name="$_csrf.parameterName" 
             th:value="$_csrf.token" />
    </fieldset>
    ...
</form>

如果我不添加这个,就会出现 403 Forbidden 错误。但是如果我像这样禁用这个 csrf ..:

@Override
protected void configure(HttpSecurity http) throws Exception 
    http.csrf().disable();

然后网站中的所有页面都失去了csrf保护。如何将 csrf 应用于某些页面而不是其他页面,即使他们正在发出发布请求?

我正在使用 Spring Boot + Spring Security + thymeleaf

【问题讨论】:

【参考方案1】:

您可以在configure(HttpSecurity http) 中使用.csrf().ignoringAntMatchers("/login")

csrf().ignoringAntMatchers("String")

允许指定不应使用 CSRF 保护的 HttpServletRequest,即使它们与 requireCsrfProtectionMatcher(RequestMatcher) 匹配。

例如,下面的配置将确保 CSRF 保护 忽略:

任何 GET、HEAD、TRACE、OPTIONS(这是默认设置) 我们还明确声明忽略任何以“/sockjs/”开头的请求
    http
          .csrf()
              .ignoringAntMatchers("/sockjs/**")
              .and()
          ...

.csrf().ignoringRequestMatchers(requestMatchers)

允许指定不应使用 CSRF 的 HttpServletRequests 保护即使它们匹配 需要CsrfProtectionMatcher(RequestMatcher)。

例如,下面的配置将确保 CSRF 保护 忽略:

任何 GET、HEAD、TRACE、OPTIONS(这是默认设置) 我们还明确声明忽略任何具有“X-Requested-With: XMLHttpRequest”标头的请求
http
     .csrf()
         .ignoringRequestMatchers(request -> "XMLHttpRequest".equals(request.getHeader("X-Requested-With")))
         .and()

【讨论】:

以上是关于如何禁用我网站中特定页面的 csrf 保护?的主要内容,如果未能解决你的问题,请参考以下文章

如何仅在某些情况下禁用 Django 的 csrf 保护?

Spring Boot - Spring Security CSRF 保护未在登录页面中注入令牌

在 ajax 提交时禁用 symfony 2 csrf 令牌保护

Codeigniter CSRF 问题

Springs CSRF 保护 HTML *only* 登录页面

Wordpress 在特定页面/帖子上禁用插件