当前位置: 首页 > news >正文

SpringSecurity基于配置方法控制访问权限:MVC匹配器、Ant匹配器

Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。在 Spring Security 中,可以通过配置方法来控制访问权限。认证是实现授权的前提和基础,在执行授权操作前需要明确目标用户,只有明确目标用户才能明确它所具备的角色和权限。Spring Security 中所采用的授权模型也是由用户、角色和权限组成的。

Spring Security 实现配置方法控制访问权限很简单,只需要使用基于 HttpSecurity 对象提供的一组工具方法就能实现复杂场景下的访问控制。

Spring Security 中常见的配置方法及其作用:

配置方法作用
anonymous()允许匿名访问。
anyRequest()匹配所有的请求。
authenticated()所有匹配的 URL 都需要被认证才能访问。
permitAll()无条件允许一切用户访问。
hasAuthority(String)允许具有特定权限的用户访问。
hasAnyAuthority(String)允许具有任一权限的用户访问。
hasRole(String)允许具有特定角色的用户访问。
hasAnyRole(String)允许具有任一角色的用户访问。
hasIpAddress()允许来自特定 IP 地址的用户访问。
denyAll()无条件禁止一切访问。
access()该方法允许开发人员传入一个表达式进行更加细颗粒度的权限控制。
mvcMatchers(String)通过 MVC 匹配器,匹配 HTTP 端点的访问路径。
antMatchers(String)通过 Ant 匹配器,匹配 HTTP 端点的访问路径。
regexMatchers(String)通过正则表达式匹配器,匹配 HTTP 端点的访问路径。

综合实例:

Spring Security 的核心配置类,WebSecurityConfig 类(Spring Security 配置类),并添加 @EnableWebSecurity 注解和继承 WebSecurityConfigurerAdapter 类。

/**
 * Spring Security 配置类
 * @author pan_junbiao
 **/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
    
    //公开权限的路径(白名单)
    private static final String[] WHITE_LIST = {
            "/admin/getLoginAdmin",
            "/js/**",
            "/captcha.jpg"
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests() //返回一个URL拦截注册器
                .antMatchers(WHITE_LIST).permitAll() //公开其权限(公开的权限必须放在最上面)
                .antMatchers("/account/**").hasAnyRole("SUPER_ADMIN","GENERAL_ADMIN") //设置授权角色(普通管理员)
                .antMatchers("/log/**").hasAnyRole("SUPER_ADMIN","GENERAL_ADMIN") //设置授权角色(普通管理员)
                .antMatchers("/**").hasRole("SUPER_ADMIN") //设置授权角色(超级管理员)
                .anyRequest() //匹配所有的请求
                .authenticated() //所有匹配的URL都需要被认证才能访问
                .and() //结束当前标签,让上下文回到 HttpSecurity
                .formLogin() //启动表单认证
                .loginPage("/myLogin.html") //自定义登录页面
                .loginProcessingUrl("/auth/form") //指定处理登录请求路径
                .permitAll() //使登录页面不设限访问
                .and().csrf().disable(); //关闭CSRF的防御功能
    }
}

1、Spring Security 中的权限和角色

在权限和角色的概念中,两者都是用于管理系统中用户访问权限的重要机制,但它们有着不同的含义和用途。角色代表用户在系统中的身份或职位。它是权限的一种组合方式,通常用于描述用户在组织或系统中的职责和权限级别。权限表示用户可以执行的具体操作或访问的具体资源。它是更细粒度的控制机制,用于描述用户在系统中的具体操作权限。

Spring Security 的核心配置类,WebSecurityConfig 类中,configure(HttpSecurity http)  方法,如下所示。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests() //返回一个URL拦截注册器
            .anyRequest()    //匹配所有的请求
            .authenticated() //所有匹配的URL都需要被认证才能访问
            .and()           //结束当前标签,让上下文回到 HttpSecurity
            .formLogin()     //启动表单认证
            .and()
            .httpBasic();
}

1.1 基于权限进行访问配置

基于权限进行访问配置是确保系统安全性的重要手段。权限表示用户可以执行的具体操作或访问的具体资源。

