Spring Security配置异常:permitAll与hasRole不生效问题排查求助
Spring Security配置问题:permitAll与权限校验规则不生效的原因及解决办法
问题原因分析
核心问题:WebSecurityCustomizer 完全忽略所有请求
你配置的WebSecurityCustomizer中使用了web.ignoring().anyRequest(),这会让Spring Security跳过所有请求的安全校验逻辑,直接放行所有请求。这就导致后续SecurityFilterChain里定义的permitAll、hasAuthority规则根本不会被执行,是规则失效的关键原因。JDBC认证配置未生效
你编写的configure(AuthenticationManagerBuilder authentication)方法没有添加@Autowired注解,在Spring Security 5.7+版本中,这种旧配置方式如果缺少注解,不会被自动调用,导致基于数据库的认证逻辑没有生效。H2控制台访问配置不完整
仅给/h2/**配置permitAll还不够,浏览器的X-Frame-Options拦截会导致H2控制台页面无法正常加载,需要额外配置允许iframe加载。
解决办法及修改后的代码
步骤说明
- 移除或修改
WebSecurityCustomizer,避免忽略所有请求(仅在需要忽略静态资源时保留) - 给
configure方法添加@Autowired,确保JDBC认证配置生效 - 补充H2控制台的iframe允许配置
- 添加
anyRequest().authenticated()规则,确保除放行路径外,其余请求都需认证
修改后的完整代码
package com.productiv.authentication; import javax.sql.DataSource; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SpringSecurityBasicAuthConfig { private static final Logger logger = LogManager.getLogger(SpringSecurityBasicAuthConfig.class); @Autowired private DataSource dataSource; @Autowired protected void configure(AuthenticationManagerBuilder authentication) throws Exception { authentication.jdbcAuthentication() .dataSource(dataSource) .passwordEncoder(passwordEncoder()); // 指定密码编码器,匹配数据库加密后的密码 } // 若无需忽略静态资源,直接删除这个Bean;如需忽略,可指定具体路径如/css/**、/js/** // @Bean // public WebSecurityCustomizer webSecurityCustomizer() { // return (web) -> web.ignoring().requestMatchers("/css/**", "/js/**"); // } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { String methodName = "filterChain"; logger.info("Executing, " + methodName); http.authorizeHttpRequests(auth -> auth .requestMatchers("/h2/**").permitAll() .requestMatchers("/api/v1/registration/**").permitAll() .requestMatchers("/users/**").hasAuthority("USER") .anyRequest().authenticated()) // 所有未匹配的请求都需要认证 .formLogin() .and() .csrf().disable() .headers(headers -> headers.frameOptions().disable()); // 允许H2控制台的iframe加载 return http.build(); } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
额外说明
- 如果数据库中角色前缀为
ROLE_(比如存储的是ROLE_USER),可以用hasRole("USER")替代hasAuthority("USER"),hasRole会自动补全ROLE_前缀 - 确保数据库中
users和authorities表结构符合Spring Security JDBC认证的默认要求,或自定义查询语句适配你的表结构
内容的提问来源于stack exchange,提问作者Andrew Johnson
相关产品推荐
相关产品推荐

