通过 属性 禁用 CSRF 保护

Disable CSRF protection by property

Spring security 提供了一种 XML 方法来配置 CSRF 保护,方法是将 <csrf /> 标记应用到 <http> 元素配置中。

出于开发目的,我想偶尔关闭这种保护。通常我会编辑我的 security-context.xml 文件并更改为 <csrf disabled="true">.

我尝试使用 <csrf disabled="${someProperty:false}" /> 等表达式,但它无效,因为 XML 架构只接受原始布尔值。

我不想将整个 bean 配置文件(用于整个 <http> 元素)仅用于有时必须切换的单个参数 on/off。

有什么建议吗?

附加信息

为了使用 RESTClient 针对经过身份验证的控制器执行一些单元测试(当我懒得将 JUnit 与 MockMvc 一起使用时)我都需要绕过表单身份验证(例如使用 <http-basic /> 并在凭据上指示 RESTClient ) 并禁用 CSRF,否则所有请求都将因缺少令牌而被阻止。

我的应用程序是一个 WAR 应用程序,它在设计上使用 XML 配置而不是基于代码的配置

使用 request-matcher-ref 并创建您自己的自定义 RequestMatcher。

<csrf token-repository-ref="csrfTokenRepository" request-matcher-ref="csrfRequestMatcher" />

这里是 spring bean 定义:

   <spring:bean class="com.faizalsidek.security.CsrfRequestMatcher" id="csrfRequestMatcher" />
        <spring:bean class="org.springframework.security.web.csrf.CookieCsrfTokenRepository" id="csrfTokenRepository" />

这里是自定义 CsrfRequestMatcher:

public class CsrfRequestMatcher implements RequestMatcher {

  /**
   * Enable CSRF flag.
   */
  @Value("${csrf.enabled}")
  private boolean csrfEnabled;

  @Override
  public final boolean matches(final HttpServletRequest request) {
    return csrfEnabled;
  }
}

因为我偶然发现了这个有同样问题的问题,所以我想补充 Faizal Sidek 的答案,因为他的答案删除了 Spring 安全性的默认匹配。

要在启用 csrf 时保持默认行为,您需要像这样匹配请求 HTTP 方法:

您的自定义请求匹配器:

package my.example;

import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;

public class CustomRequestMatcher implements RequestMatcher {

    private Pattern allowedMethods = Pattern.compile("^(GET|TRACE|HEAD||OPTIONS)$");

    private boolean enabled;

    public CustomRequestMatcher(boolean enabled) {
        this.enabled = enabled;
    }

    @Override
    public boolean matches(HttpServletRequest httpServletRequest) {
        return enabled && !allowedMethods.matcher(httpServletRequest.getMethod()).matches();
    }

}

然后在您的 security.xml:

中使用它
<http ...>
    <csrf request-matcher-ref="requestMatcher"/>
</http>

<beans:bean id="requestMatcher" class="my.example.CustomRequestMatcher">
    <beans:constructor-arg value="${myproperty}" />
</beans:bean>

现在,如果将 "myproperty" 设置为 false,csrf 将被禁用,但如果 "myproperty" 为 true,则会保留默认行为。