配置Spring Security后未登录仍跳转登录页,如何允许主页匿名访问?
Spring Security配置后主页仍强制跳转登录页问题
我搭建了Spring MVC项目并集成Spring Security,期望所有用户无需登录即可访问主页,但配置后仍自动跳转到登录页。已清除浏览器缓存、尝试添加空匹配模式,问题依旧。
我的Security配置代码
package uz.smartup.academy.bloggingplatform.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.provisioning.UserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import javax.sql.DataSource; @Configuration public class SecurityConfiguration { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public UserDetailsManager userDetailsManager(DataSource dataSource) { JdbcUserDetailsManager detailsManager = new JdbcUserDetailsManager(dataSource); detailsManager.setUsersByUsernameQuery("SELECT username, password, enabled FROM user WHERE username = ?"); detailsManager.setAuthoritiesByUsernameQuery("SELECT username, role FROM role WHERE username = ?"); return detailsManager; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests( authManager -> authManager .requestMatchers(HttpMethod.GET, "/admin", "/admin/*").hasAnyRole("ADMIN") .requestMatchers(HttpMethod.GET, "/", "/posts/*", "/profile/*", "/categories/*").permitAll() .requestMatchers(HttpMethod.POST, "/profile/*").permitAll() .requestMatchers(HttpMethod.GET, "/css/**", "/js/**", "/photos/**").permitAll() .anyRequest().authenticated()) .formLogin( form -> form.loginPage("/login") .loginProcessingUrl("/authenticate") .defaultSuccessUrl("/", true) .permitAll() ) .logout(logout -> logout.logoutUrl("/logout") .logoutSuccessUrl("/") .permitAll() ); http.csrf(AbstractHttpConfigurer::disable); http.httpBasic(Customizer.withDefaults()); return http.build(); } }
调试日志(翻译后)
2024-07-06T23:19:21.944+05:00 DEBUG 4448 --- [bloggingplatform] [nio-8080-exec-2] s.w.a.DelegatingAuthenticationEntryPoint : 尝试使用以下规则匹配:And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@75a4ae9e, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]] 2024-07-06T23:19:21.948+05:00 DEBUG 4448 --- [bloggingplatform] [nio-8080-exec-2] s.w.a.DelegatingAuthenticationEntryPoint : 匹配成功!执行org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@76192bf1 2024-07-06T23:19:21.949+05:00 DEBUG 4448 --- [bloggingplatform] [nio-8080-exec-2] o.s.s.web.DefaultRedirectStrategy : 重定向至http://localhost:8080/login 2024-07-06T23:19:21.960+05:00 DEBUG 4448 --- [bloggingplatform] [nio-8080-exec-3] o.s.security.web.FilterChainProxy : 保护GET /login请求 2024-07-06T23:19:21.960+05:00 DEBUG 4448 --- [bloggingplatform] [nio-8080-exec-3] o.s.security.web.FilterChainProxy : 已完成GET /login请求的保护 2024-07-06T23:19:21.977+05:00 DEBUG 4448 --- [bloggingplatform] [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : 将SecurityContextHolder设置为匿名SecurityContext
问题分析与解决方案
从日志可以看出,请求未匹配到permitAll规则,触发了登录页重定向。核心原因是Spring Security的权限规则按顺序匹配,一旦前面的规则未命中,就会走到anyRequest().authenticated()强制认证。
调整规则顺序
把主页的permitAll规则移到最前面,确保优先匹配:
http.authorizeHttpRequests(authManager -> authManager // 优先放行主页,不限制请求方法(避免GET/POST方法不匹配) .requestMatchers("/").permitAll() .requestMatchers(HttpMethod.GET, "/admin", "/admin/*").hasAnyRole("ADMIN") .requestMatchers(HttpMethod.GET, "/posts/*", "/profile/*", "/categories/*").permitAll() .requestMatchers(HttpMethod.POST, "/profile/*").permitAll() .requestMatchers(HttpMethod.GET, "/css/**", "/js/**", "/photos/**").permitAll() .anyRequest().authenticated())
额外排查点
- 确认请求URL:检查实际访问的主页URL是否为
GET /,是否带有后缀(如.jsp)或参数,若有需在规则中补充对应匹配(比如"/index.jsp")。 - 多配置类冲突:如果存在多个
SecurityFilterChain配置类,需通过@Order注解明确优先级,避免高优先级配置覆盖当前规则。 - 请求方法匹配:若主页请求包含POST方法(比如表单提交),需补充
HttpMethod.POST, "/"到permitAll规则中。
内容的提问来源于stack exchange,提问作者abdullakh mirfayziev
相关产品推荐
相关产品推荐

