通过 属性 禁用 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,则会保留默认行为。
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,则会保留默认行为。