Spring Boot 2.0 禁用默认安全

Spring Boot 2.0 disable default security

我想使用 Spring 安全性进行 JWT 身份验证。但它带有默认身份验证。我正在尝试禁用它,但是执行此操作的旧方法 - 通过 application.properties 禁用它 - 在 2.0.

中已弃用

这是我试过的:

@Configuration
public class StackWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().disable();
        // http.authorizeRequests().anyRequest().permitAll(); // Also doesn't work.
    }
}

我怎样才能简单地禁用基本安全?

更新
很高兴知道我使用的不是 web mvc 而是 web flux。

截图:

我认为您正在寻找的是覆盖设置为 BasicAuthenticationEntryPoint.

的默认身份验证入口点

这个入口点添加了

"WWW-Authenticate": "Basic realm=..."

header 告诉您的浏览器使用基本身份验证。

According to the reference documentation,允许所有 WebFlux 请求的安全配置应如下所示:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange().anyExchange().permitAll();
        return http.build();
    }
}

这对我有用:

@Configuration
public class SecurityConfig  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests().anyRequest().permitAll();
    }
}

根据 Spring 2.0 中的新更新,如果 Spring Security 在类路径中,Spring Boot 将添加 @EnableWebSecurity.So 添加条目到 application.properties 不会工作(即它不再以这种方式可定制)。欲了解更多信息,请访问官方网站 Security changes in Spring Boot 2.0

虽然不确定您的要求,但我可以想到如下解决方法:-

@Configuration
@EnableWebSecurity
public class SecurityConfiguration  extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeRequests().antMatchers("/").permitAll();
    }
}

希望对您有所帮助。

您可以add/modify您的申请class:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class MyApplication {

}

在 Spring 引导 2 中,无法通过 application.properties 文件禁用基本身份验证。但唯一的事情是使用注释

@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class})

主要class。 有效

添加一些新的答案,我假设所有人都使用执行器,如果不是,我敢打赌一个 class 排除应该足够了,我设法通过属性禁用:

spring:
  autoconfigure:
    exclude: ${spring.autoconfigure.sac}, ${spring.autoconfigure.mwsas}
    sac: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
    mwsas: org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration

我通过 属性 引用了两个自动配置 classes 以保持长度不变(请注意,如果你这样引用它,IntelliJ Ultimate 会哭,因为它不知道是什么这些占位符值,如果它们实际上是合法的 classes,那么内联如果这让你烦恼)。

然而,应用程序不会像以下声明的那样无法启动:

https://www.baeldung.com/spring-boot-security-autoconfiguration

如果你只是禁用 SecurityAutoConfiguration

如果它确实有效,您将不再看到自动生成的密码,并且它比接受的答案更容易混淆,因为读取日志的开发人员不会被生成的基本身份验证密码所混淆,而安全允许所有.

为什么仅仅禁用主自动配置 class 是不够的,因为这个家伙:

@Configuration
class ManagementWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .requestMatchers(
                        EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class))
                .permitAll().anyRequest().authenticated().and().formLogin().and()
                .httpBasic();
    }

}

为了拆分执行器和安全配置,我们做了很多工作,这让我们所有人都感到困惑,现在它更简单了,但像这样的工件仍然存在。 Spring 如果我错了,开发者会纠正我:-)。

从SpringBoot 2.1开始,如果包含spring-boot-actuator,只排除SecurityAutoconfiguration已经不够了,还需要排除ManagementWebSecurityAutoConfiguration,像这样:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })

问题出在 org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter

它有private ServerAuthenticationEntryPoint authenticationEntryPoint = new HttpBasicServerAuthenticationEntryPoint();

因此要在 ServerHttpSecurity 初始化期间修复它,请添加:

http.exceptionHandling().authenticationEntryPoint(HttpStatusServerEntryPoint(HttpStatus.FORBIDDEN))

看起来像 vanilla (servlet) spring 使用 org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer#createDefaultEntryPoint

