Spring Security 3.2 CSRF 禁用特定 URL
Posted
技术标签:
【中文标题】Spring Security 3.2 CSRF 禁用特定 URL【英文标题】:Spring Security 3.2 CSRF disable for specific URLs 【发布时间】:2014-04-26 19:06:45 【问题描述】:使用 Spring security 3.2 在我的 Spring MVC 应用程序中启用 CSRF。
我的 spring-security.xml
<http>
<intercept-url pattern="/**/verify" requires-channel="https"/>
<intercept-url pattern="/**/login*" requires-channel="http"/>
...
...
<csrf />
</http>
尝试为请求 URL 中包含“验证”的请求禁用 CSRF。
MySecurityConfig.java
@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter
private CsrfMatcher csrfRequestMatcher = new CsrfMatcher();
@Override
public void configure(HttpSecurity http) throws Exception
http.csrf().requireCsrfProtectionMatcher(csrfRequestMatcher);
class CsrfMatcher implements RequestMatcher
@Override
public boolean matches(HttpServletRequest request)
if (request.getRequestURL().indexOf("verify") != -1)
return false;
else if (request.getRequestURL().indexOf("homePage") != -1)
return false;
return true;
Csrf 过滤器验证从“验证”提交的 CSRF 令牌,并在我从 http 向 https 提交请求时抛出无效令牌异常 (403)。在这种情况下如何禁用 csrf 令牌身份验证?
【问题讨论】:
在我们尝试解决此问题之前,您为什么要使用 XML 和 JavaConfig?这可能会给您带来诸如我不确定哪个配置优先等问题。您应该选择其中之一。 使用 XML 配置将一些 URL 引导至 https,将其他 URL 引导至 http。在 XML 中添加了 CSRF 功能,但是当用户从通过 https 引导的页面提交请求时,我们遇到了问题(无效令牌)。 1. 用户登陆 http 上的页面(主页) 2. 导航到 https 上的页面(验证) 3. 从验证页面提交请求时获取 Invalid Token 异常。所以尝试在验证页面上禁用 CSRF 身份验证。 您可以使用 java 配置 http.requiresChannel() 通过 Java 配置启用通道安全性。不要同时使用 XML 和 JavaConfig 使用其中之一。我的猜测是您的 Security Java Configuraiton 没有被 XML 配置拾取或覆盖 这是一篇关于如何使用 xml 配置禁用某些 URL 的 CSRF 检查的完整博客:blogs.sourceallies.com/2014/04/… 不幸的是,它似乎不适用于我的 Spring Security 3.2 版本.8. 【参考方案1】:我知道这不是一个直接的答案,但人们(如我)在搜索这类问题时通常不会指定 spring 的版本。 所以,自从 spring security a method exists 让我们忽略一些路由:
以下将确保 CSRF 保护被忽略:
-
任何 GET、HEAD、TRACE、OPTIONS(这是默认设置)
我们还明确声明忽略任何以“/sockjs/”开头的请求
【讨论】:
在 Spring Boot 2.1.4 和 Spring Security 5.1.5 上仍然可以正常工作 可以使用 Spring Security 5.20 和 Spring MVC 5.2.0 进行验证【参考方案2】:我希望我的回答可以帮助别人。我在搜索 How to disable CSFR for specific URLs in Spring Boot 时发现了这个问题。
我使用了这里描述的解决方案: http://blog.netgloo.com/2014/09/28/spring-boot-enable-the-csrf-check-selectively-only-for-some-requests/
这是允许我在某些 URL 上禁用 CSFR 控件的 Spring Security 配置:
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
// Build the request matcher for CSFR protection
RequestMatcher csrfRequestMatcher = new RequestMatcher()
// Disable CSFR protection on the following urls:
private AntPathRequestMatcher[] requestMatchers =
new AntPathRequestMatcher("/login"),
new AntPathRequestMatcher("/logout"),
new AntPathRequestMatcher("/verify/**")
;
@Override
public boolean matches(HttpServletRequest request)
// If the request match one url the CSFR protection will be disabled
for (AntPathRequestMatcher rm : requestMatchers)
if (rm.matches(request)) return false;
return true;
// method matches
; // new RequestMatcher
// Set security configurations
http
// Disable the csrf protection on some request matches
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
.and()
// Other configurations for the http object
// ...
return;
// method configure
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
// Authentication manager configuration
// ...
它适用于 Spring Boot 1.2.2(和 Spring Security 3.2.6)。
【讨论】:
@amit 是的,它对我有用。但我也允许所有 GET 请求,如参考中的示例。我现在也更新了我的答案。【参考方案3】:我正在使用 Spring Security v4.1。经过大量阅读和测试,我使用 XML 配置禁用了特定 URL 的 CSRF 安全功能。
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<http pattern="/files/**" security="none" create-session="stateless"/>
<http>
<intercept-url pattern="/admin/**" access="hasAuthority('GenericUser')" />
<intercept-url pattern="/**" access="permitAll" />
<form-login
login-page="/login"
login-processing-url="/login"
authentication-failure-url="/login"
default-target-url="/admin/"
password-parameter="password"
username-parameter="username"
/>
<logout delete-cookies="JSESSIONID" logout-success-url="/login" logout-url="/admin/logout" />
<http-basic />
<csrf request-matcher-ref="csrfMatcher"/>
</http>
<beans:bean id="csrfMatcher" class="org.springframework.security.web.util.matcher.OrRequestMatcher">
<beans:constructor-arg>
<util:list value-type="org.springframework.security.web.util.matcher.RequestMatcher">
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/rest/**"/>
<beans:constructor-arg name="httpMethod" value="POST"/>
</beans:bean>
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/rest/**"/>
<beans:constructor-arg name="httpMethod" value="PUT"/>
</beans:bean>
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/rest/**"/>
<beans:constructor-arg name="httpMethod" value="DELETE"/>
</beans:bean>
</util:list>
</beans:constructor-arg>
</beans:bean>
//...
</beans:bean>
通过上述配置,我仅为所有以/rest/
开头的URL的POST|PUT|DELETE请求启用CSRF安全。
【讨论】:
【参考方案4】:明确禁用特定 url 模式并启用某些 url 模式。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SecurityConfig
@Configuration
@Order
public static class GeneralWebSecurityConfig extends WebSecurityConfigurerAdapter
protected void configure(HttpSecurity http) throws Exception
http.csrf().ignoringAntMatchers("/rest/**").and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/home/**","/search/**","/geo/**").authenticated().and().csrf()
.and().formLogin().loginPage("/login")
.usernameParameter("username").passwordParameter("password")
.and().exceptionHandling().accessDeniedPage("/error")
.and().sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
【讨论】:
【参考方案5】:这条简单的线暂时可以派上用场:
<http pattern="/home/test**" security="none" />
【讨论】:
security='none'
属性的唯一问题是 完全 从此 url 禁用 spring-security。【参考方案6】:
<http ...>
<csrf request-matcher-ref="csrfMatcher"/>
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
...
</http>
<b:bean id="csrfMatcher"
class="AndRequestMatcher">
<b:constructor-arg value="#T(org.springframework.security.web.csrf.CsrfFilter).DEFAULT_CSRF_MATCHER"/>
<b:constructor-arg>
<b:bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
<b:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<b:constructor-arg value="/chat/**"/>
</b:bean>
</b:bean>
</b:constructor-arg>
</b:bean>
平均数
http
.csrf()
// ignore our stomp endpoints since they are protected using Stomp headers
.ignoringAntMatchers("/chat/**")
示例来自: https://docs.spring.io/spring-security/site/docs/4.1.x/reference/htmlsingle/
【讨论】:
你忘记在 NegatedRequestMatcher 和 AntPathRequestMatcher 之间封装一个构造函数【参考方案7】:使用安全=“无”。 例如在 spring-security-config.xml 中
<security:intercept-url pattern="/*/verify" security="none" />
【讨论】:
以上是关于Spring Security 3.2 CSRF 禁用特定 URL的主要内容,如果未能解决你的问题,请参考以下文章