Spring Security 提供了一组权限的配置方法,如下:

  • hasAuthority(String):允许具有特定权限的用户访问。
  • hasAnyAuthority(String):允许具有任一权限的用户访问。

可以使用上述方法来判断用户是否具备对应的访问权限。

【示例】使用 hasAuthority(String) 方法,配置具有特定权限的用户访问。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests() //返回一个URL拦截注册器
            .antMatchers("/user/**").hasAuthority("user:info"); //配置权限:允许具有特定权限的用户访问
}

【示例】使用 hasAnyAuthority(String) 方法,配置具有任一权限的用户访问。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests() //返回一个URL拦截注册器
            .antMatchers("/user/**").hasAnyAuthority("user:add","user:edit","user:delete"); //配置权限列表:允许具有任一权限的用户访问
}

1.2 基于角色进行访问配置

角色是权限的一种组合方式,用于描述用户在系统中的身份或职责,角色可以包含多个权限,但权限不一定属于某个角色(可以独立存在)。

Spring Security 提供了一组角色的配置方法,如下:

  • hasRole(String):允许具有特定角色的用户访问。
  • hasAnyRole(String):允许具有任一角色的用户访问。

可以使用上述方法来判断用户是否具备对应的访问角色。

【示例】使用 hasRole(String) 方法,配置具有特定角色的用户访问。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests() //返回一个URL拦截注册器
            .antMatchers("/user/**").hasRole("USER_INFO"); //配置角色:允许具有特定角色的用户访问
}

【示例】使用 hasAnyRole(String) 方法,配置具有任一角色的用户访问。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests() //返回一个URL拦截注册器
            .antMatchers("/user/**").hasAnyRole("USER_INFO", "SUPER_ADMIN", "GENERAL_ADMIN"); //配置角色:允许具有任一角色的用户访问。
}

1.3 使用 access() 实现更加细颗粒度的权限控制

由于 hasAuthority(String)、hasAnyAuthority(String)、hasRole(String)、hasAnyRole(String) 方法都比较简单,但局限性也很大,因此无法基于一些环境和业务参数灵活控制范围规则。为此,Spring Security 提供了  access() 方法,该方法允许开发人员传入一个表达式进行更加细颗粒度的权限控制。这里将引入 SpEL( Spring 表达式语言,Spring Expression Language)表达式,它是 Spring 框架提供的一种动态表达式语言。基于 SpEL,只要该表达式的返回值为 true,那么 access() 方法允许用户访问。

【示例】使用 access() 实现更加细颗粒度的权限控制。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    //定义权限规则:只能拥有 “user:add” 权限,且不拥有 “user:delete” 权限的用户才能访问
    String expression = "hasAuthority('user:add') and !hasAuthority('user:delete')";

    //设置权限
    http.authorizeRequests() //返回一个URL拦截注册器
            .antMatchers("/user/**").access(expression);
}

上述代码的执行效果是只能拥有 “user:add” 权限,且不拥有 “user:delete” 权限的用户才能访问。

2、使用配置方法控制访问权限

确保请求安全的手段是对访问进行限制,只有那些具有访问限制的请求才能被服务器处理。那么,如何让 HTTP 请求与权限控制过程产生关联呢?答案还是使用 Spring Security 提供的配置方法。Spring Security 提供了三种强大的匹配器(Matcher)来实现这一目标,分别是 MVC 匹配器、Ant 匹配器及正则表达式匹配器。

2.1 MVC 匹配器

在三种匹配器中,MVC 匹配器的使用方法比较简单,基于 HTTP 端点的访问路径进行匹配即可。

【示例】使用 MVC 匹配器,基于 HTTP 端点的访问路径匹配权限访问。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests()
            .mvcMatchers("/user/*").hasRole("USER")
            .mvcMatchers("/admin").hasRole("ADMIN")
            .anyRequest().authenticated();
}

现在又有一个新的问题,如果一个 Controller 中存在两个路径完全一样的 HTTP 端点呢?这种情况是存在的。对于 HTTP 端点而言,就算路劲一样,只要所使用的 HTTP 方法不同,那就是不同的两个端点。

