禁用 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 在特定环境(如 dev
或 test
环境)中禁用 Security。
创建一个新的特定于 Profiles 的属性文件,例如 application-dev.properties
,并添加以下一行:
server.port= 8080
spring.profiles.active=dev
spring.application.name=spring-security-noauth-profile
现在,创建名为 DevSecurityConfiguration
的配置类。该类仅在 Profiles 为 dev
时生效。它允许不受限制地访问所有端点,允许所有请求。这在开发阶段非常有用,可以在没有安全限制的情况下简化测试和调试:
@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 端点时,会看到下面的响应:
我们可以通过使用 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 的不同而有不同的表现。
Pofiles 为 dev
时的单元测试:
@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