feat(security): 动态配置公共端点白名单

-引入 Environment 接口以获取当前激活的配置文件
-根据是否为生产环境动态设置公共端点白名单
-优化了 SecurityConfig 类中的安全过滤链配置
This commit is contained in:
ikmkj
2025-08-02 19:38:39 +08:00
parent f4851a80d3
commit 1e7285cb68

View File

@@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
@@ -17,6 +18,8 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.util.Arrays;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfig { public class SecurityConfig {
@@ -33,6 +36,9 @@ public class SecurityConfig {
@Autowired @Autowired
private JwtAccessDeniedHandler jwtAccessDeniedHandler; private JwtAccessDeniedHandler jwtAccessDeniedHandler;
@Autowired
private Environment environment;
@Value("${jwt.header}") @Value("${jwt.header}")
private String tokenHeader; private String tokenHeader;
@@ -48,18 +54,26 @@ public class SecurityConfig {
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter = new JwtAuthenticationTokenFilter(userDetailsService, jwtTokenUtil, tokenHeader, tokenHead); JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter = new JwtAuthenticationTokenFilter(userDetailsService, jwtTokenUtil, tokenHeader, tokenHead);
http // 检查当前激活的profile中是否包含 "prod"
.csrf(csrf -> csrf.disable()) boolean isProd = Arrays.asList(environment.getActiveProfiles()).contains("prod");
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authz -> authz // 根据环境动态设置白名单
// 1. 始终允许的核心公共端点 (登录、注册、API文档) String[] publicEndpoints = isProd ?
.requestMatchers( new String[]{"/api/user/login", "/api/user/register"} :
new String[]{
"/doc.html", "/doc.html",
"/webjars/**", "/webjars/**",
"/v3/api-docs/**", "/v3/api-docs/**",
"/api/user/login", "/api/user/login",
"/api/user/register" "/api/user/register"
).permitAll() };
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authz -> authz
// 1. 动态允许公共端点
.requestMatchers(publicEndpoints).permitAll()
// 2. 精确允许用于“公开阅读”的 GET 请求 // 2. 精确允许用于“公开阅读”的 GET 请求
.requestMatchers(org.springframework.http.HttpMethod.GET, .requestMatchers(org.springframework.http.HttpMethod.GET,