private AuthenticationEntryPoint createDefaultEntryPoint(H http) {
        if (this.defaultEntryPointMappings.isEmpty()) {
            return new Http403ForbiddenEntryPoint();
        }
        if (this.defaultEntryPointMappings.size() == 1) {
            return this.defaultEntryPointMappings.values().iterator().next();
        }
        DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(
                this.defaultEntryPointMappings);
        entryPoint.setDefaultEntryPoint(this.defaultEntryPointMappings.values().iterator()
                .next());
        return entryPoint;
    }

旁注:构建器样式 bean 中的可变字段(如 ExceptionTranslationWebFilter)使 spring 代码难以调试(配置太神奇)

如果您要扩展 WebSecurityConfigurerAdapter,您可以将 true 传递给超级构造函数以禁用默认值。
如果这样做,您可能需要提供其他 bean。

    /**
     * Creates an instance which allows specifying if the default configuration should be
     * enabled. Disabling the default configuration should be considered more advanced
     * usage as it requires more understanding of how the framework is implemented.
     *
     * @param disableDefaults true if the default configuration should be disabled, else
     * false
     */
    protected WebSecurityConfigurerAdapter(boolean disableDefaults) {
        this.disableDefaults = disableDefaults;
    }

如果您只是为了测试目的而禁用它 - 我没有完全禁用自动配置,而是在 "SecurityConfiguration" 之外创建了一个 "InsecurityConfiguration",并使用 Spring 配置文件或 属性 值激活它。

从技术上讲,安全性仍处于配置状态,但完全开放。

@Configuration
@ConditionalOnProperty(prefix = "security", value = "disabled", havingValue = "true")
public class InsecurityConfiguration extends WebSecurityConfigurerAdapter {

    private final static Logger log = LoggerFactory.getLogger(InsecurityConfiguration.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        log.warn("configuring insecure HttpSecurity");
        http.authorizeRequests().anyRequest().permitAll();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        log.warn("configuring insecure WebSecurity");
        web.ignoring().antMatchers("/**");
    }

}

注意这是针对mvc的,不是webflux。对于 Webflux,您应该像 Bryan 提到的那样创建一个 SecurityWebFilterChain

这就是我在使用 JWT 时通常在 webflux 中禁用基本身份验证的方式 -

    @Bean
    public SecurityWebFilterChain configure(ServerHttpSecurity http) {

        http
        .authorizeExchange().anyExchange().authenticated().and()
            .httpBasic().disable()
            .formLogin().disable()
            .logout().disable()
            .oauth2ResourceServer()
            .jwt()
            .and()
                .and().exceptionHandling().accessDeniedHandler(problemSupport);
        return http.build();
    }

如果有人在基于 WebFlux 的应用程序或 Spring 云网关应用程序中遇到这个问题,以下对我有用:

@EnableWebFluxSecurity
public class InsecurityConfiguration {
    // @formatter:off
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
         http
              .authorizeExchange()
                   .anyExchange().permitAll();
         return http.build();
    }
}

如果我在 application.yml 中将 spring.security.enabled 属性 设置为 false,我将利用 @ConditionalOnProperty 加载以下 SecurityConfig.java class禁用 spring 安全性,它就像一个魅力。

@ConditionalOnProperty(name = "spring.security.enabled", havingValue = "false")
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests().antMatchers("/").permitAll();
    }
}

要禁用 Spring Boot Reactive Web 应用程序的默认安全性,请在类路径中也有执行器时使用以下排除项。

@SpringBootApplication(exclude = {ReactiveSecurityAutoConfiguration.class, ReactiveManagementWebSecurityAutoConfiguration.class })

您应该添加 @EnableWebSecurity 以启用自定义安全配置。 之后只需禁用表单登录

@Configuration
@EnableWebSecurity
public class StackWebSecurityConfigurerAdapter extends 
WebSecurityConfigurerAdapter {
 @Override
 protected void configure(HttpSecurity http) throws Exception {
    http.formLogin().disable();
 }

}