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

配置Spring Security后访问H2控制台仍提示权限被拒的问题

H2控制台访问被拒绝问题排查(已配置Spring Security放行规则)

问题描述

已在SecurityConfiguration中配置.requestMatchers("/h2/**").permitAll(),同时禁用CSRF、frameOptions,设置无状态会话并添加JwtAuthenticationFilter,但访问http://localhost:8080/h2时仍收到:

Access to localhost was denied

相关配置代码

SecurityConfiguration类

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {

  private final JwtAuthenticationFilter jwtAuthFilter;
  private final AuthenticationProvider authenticationProvider;

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http
        .headers()
            .frameOptions().disable()
            .and()
        .csrf().disable()
        .authorizeHttpRequests()
            .requestMatchers("/h2/**").permitAll()
            .requestMatchers("/api/v1/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .authenticationProvider(authenticationProvider)
        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

    return http.build();
  }
} 

JwtAuthenticationFilter类

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(
            @NonNull HttpServletRequest request,
            @NonNull HttpServletResponse response,
            @NonNull FilterChain filterChain
    ) throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");
        final String jwt;
        final String userEmail;
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }
        jwt = authHeader.substring(7);
        userEmail = jwtService.extractUsername(jwt);
        if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
            if (jwtService.isTokenValid(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
                authToken.setDetails(
                        new WebAuthenticationDetailsSource().buildDetails(request)
                );
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        filterChain.doFilter(request, response);
    }
}

解决办法

1. 核对H2控制台的实际访问路径

多数情况下H2控制台默认路径是/h2-console而非/h2,可在application配置文件中确认:

spring.h2.console.path=/h2-console
spring.h2.console.enabled=true

若路径为/h2-console,需修改Security配置中的规则:

.requestMatchers("/h2-console/**").permitAll()

2. 让H2请求跳过JWT过滤器

尽管Spring Security授权规则放行H2路径,但JWT过滤器会优先执行,可能因无Token导致隐式拦截。重写过滤器的shouldNotFilter方法,排除H2相关路径:

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
    String requestUri = request.getRequestURI();
    return requestUri.startsWith("/h2/") || requestUri.startsWith("/h2-console/");
}

3. 排查配置冲突

确保项目中仅存在一个标注@EnableWebSecurity的配置类,避免多配置覆盖规则;同时检查是否有其他自定义Filter对H2路径进行拦截。

4. 确认H2控制台启用状态

务必在application配置中开启H2控制台:

spring.h2.console.enabled=true

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:02:53