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

Spring Boot项目如何正确配置Spring Security实现页面权限控制

配置错误点

你当前的权限配置逻辑有三处问题,完全不符合需求:

  • .anyRequest().authenticated()规则强制所有请求必须认证后才能访问,直接把所有公共页面、静态资源、登录页全部拦截,匿名用户无法访问任何非鉴权路径
  • 仅指定了登录页路径,但没有给登录页开放匿名访问权限,会触发未登录→跳登录页→登录页也要登录→再跳登录页的重定向死循环
  • 没有放行静态资源路径,static目录下的css、js、存放在static的图片资源会被拦截,页面样式、交互会全部失效
  • 注意:Thymeleaf的templates目录下的文件是受保护的模板资源,无法被直接通过物理路径访问,所有权限匹配的是Controller层的请求映射路径,不是模板文件的磁盘路径
可用的完整配置
@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
                // 开发阶段可先关闭CSRF,避免普通表单提交报403,生产环境按需开启
                .csrf().disable()
                .authorizeRequests()
                // 放行所有静态资源
                .antMatchers("/static/**", "/images/**").permitAll()
                // 放行所有不需要登录就能访问的公共页面:首页、注册页、登录页
                .antMatchers(
                        "/",
                        "/index",
                        "/home",
                        "/firstPage",
                        "/inscriptionForm",
                        "/loginPage.html"
                ).permitAll()
                // userOnly目录下的所有请求,必须拥有USER角色才可访问
                .antMatchers("/userOnly/**").hasRole("USER")
                // 其余所有请求,只要登录即可访问,不限制角色
                .anyRequest().authenticated()
                .and()
                .formLogin()
                // 自定义登录页路径
                .loginPage("/loginPage.html")
                // 登录表单提交的默认处理路径,和表单action保持一致即可,默认值为/login
                .loginProcessingUrl("/login")
                // 登录成功后默认跳转首页
                .defaultSuccessUrl("/home", true)
                // 登录失败返回登录页并携带错误参数
                .failureUrl("/loginPage.html?error=true")
                // 放行登录相关的所有请求
                .permitAll()
                .and()
                // 配置退出登录逻辑
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/loginPage.html?logout=true")
                .permitAll();
    }
}
配套配置说明

如果你没有为每个页面单独写Controller方法做视图返回,可以加一个MVC配置类,直接把请求路径和templates下的模板做绑定,不需要写冗余的Controller方法:

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 公共页面映射
        registry.addViewController("/loginPage.html").setViewName("loginPage");
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index").setViewName("index");
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/firstPage").setViewName("firstPage");
        registry.addViewController("/inscriptionForm").setViewName("inscriptionForm");
        // userOnly目录下页面映射
        registry.addViewController("/userOnly/help").setViewName("userOnly/help");
        registry.addViewController("/userOnly/menu").setViewName("userOnly/menu");
        registry.addViewController("/userOnly/newDocForm").setViewName("userOnly/newDocForm");
        registry.addViewController("/userOnly/profil").setViewName("userOnly/profil");
    }
}
避坑提醒
  • hasRole("USER")方法会自动在角色名前拼接ROLE_前缀,如果你数据库里存储的用户角色字段值是USER,要改成ROLE_USER,或者换成hasAuthority("USER")做权限匹配,后者不会自动拼接前缀
  • 不要把templates目录配置成静态资源目录,否则会直接泄露模板源码
  • 如果登录后访问userOnly路径报403,优先检查当前登录用户是否被正确授予了对应角色

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:36:27