From e80f7ba501dd0973e12095054c4fd2be20f732cc Mon Sep 17 00:00:00 2001 From: zichun Date: Thu, 30 Apr 2026 14:58:38 +0800 Subject: [PATCH] refactor(usr): tighten security to authenticated REQ-USR-004 --- backend/src/main/java/com/xly/erp/common/security/JwtAuthenticationEntryPoint.java | 31 +++++++++++++++++++++++++++++++ backend/src/main/java/com/xly/erp/common/security/SecurityConfig.java | 10 ++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/java/com/xly/erp/common/security/JwtAuthenticationEntryPoint.java diff --git a/backend/src/main/java/com/xly/erp/common/security/JwtAuthenticationEntryPoint.java b/backend/src/main/java/com/xly/erp/common/security/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..2d433c3 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/common/security/JwtAuthenticationEntryPoint.java @@ -0,0 +1,31 @@ +package com.xly.erp.common.security; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.xly.erp.common.response.Result; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + + private final ObjectMapper objectMapper; + + public JwtAuthenticationEntryPoint(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException { + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json;charset=UTF-8"); + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); + response.getWriter().write(objectMapper.writeValueAsString(Result.fail(20001, "未认证"))); + } +} diff --git a/backend/src/main/java/com/xly/erp/common/security/SecurityConfig.java b/backend/src/main/java/com/xly/erp/common/security/SecurityConfig.java index fa6bb7f..02e9f31 100644 --- a/backend/src/main/java/com/xly/erp/common/security/SecurityConfig.java +++ b/backend/src/main/java/com/xly/erp/common/security/SecurityConfig.java @@ -3,6 +3,7 @@ package com.xly.erp.common.security; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; @@ -13,9 +14,11 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic public class SecurityConfig { private final JwtAuthenticationFilter jwtFilter; + private final JwtAuthenticationEntryPoint authEntryPoint; - public SecurityConfig(JwtAuthenticationFilter jwtFilter) { + public SecurityConfig(JwtAuthenticationFilter jwtFilter, JwtAuthenticationEntryPoint authEntryPoint) { this.jwtFilter = jwtFilter; + this.authEntryPoint = authEntryPoint; } @Bean @@ -23,11 +26,10 @@ public class SecurityConfig { http.csrf(csrf -> csrf.disable()) .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth - // REQ-MOD-001 stub: see USR-004 follow-up — 角色硬校验在 USR-004 完成后回填为 hasAuthority('SUPER_ADMIN') - .requestMatchers("/api/mod/**").permitAll() - .requestMatchers("/api/usr/**").permitAll() + .requestMatchers(HttpMethod.POST, "/api/usr/auth/login").permitAll() .anyRequest().authenticated() ) + .exceptionHandling(eh -> eh.authenticationEntryPoint(authEntryPoint)) .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } -- libgit2 0.22.2