diff --git a/services/delivery-platform-api/src/main/java/cn/craftlabs/platform/api/config/SecurityConfig.java b/services/delivery-platform-api/src/main/java/cn/craftlabs/platform/api/config/SecurityConfig.java index 5e2e52a..fd003b5 100644 --- a/services/delivery-platform-api/src/main/java/cn/craftlabs/platform/api/config/SecurityConfig.java +++ b/services/delivery-platform-api/src/main/java/cn/craftlabs/platform/api/config/SecurityConfig.java @@ -6,15 +6,18 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; +import org.springframework.security.config.Customizer; 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.configurers.HeadersConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.HttpStatusEntryPoint; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy; /** - * I1:JWT(Bearer)保护业务 API;I5:{@code /internal/**} 使用内部共享 Token,与 JWT 分离。 + * I1:JWT(Bearer)保护业务 API;I5:{@code /internal/**} 使用内部共享 Token,与 JWT 分离;I6:统一安全响应头。 */ @Configuration @EnableWebSecurity @@ -26,6 +29,7 @@ public class SecurityConfig { HttpSecurity http, InternalTokenAuthenticationFilter internalTokenFilter) throws Exception { http.securityMatcher("/internal/**") .csrf(csrf -> csrf.disable()) + .headers(this::apiHeaders) .sessionManagement( sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) @@ -43,6 +47,7 @@ public class SecurityConfig { public SecurityFilterChain jwtFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtFilter) throws Exception { http.csrf(csrf -> csrf.disable()) + .headers(this::apiHeaders) .sessionManagement( sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests( @@ -66,4 +71,12 @@ public class SecurityConfig { .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } + + /** I6:API 最小安全头;HSTS 由边缘 HTTPS 终止(Nginx/Caddy)配置。 */ + private void apiHeaders(HeadersConfigurer headers) { + headers + .contentTypeOptions(Customizer.withDefaults()) + .frameOptions(frame -> frame.deny()) + .referrerPolicy(referrer -> referrer.policy(ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)); + } }