[spring-projects/spring-boot]使用属性 security.enable-csrf 禁用 CSRF

2024-04-29 886 views
3
概括

我想通过设置 活动应用程序.propertiesfalse文件中的属性来禁用 CSRF 安全性。security.enable-csrf

实际行为

根据官方文档,默认情况下启用此安全性。要禁用它,您必须在org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)with中指定它

http.csrf().disable();

或 xml 配置中的等效项。

预期行为

该变量被 Spring Boot 视为公共属性security.enable-csrf之一,但将其设置为 false 并不能解决任何问题。

配置

在我的application.yml中我有这个部分

---
spring:
  profiles: dev

security.enable-csrf: false

但将配置文件设置为dev不会禁用 CRSF 安全性

版本

我在用spring-security-config-4.2.2.RELEASE

可能的解决方案

我通过在我的实现中指定WebSecurityConfigurerAdapter以下代码轻松解决了这个问题:

@Order(FRONTEND_SECURITY_ORDER)
@EnableAspectJAutoProxy
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    public static final int FRONTEND_SECURITY_ORDER
            = SecurityProperties.ACCESS_OVERRIDE_ORDER + 3;

    @Value("${security.enable-csrf}")
    private boolean csrfEnabled;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if (!csrfEnabled) {
            http.csrf().disable();
        }

        http
                .httpBasic()
                //..... etc
    }
}

security.enable-csrf如果该属性设置为 ,这将禁用 csrf 安全性false。可以使用等效的方法来解决。

回答

8

@EliuX 你使用什么版本的 Spring Boot?对于 2.0,我们对用户自定义安全配置的方式进行了一些更改。要关闭 Spring Boot 的默认安全配置,您需要添加自己的安全配置WebSecurityConfigurerAdapter并在那里禁用 csrf。

2

如果您希望我们查看此问题,请提供所需的信息。如果在接下来的 7 天内未提供信息,此问题将被关闭。

6

@mbhave

我使用springboot v1.4.2.RELEASE,也遇到了这个问题。在应用程序中设置“security.enable-csrf: false”。属性不会有帮助。

添加我自己的 WebSecurityConfigurerAdapter (如 @EliuX)后,出现异常 org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter' available: expected single matching bean but found 2: webSecurityConfig,defaultWebSecurityConfigurer

你能给点建议吗?谢谢您的帮助。

9

@shenxiusi 如果您有自己的问题,请在 Stack Overflow 上提问。

4

对我来说也一样spring-boot 1.5.9

3

我无法在 1.5.9 上重现此问题。默认情况下,csrfSecurityProperties.要启用它,security.enable_csrf可以设置为true

请注意,在 1.5.x 中,执行器端点具有单独的安全配置,并且上述标志不会影响执行器的 CSRF。

如果需要重新讨论该问题,请提供一个可重现该问题的小样本。

1

回复晚了非常抱歉。我正在使用 Spring Boot 1.5.2.RELEASE。 @shenxiusi 可能你有 2 个继承自 的 beans org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,你应该只保留一个,就是这样。根据 @mbhave 的说法,对于 1.5.9 这样的版本,这个问题已经修复了。所以csrf默认是禁用的,通过属性激活它security.enable_csrf是有效的。因此迁移到新版本将解决这个问题。

8

刚刚偶然发现这个问题。我对 1.5.9 中是否默认禁用 CSRF 感到困惑。 1.5.9 的文档明确提到它默认启用:

Spring Security 提供的常见低级功能(HSTS、XSS、CSRF、缓存)默认处于启用状态。

https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/

然而,再往下我们发现:

security.enable-csrf=false # Enable Cross Site Request Forgery support.

这似乎意味着 csrf 设置默认设置为 false。

根据 @mbhave 的评论,它已被禁用,这也符合我的经验吗?请澄清这个问题并可能更新 1.5.9 的文档吗?

谢谢。

4

最新的 1.5.11 快照中不存在这种差异,因为 的默认值security.enable-csrf已更改为 true 以匹配 Spring Security 默认值。

1

感谢您的澄清。更改默认值是否不被视为重大更改,对于补丁级别版本(例如)来说这没有问题吗.11?当我偶然发现这个问题时,是因为当我从 Spring Boot 的自动配置切换到手动配置的 Spring Security 配置时测试失败。 Spring Boot 的 CSRF 默认为 false,但 Spring security 默认启用它,所以我的测试最初失败,直到我添加csrf().disabled()到配置中。

如果您打算进行此更改,请考虑在测试中的某个位置添加一个大警告,以便人们在 Spring Boot 文档中搜索 CSRF 时可以轻松找到(无论如何,文档中只出现了几次) 。

4

这是一个重大变化,但这样做是为了加强安全性。在这种情况下,Boot 坚持 Spring Security 的默认值是有意义的,如果人们想要带有标志的值,很容易将其翻转回来。

因为当我从 Spring Boot 的自动配置切换到手动配置的 Spring Security 配置时测试失败。 Spring Boot 的 CSRF 默认为 false,但 Spring security 默认启用它

情况不应该是这样,1.5.11.BUILD-SNAPSHOTS因为 Spring Boot 和 Spring Security 的 CSRF 默认值是相同的。

对于它的文档部分,我在这里添加了一个新问题。

9

.csrf.disable() 不工作 Spring Boot 3.0.4

下面是我的安全配置

package meetona.infrastructure.config;

import lombok.extern.slf4j.Slf4j;
import meetona.infrastructure.security.AuthEntryPoint;
import meetona.infrastructure.security.AuthenticationManager;
import meetona.infrastructure.security.JwtAuthFilter;
import meetona.infrastructure.security.SecurityContextRepository;
import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.reactive.CorsConfigurationSource;

@Slf4j
@EnableWebFluxSecurity
@Configuration
@EnableReactiveMethodSecurity
public class SecurityConfig {

    protected static final String[] ACTUATOR_WHITELIST = {
            "/actuator/**",
            "/health/**",
            "/health"
    };

    protected static final String[] SWAGGER_WHITELIST = {
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/swagger-ui.html",
    };

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(
            ServerHttpSecurity http,
            JwtAuthFilter jwtAuthFilter,
            AuthEntryPoint authEntryPoint,
            AuthenticationManager authenticationManager,
            SecurityContextRepository securityContextRepository,
            CorsConfigurationSource corsConfigurationSource
    ) {
        return http
                .exceptionHandling()
                .authenticationEntryPoint(authEntryPoint)
                .and().csrf().disable()
                .authenticationManager(authenticationManager)
                .securityContextRepository(securityContextRepository)
                .authorizeExchange(auth -> auth
                        .matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                        .pathMatchers("/auth/**").permitAll()
                        .pathMatchers(SWAGGER_WHITELIST).permitAll()
                        .pathMatchers(ACTUATOR_WHITELIST).permitAll()
                        .anyExchange().authenticated()
                )
                .addFilterAt(jwtAuthFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                .cors().configurationSource(corsConfigurationSource)
                .and()
                .build();
    }
}
5

@emmysteven 由于这个问题已经很老了并且已经有很多评论,您能开一个新的吗?请提供一个示例应用程序,我们可以运行它来诊断问题。