You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security配置问题:浏览器访问接口出现Access Denied异常

问题描述

我配置了如下Spring Security的SecurityConfig类:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final AuthenticationProvider authenticationProvider;

    @Bean
    @Order(1)
    public SecurityFilterChain securityFilterChain(final HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf(AbstractHttpConfigurer::disable) 
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/Auth/**", "/").permitAll()
                        .anyRequest().authenticated()
                ).sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authenticationProvider(authenticationProvider);
        return httpSecurity.build();
    }
    
}

以及基础的AuthController控制器:

@RestController
@RequestMapping("/Auth/")
@RequiredArgsConstructor
public class AuthController {
    private final AuthService authService;
    @PostMapping("RegisterWithUserNameAndPassword")
    public ResponseEntity<?> registerWithUserNameAndPassword(@RequestBody RegisterRequest authRequest){
        try{
            return ResponseEntity.ok(authService.register(authRequest));
        } catch (Exception e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }
    
    @GetMapping("Hello")
    public ResponseEntity<String> hello(){
        return ResponseEntity.ok("Hello Auth controller");
    }
}

使用Postman访问/Auth/Hello接口时一切正常,可获取正确响应且无报错;但使用浏览器访问该接口时,虽能得到正确的字符串响应,却会抛出如下AccessDeniedException异常:

org.springframework.security.access.AccessDeniedException: Access Denied
    at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:98) ~[spring-security-web-6.1.2.jar:6.1.2]
    at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) ~[spring-security-web-6.1.2.jar:6.1.2]
    at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) ~[spring-security-web-6.1.2.jar:6.1.2]
    at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) ~[spring-security-web-6.1.2.jar:6.1.2]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) ~[spring-security-web-6.1.2.jar:6.1.2]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) ~[spring-security-web-6.1.2.jar:6.1.2]

对应的调试日志如下:

2023-08-13T16:24:50.955+03:00 DEBUG 55724 --- [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /Auth/Hello
2023-08-13T16:24:50.962+03:00 DEBUG 55724 --- [nio-8090-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-08-13T16:24:50.969+03:00 DEBUG 55724 --- [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Secured GET /Auth/Hello
2023-08-13T16:24:50.985+03:00  WARN 55724 --- [nio-8090-exec-1] c.m.security.config.JwtAuthFilter        : No valid jwt token in Authorization
2023-08-13T16:24:51.002+03:00 DEBUG 55724 --- [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /favicon.ico
2023-08-13T16:24:51.002+03:00 DEBUG 55724 --- [nio-8090-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-08-13T16:24:51.005+03:00 DEBUG 55724 --- [nio-8090-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access
2023-08-13T16:24:51.008+03:00 DEBUG 55724 --- [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /error
2023-08-13T16:24:51.010+03:00 DEBUG 55724 --- [nio-8090-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-08-13T16:24:51.010+03:00 DEBUG 55724 --- [nio-8090-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access

移除JwtAuthFilter后的调试日志:

2023-08-13T23:19:30.050+03:00 DEBUG 94616 --- [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /Auth/Hello
2023-08-13T23:19:30.057+03:00 DEBUG 94616 --- [nio-8090-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-08-13T23:19:30.064+03:00 DEBUG 94616 --- [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Secured GET /Auth/Hello
2023-08-13T23:19:30.097+03:00 DEBUG 94616 --- [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /favicon.ico
2023-08-13T23:19:30.097+03:00 DEBUG 94616 --- [nio-8090-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-08-13T23:19:30.101+03:00 DEBUG 94616 --- [nio-8090-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access
2023-08-13T23:19:30.103+03:00 DEBUG 94616 --- [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /error
2023-08-13T23:19:30.105+03:00 DEBUG 94616 --- [nio-8090-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-08-13T23:19:30.106+03:00 DEBUG 94616 --- [nio-8090-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access

请问有什么方法可以修复这个异常?


解决方案

原因分析

从调试日志可以明确:异常并非来自/Auth/Hello的请求,而是浏览器自动发起的/favicon.ico请求——该路径不在permitAll列表中,被Spring Security拦截后触发AccessDeniedException。同时Spring Boot默认错误页面路径/error也未被允许访问,导致二次触发异常。

修复方法

方法1:将favicon和error路径加入permitAll

修改SecurityConfig中的授权规则,把/favicon.ico和/error添加到允许匿名访问的范围:

.authorizeHttpRequests(auth -> auth
        .requestMatchers("/Auth/**", "/", "/favicon.ico", "/error").permitAll()
        .anyRequest().authenticated()
)

方法2:直接忽略favicon路径

如果不需要处理网站图标,可以让Spring Security直接跳过对该路径的拦截,在securityFilterChain方法中添加:

httpSecurity
        .csrf(AbstractHttpConfigurer::disable)
        .authorizeHttpRequests(auth -> auth
                .requestMatchers("/Auth/**", "/").permitAll()
                .anyRequest().authenticated()
        )
        .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authenticationProvider(authenticationProvider)
        .ignoringRequestMatchers("/favicon.ico"); // 忽略favicon请求

方法3:自定义错误页面处理(可选)

若希望更优雅地处理错误,可配置自定义错误控制器,并确保错误路径被允许访问:

@RestController
@RequestMapping("/error")
public class CustomErrorController {
    @GetMapping
    public ResponseEntity<String> handleError() {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Resource not found");
    }
}

同时在SecurityConfig的permitAll列表中保留/error路径。


内容的提问来源于stack exchange,提问作者Itamarled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 10:27:03