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

Spring Security配置Actuator端点后/actuator/env仍返回403问题排查

问题:Spring Security配置后/actuator/env仍返回403

配置Spring Security允许InfoEndpoint、HealthEndpoint、EnvironmentEndpoint无需认证访问,但请求/actuator/env时返回403状态码。以下是相关代码、请求结果及调试日志:

我的代码

@EnableWebSecurity
@Configuration
public class SecurityConfiguration {

  @Bean
  SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(
            authorize -> authorize
                .requestMatchers(
                    EndpointRequest.to(InfoEndpoint.class, HealthEndpoint.class, EnvironmentEndpoint.class))
                .permitAll().anyRequest().authenticated())
        .formLogin(cr -> cr.disable());
    return http.build();
  }
}

请求结果

❯ http localhost:9090/actuator/env
HTTP/1.1 403
...

Spring Security调试日志

2023-11-16T16:09:18.834+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@3e8799f, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3b353651, org.springframework.security.web.context.SecurityContextHolderFilter@1290ed28, org.springframework.security.web.header.HeaderWriterFilter@a6c54c3, org.springframework.security.web.authentication.logout.LogoutFilter@4373f66f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5c887052, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3610f277, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@270d43a7, org.springframework.security.web.access.ExceptionTranslationFilter@2b916808, org.springframework.security.web.access.intercept.AuthorizationFilter@33f17289]] (1/1)
2023-11-16T16:09:18.835+01:00 DEBUG 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Securing GET /actuator/env
2023-11-16T16:09:18.835+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking DisableEncodeUrlFilter (1/10)
2023-11-16T16:09:18.836+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (2/10)
2023-11-16T16:09:18.836+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderFilter (3/10)
2023-11-16T16:09:18.836+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (4/10)
2023-11-16T16:09:18.836+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking LogoutFilter (5/10)
2023-11-16T16:09:18.836+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.s.w.a.logout.LogoutFilter            : Did not match request to Or [Ant [pattern='/logout', GET], Ant [pattern='/logout', POST], Ant [pattern='/logout', PUT], Ant [pattern='/logout', DELETE]]
2023-11-16T16:09:18.837+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking RequestCacheAwareFilter (6/10)
2023-11-16T16:09:18.837+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.s.w.s.HttpSessionRequestCache        : matchingRequestParameterName is required for getMatchingRequest to lookup a value, but not provided
2023-11-16T16:09:18.837+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderAwareRequestFilter (7/10)
2023-11-16T16:09:18.837+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking AnonymousAuthenticationFilter (8/10)
2023-11-16T16:09:18.837+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking ExceptionTranslationFilter (9/10)
2023-11-16T16:09:18.838+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.security.web.FilterChainProxy        : Invoking AuthorizationFilter (10/10)
2023-11-16T16:09:18.838+01:00 TRACE 241896 --- [nio-9090-exec-8] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@14d8e31b]
2023-11-16T16:09:18.838+01:00 TRACE 241896 --- [nio-9090-exec-8] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@14d8e31b] using org.springframework.security.authorization.AuthenticatedAuthorizationManager@6f5c58c
2023-11-16T16:09:18.839+01:00 TRACE 241896 --- [nio-9090-exec-8] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2023-11-16T16:09:18.839+01:00 TRACE 241896 --- [nio-9090-exec-8] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
2023-11-16T16:09:18.839+01:00 TRACE 241896 --- [nio-9090-exec-8] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
2023-11-16T16:09:18.839+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]
2023-11-16T16:09:18.840+01:00 TRACE 241896 --- [nio-9090-exec-8] o.s.s.w.a.ExceptionTranslationFilter     : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied

org.springframework.security.access.AccessDeniedException: Access Denied
解决方案

从调试日志可知,请求/actuator/env未匹配到permitAll规则,而是进入了anyRequest().authenticated()的校验逻辑,导致匿名用户被拒绝。可通过以下方式解决:

方式一:直接匹配端点URL路径

将EndpointRequest.to替换为具体端点路径,这种方式更直观且不易出错:

@EnableWebSecurity
@Configuration
public class SecurityConfiguration {

  @Bean
  SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(
            authorize -> authorize
                // 直接指定允许匿名访问的Actuator端点路径
                .requestMatchers("/actuator/info", "/actuator/health", "/actuator/env")
                .permitAll()
                .anyRequest().authenticated())
        .formLogin(cr -> cr.disable());
    return http.build();
  }
}

方式二:修复EndpointRequest匹配逻辑(若坚持使用类匹配)

  1. 确认导入的EnvironmentEndpoint为正确包路径:org.springframework.boot.actuate.env.EnvironmentEndpoint,避免因导入错误类导致匹配失败。
  2. 检查Actuator端点ID是否被自定义修改,默认EnvironmentEndpoint的ID为env,对应路径/actuator/env。

额外配置检查

需确保配置文件中已暴露对应Actuator端点,否则即使Security允许访问也会返回404。在application.properties中添加:

management.endpoints.web.exposure.include=info,health,env

或在application.yml中添加:

management:
  endpoints:
    web:
      exposure:
        include: info,health,env

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:27:02