禁用 Spring Security

1、概览

Spring Security 是一个功能强大、高度可定制的 Java 应用身份认证和访问控制框架。本文将带你了解 Spring Security 的基本概念,以及一些可能需要禁用它的常见场景,例如在 开发测试使用自定义安全机制 时。

2、禁用 Spring Security

我们可以通过多种方式禁用 Spring Security:

  • 使用自定义安全(Security)配置
  • 利用 Spring Profile
  • 移除 Spring Security 依赖
  • 排除 Spring Security 自动配置

先通过 Spring Initializr 创建一个基于 Maven 的最小 Spring Boot 项目,其中包含一个 Controller,作为我们的测试端点:

@RestController
@RequestMapping("/api")
public class PublicController {
    @GetMapping("/endpoint")
    public ResponseEntity<String> publicEndpoint() {
        return ResponseEntity.ok("This is a public endpoint.");
    }
}

3、使用自定义 Security 配置

禁用 Spring Security 的最直接方法之一就是创建自定义 Security 配置类。这种方法包括定义和配置 SecurityFilterChain Bean,以允许所有未经身份验证的请求:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
      .csrf(AbstractHttpConfigurer::disable);
    return http.build();
}

4、利用 Spring Profiles

Spring Profiles 允许我们为应用配置不同的环境。我们可以使用 Profiles 在特定环境(如 devtest 环境)中禁用 Security。

创建一个新的特定于 Profiles 的属性文件,例如 application-dev.properties,并添加以下一行:

server.port= 8080
spring.profiles.active=dev
spring.application.name=spring-security-noauth-profile

现在,创建名为 DevSecurityConfiguration 的配置类。该类仅在 Profilesdev 时生效。它允许不受限制地访问所有端点,允许所有请求。这在开发阶段非常有用,可以在没有安全限制的情况下简化测试和调试:

@Profile("dev")
public class DevSecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
        return http.build();
    }
}

除上述配置外,我们还要定义另一个 Security 配置类,在非 dev Profiles 时激活。该配置可启用身份验证,并允许对所有端点进行受限访问:

@Profile("!dev")  // 非 dev 环境下生效
public class SecurityConfiguration {
    @Bean
    SecurityFilterChain httpSecurity(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
          .formLogin(withDefaults())
          .httpBasic(withDefaults());

        return http.build();
    }
}

当应用运行在 dev Profiles 时,将允许所有请求而无需身份验证。但是,当应用运行在所有非 dev Profiles 环境下时,应用就会对任何类型的请求进行身份认证。

5、移除 Spring Security 依赖

禁用 Spring Security 的最简单方法是从项目中移除其依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>...</version>
</dependency>

移除该依赖后,应用中的所有 Spring Security 功能都将消失。

6、排除 Spring Security 自动配置

当我们在 classpath 中包含 spring-boot-starter-security 时,Spring Boot 会自动配置 Security。要禁用它,可通过在 application.properties 中添加以下属性来排除自动配置:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

如果我们想完全禁用 Spring Security,则应使用 spring.autoconfigure.exclude,而无需创建 SecurityConfiguration 类。手动配置 Spring Security 类会覆盖 application.properties 配置,因此当两者同时使用时,application.properties 中的排除不会产生任何影响。

7、测试

我们可以通过启动应用并在本地访问端点来验证是否已禁用 Security。

启动并运行 Spring boot 应用,当我们尝试访问 REST 端点时,会看到下面的响应:

Spring boot 200 响应

我们可以通过使用 MockMvc 库编写 JUnit 测试,以编程方式验证是否禁用了 Security。

7.1、测试 Security Configuration

如下,验证 Security Configuration 是否允许不受限制的访问:

public class CommonSecurityConfigTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void whenSecurityIsDisabled_thenAllEndpointsAreAccessible() throws Exception {
        mockMvc.perform(get("/api/endpoint"))
          .andExpect(status().isOk());
    }
}

7.2、测试 Profiles

我们编写了两个独立的测试,以验证我们的 Security 是否会根据激活的 Pofiles 的不同而有不同的表现。

Pofilesdev 时的单元测试:

@ActiveProfiles("dev")
public class DevProfileSecurityConfigTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void whenDevProfileIsActive_thenAccessIsAllowed() throws Exception {
        mockMvc.perform(get("/api/endpoint"))
          .andExpect(status().isOk());
    }
}

Pofiles 为非 dev 时的单元测试:

public class NonDevProfileSecurityConfigTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void whenNonDevProfileIsActive_thenAccessIsDenied() throws Exception {
        mockMvc.perform(get("/api/endpoint"))
          .andExpect(status().isUnauthorized());
    }
}

8、总结

本文介绍了在开发和测试阶段中禁用 Spring Security 的各种方法,包括使用自定义 Security Configuration 以及利用 Spring Profiles。


Ref:https://www.baeldung.com/spring-security-deactivate