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

配置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())

额外排查点

  1. 确认请求URL:检查实际访问的主页URL是否为GET /,是否带有后缀(如.jsp)或参数,若有需在规则中补充对应匹配(比如"/index.jsp")。
  2. 多配置类冲突:如果存在多个SecurityFilterChain配置类,需通过@Order注解明确优先级,避免高优先级配置覆盖当前规则。
  3. 请求方法匹配:若主页请求包含POST方法(比如表单提交),需补充HttpMethod.POST, "/"到permitAll规则中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:45:07