fix(file-service): use AntPathRequestMatcher to bypass Spring MVC matching
Spring Security 6 with MVC on classpath resolves requestMatchers(HttpMethod, String) to MvcRequestMatcher, which fails to match the actual servlet paths for this service. Switching to explicit AntPathRequestMatcher instances bypasses MVC introspection and forces pure Ant pattern evaluation, fixing persistent 401 on public upload/serve endpoints. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
b49b67bb1e
当前提交
8bc9b1ebda
@ -5,13 +5,13 @@ import com.xuqm.common.security.JwtUtil;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
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.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
@ -35,13 +35,11 @@ public class SecurityConfig {
|
||||
.cors(cors -> {})
|
||||
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||
// Public: file upload and serving (AntRequestMatcher via explicit method)
|
||||
.requestMatchers(HttpMethod.POST, "/api/file/upload").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/file/*/thumbnail").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/file/*").permitAll()
|
||||
// Actuator health & info
|
||||
.requestMatchers(HttpMethod.GET, "/actuator/**").permitAll()
|
||||
.requestMatchers(new AntPathRequestMatcher("/**", "OPTIONS")).permitAll()
|
||||
.requestMatchers(new AntPathRequestMatcher("/api/file/upload", "POST")).permitAll()
|
||||
.requestMatchers(new AntPathRequestMatcher("/api/file/*/thumbnail", "GET")).permitAll()
|
||||
.requestMatchers(new AntPathRequestMatcher("/api/file/*", "GET")).permitAll()
|
||||
.requestMatchers(new AntPathRequestMatcher("/actuator/**", "GET")).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.exceptionHandling(ex -> ex
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户