Spring Security6/Spring Boot3中permitAll端点重定向至/login问题排查
Spring Security 6/Spring Boot 3:permitAll端点仍重定向至登录页的问题排查与解决方案
问题描述
已按官方文档配置SecurityFilterChain Bean,为/h2、/register/**等端点设置permitAll权限,但访问这些端点时仍被自动重定向至Spring登录表单。
核心问题排查
1. H2控制台路径匹配不完整
H2控制台的入口路径配置为/h2,但实际访问时会涉及/h2/、/h2/login等子路径资源。原配置仅匹配/h2,导致子路径被拦截触发登录跳转。
2. FrameOptions限制导致H2控制台访问异常
配置中frameOptionsConfig.deny()禁用了iframe,而H2控制台依赖iframe渲染,即使权限配置正确,也会导致访问异常(间接引发跳转问题)。
3. 重复的PasswordEncoder Bean
SecurityConfiguration和SecurityBeansConfiguration中都定义了BCryptPasswordEncoder Bean,引发Bean冲突,可能影响Spring Security的正常初始化。
4. FormLogin未指定自定义登录页(可选优化)
虽然配置了/login的GET接口,但未显式指定Spring Security的登录页路径,可能导致默认登录逻辑与自定义接口冲突。
解决方案
1. 修正H2控制台路径匹配
将requestMatchers中的/h2改为/h2/**,覆盖所有H2控制台相关子路径:
.requestMatchers("/healthcheck", "/index", "/login", "/register/**", "/h2/**").permitAll()
2. 调整FrameOptions配置
将frameOptions改为允许同源iframe,适配H2控制台需求:
.frameOptions(frameOptionsConfig -> frameOptionsConfig.sameOrigin())
3. 移除重复的PasswordEncoder Bean
删除SecurityBeansConfiguration类(或其中的getBCE()方法),保留SecurityConfiguration中的passwordEncoder() Bean即可。
4. 显式指定FormLogin登录页(可选)
在formLogin配置中指定自定义登录页路径,确保与控制器接口匹配:
.formLogin(form -> form.loginPage("/login") .defaultSuccessUrl("/swagger-ui/index.html#/", true) )
修改后的完整SecurityConfiguration代码
@Configuration @EnableWebSecurity public class SecurityConfiguration { @Autowired private DomainUserDetailsService domainUserDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(domainUserDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(authenticationProvider); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) .headers(headers -> headers .contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self' data:;" + "style-src 'self' maxcdn.bootstrapcdn.com getbootstrap.com 'unsafe-inline';")) .frameOptions(frameOptionsConfig -> frameOptionsConfig.sameOrigin()) .permissionsPolicy(permissions -> permissions.policy( "fullscreen=(self), geolocation=(), microphone=(), camera=()" ) ) ) .authorizeHttpRequests(authorizations -> authorizations .requestMatchers("/healthcheck", "/index", "/login", "/register/**", "/h2/**").permitAll() .requestMatchers(HttpMethod.GET, "/players/**").hasAuthority("ROLE_USER") .requestMatchers(HttpMethod.PUT, "/players/**").hasAuthority("ROLE_ADMIN") .requestMatchers(HttpMethod.POST, "/players/**").hasAuthority("ROLE_ADMIN") .requestMatchers(HttpMethod.DELETE, "/players/**").hasAuthority("ROLE_ADMIN") .anyRequest().authenticated() ) .formLogin(form -> form.loginPage("/login") .defaultSuccessUrl("/swagger-ui/index.html#/", true) ); return http.build(); } }
额外说明
- 确保
/register的GET请求有对应的控制器方法(当前仅实现了/register/save的POST),否则访问/register会返回404,但不会触发登录跳转。 - 若使用模板引擎(如Thymeleaf),需确保
templates目录下存在login.html和register.html视图文件,否则控制器返回的字符串会直接作为响应体返回。
内容的提问来源于stack exchange,提问作者peace3106
相关产品推荐
相关产品推荐

