配置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
相关产品推荐
相关产品推荐

