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

news/2025/2/22 0:54:50/

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 类。

java">/*** Spring Security 配置类* @author pan_junbiao**/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{//公开权限的路径(白名单)private static final String[] WHITE_LIST = {"/admin/getLoginAdmin","/js/**","/captcha.jpg"};@Overrideprotected 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)  方法,如下所示。

java">@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) 方法,配置具有特定权限的用户访问。

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

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

java">@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) 方法,配置具有特定角色的用户访问。

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

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

java">@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() 实现更加细颗粒度的权限控制。

java">@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 端点的访问路径匹配权限访问。

java">@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() 方法。

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

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

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

java">@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 端点地址。

java">@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)

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

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

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


http://www.ppmy.cn/news/1574016.html

相关文章

JavaScript 前端面试 3(等于、全等、instanceof、typeof 、原型、原型链)

五、和的区别,分别在什么时候使用? 等于操作符,全等操作符 1:等于操作符 如果操作数相等 返回true JavaScript存在隐式转换,会先进行类型转换,再确定操作数是否相等,如果有一个是bool值&am…

板块一 Servlet编程:第十节 监听器全解 来自【汤米尼克的JAVAEE全套教程专栏】

板块一 Servlet编程:第十节 监听器全解 一、什么是监听器实现一个监听器的简单流程 二、各对象的监听器使用方法(1)Request域的监听器(2)Session域的监听器(3)Application域的监听器 三、实例&a…

MySQL多表连接查询高阶技巧和高阶函数

MySQL多表连接查询高阶技巧和高阶函数 以下是 MySQL 中多表连接查询的高阶技巧和高阶函数的详细介绍: 一、多表连接查询高阶技巧 1. 减少连接次数 技巧:通过子查询或临时表预先处理部分数据,减少多表连接的复杂度和次数,从而提…

QSNCTF做题记录-应急响应

题目来源&#xff1a;青少年CTF <天狩CTF竞赛平台> 应急响应一 题目描述&#xff1a;题目请使用SSH连接。用户名root&#xff0c;密码qsnctf&#xff0c;请提交当前系统发行版信息&#xff0c;得到的结果请包含qsnctf{}提交 1&#xff0c;首先使用kali-linux启用SSH服务连…

《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用 AlexNet 实现图片分类 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于学习 9年后重读深度学习奠基作之一&#xff1a;AlexNet【下】【论文精读】】的心得。 《跟李沐…

AI客服-接入deepseek大模型到微信(本地部署deepseek集成微信自动收发消息)

1.本地部署 1.1 ollama Ollama软件通过其高度优化的推理引擎和先进的内存管理机制&#xff0c;显著提升了大型语言模型在本地设备上的运行效率。其核心采用了量化技术&#xff08;Quantization&#xff09;以降低模型的计算复杂度和存储需求&#xff0c;同时结合张量并行计算&…

企业软件合规性管理:构建高效、安全的软件资产生态

引言 在数字化转型的浪潮下&#xff0c;企业的软件使用方式日益多元化&#xff0c;涉及云端、订阅制、永久授权及浮动许可等多种模式。然而&#xff0c;随着软件资产的增多&#xff0c;企业面临着合规性管理的严峻挑战&#xff1a;非法软件使用、许可证管理不当、软件资产闲置…

Sphinx和Read the Docs快速生成多语言版本的文档

下面是调整后的默认语言为简体中文&#xff0c;并添加英文翻译的具体操作步骤&#xff1a; 一、Sphinx本地配置调整 修改conf.py 将默认语言设置为中文&#xff0c;并声明支持英文&#xff1a; language zh_CN # 默认语言改为中文 locale_dirs [locale/] # 翻译文件目录不变…