【示例】针对上述问题,MVC 匹配器还提供了重载的 mvcMatchers() 方法。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests()
            .mvcMatchers(HttpMethod.POST, "/hello").authenticated()
            .mvcMatchers(HttpMethod.GET, "/hello").permitAll()
            .anyRequest().denyAll(); //拒绝
}

同时,如果想对某个路径下的所有子路径都指定同样的访问控制,在该路径后面添加“*”符号即可。

【示例】使用“*”符号,配置某个路径下的所有子路径。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests()
            .mvcMatchers(HttpMethod.POST, "/user/*").authenticated();
}

2.2 Ant 匹配器

Ant 匹配器的表现形式和使用方法与前面介绍的 MVC 匹配器非常类似,也提供了如下的三个方法来完成请求与 HTTP 端点地址之间的匹配关系。

  • antMatchers(String... antPatterns)
  • antMatchers(HttpMethod method)
  • antMatchers(HttpMethod method, String... antPatterns)

【示例】使用 Ant 匹配器,匹配 HTTP 端点地址。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests()
            .antMatchers("/user").hasRole("USER")
            .antMatchers(HttpMethod.POST, "/admin").hasRole("ADMIN")
            .anyRequest().authenticated();
}

注意:在浏览器的地址栏最后面添加“/”符号,如:http://localhost:8080/user/,这样才会得到正确的访问结果。

显然,Ant 匹配器处理请求地址的方式有点让人感到困惑,而使用 MVC 匹配器则没有这个问题,无论请求地址的末尾是否存在“/”符号,它都是正确匹配。

所以在日常开发过程中,我们更倾向于使用 MVC 匹配器而非 Ant 匹配器,原因在于 Ant 匹配器在匹配路径上存在一定风险。

2.3 正则表达式匹配器

最后要介绍的匹配器是正则表达式匹配器。它提供的两个配置方法如下:

  • regexMatchers(String... regexPatterns)
  • regexMatchers(HttpMethod method, String... regexPatterns)

使用正则表达式匹配器的主要优势在于它能够基于复杂的正则表达式对请求地址进行匹配。

【示例】使用正则表达式匹配器,匹配常见的邮箱地址。

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.authorizeRequests()
            .regexMatchers("/email/{email:.*(.+@.+\\.com)}")
            .permitAll()
            .anyRequest().denyAll();
}

相关文章:

  • hive 编译慢问题处理
  • FontConfig封装分享
  • Token Embedding(词嵌入)和Positional Encoding(位置编码)的矩阵形状关系及转换过程
  • [grub]修改启动项选项来区分不同系统
  • fastapi sqlalchemy 日志 logging 写入异常 多进程文件写入异常
  • python-leetcode 37.翻转二叉树
  • Javascript网页设计实例:通过JS实现上传Markdown转化为脑图并下载脑图
  • 火语言RPA--Excel关闭保存文档
  • 【HarmonyOS Next】鸿蒙监听手机按键
  • 汇能感知的光谱相机/模块产品有哪些?
  • 【python】tkinter简要教程
  • oppo,汤臣倍健,康冠科技,高途教育25届春招内推
  • 记录一下windows11编译Openpose的过程
  • 使用VSCODE开发C语言程序
  • 【PLL】应用:时钟生成
  • 【项目日记】仿RabbitMQ实现消息队列 --- 模块设计
  • 【云安全】云原生-Docker(六)Docker API 未授权访问
  • unity学习49:寻路网格链接 offMeshLinks, 以及传送门效果
  • 使用FFmpeg将PCMA格式的WAV文件转换为16K采样率的PCM WAV文件
  • 基于SpringBoot实现的宠物领养系统平台功能一
  • 《大风杀》导演张琪:为了不算计观众,拍了部不讨好的警匪片
  • 缅甸内观冥想的历史漂流:从“人民鸦片”到东方灵修
  • 前四个月社会融资规模增量累计为16.34万亿元,比上年同期多3.61万亿元
  • 商务部就开展加强战略矿产出口全链条管控工作应询答记者问
  • 极限拉扯上任巴西,安切洛蒂开启夏窗主帅大挪移?
  • 训练孩子的科学思维,上海虹口推出“六个一百”旗舰工程