按属性禁用CSRF保护

时间:2015-10-22 07:50:15

标签: spring web-applications spring-security

Spring安全性提供了一种XML方法,通过将{item: {id:1}, customer: {id:1}}标记应用于<csrf />元素配置来配置CSRF保护。

出于开发目的,我偶尔会关闭此类保护。通常我会修改我的<http>文件并更改为security-context.xml

我尝试使用<csrf disabled="true">之类的表达式,但它无效,因为XML架构只接受原始布尔值。

我不想使用整个bean配置文件(对于整个<csrf disabled="${someProperty:false}" />元素)只是为了一个必须有时打开/关闭的参数。

有什么建议吗?

其他信息

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

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

2 个答案:

答案 0 :(得分:2)

使用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;
  }
}

答案 1 :(得分:2)

因为我偶然发现了同样问题的问题,我想补充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,则会保留默认行为。