目录
一.访问控制 url 匹配
二.内置访问控制方法介绍
三.角色权限判断
一.访问控制 url 匹配
在前面讲解了认证中所有常用配置,主要是对
http.formLogin() 进行操作。而在配置类中 http.authorizeRequests()
主要是对
url
进行控制,也就是我们所说的授权(访问控制)。
http.authorizeRequests() 也支持连缀写法,总体公式为:
url
匹配规则
.
权限控制方法
通过上面的公式可以有很多
url
匹配规则和很多权限控制方法。
这些内容进行各种组合就形成了
Spring Security
中的授权。
在所有匹配规则中取所有规则的交集。配置顺序影响了之后授权效果,越是具体的应该放在前面,越是笼统的应该放到后面。
1.anyRequest()
在之前认证过程中我们就已经使用过
anyRequest()
,表示匹配所有的请求。一般情况下此方法都会使用,设置全部内容都需要进行认证。
代码示例:
anyRequest().authenticated();
比如咱们之前写的代码中,上半部分是认证(),下半部分是授权(url拦截那块)
2.antMatcher()
方法定义如下:
参数是不定向参数,每个参数是一个 ant 表达式,用于匹配 URL规则。
规则如下:
? 匹配一个字符 * 匹配 0 个或多个字符 ** 匹配 0 个或多个目录
在实际项目中经常需要放行所有静态资源,下面演示放行jpg格式的图片
。
在resources/static下创建三个文件夹,并且在image下放一张图片
咱们现在通过设置来antMatcher()属性来放行静态资源
//放行静态资源文件夹(路径要具体情况具体分析)
.antMatchers("/css/**","/js/**","/image/**").permitAll()
/**的意思是当前目录下的所有文件或目录及其子目录
运行项目,访问localhost:8080/image/rb.jpg
咱们现在把刚刚配置的授权语句注释掉,再换一种思路来放行上面这张图片
//放行png图片
.antMatchers("/**/*.jpg").permitAll()
上面的/**意思就是不管前面有多少层目录,最后的一个*表示匹配所有后缀名是.jpg的图片,运行项目之后,仍访问成功。
一个常见问题,这个问题虽然我没遇到,但是还是要说一下,就是如果访问不到,除了重启服务器之外,也可以将target目录删除之后再启动项目。
3.regexMatchers()
3.1
介绍
使用正则表达式进行匹配。和
antMatchers()
主要的区别就是参数,antMatchers()
参数是
ant
表达
式,
regexMatchers()
参数是正则表达式。
演示所有以
.js
结尾的文件都被放行。
.regexMatchers(".+[.]js").permitAll()
会正则表达式的可以试试。
3.2
两个参数时使用方式
无论是 antMatchers()还是 regexMatchers()都具有两个参数的方法,其中第一个参数都是HttpMethod,表示请求方式,当设置了HttpMethod 后表示只有设定的特定的请求方式才执行对应的权限设置。
枚举类型
HttpMethod
内置属性如下:
4.mvcMatchers()
mvcMatchers()
适用于配置了
servletPath
的情况。
servletPath
就是所有的
URL
的统一前缀。所谓统一前缀,就是设置一个对于所有路径都生效的前缀,在访问时,路径之前都要加加上此前缀才能成为正确的路径。在
SpringBoot
整合 SpringMVC 的项目中可以在
application.properties (在resources下创建)
中添加下面内容设置 ServletPath
spring.mvc.servlet.path= /demo
这样配置之后,以访问上节课的用到的那个上上小节访问的那个热巴的图片为例:
注意左上角的访问地址,需要在原来的访问路径上加上demo
在配置文件中的配置了servletPath前缀的前提下,在配置类可以用下列两种路径放行方法。
在 Spring Security 的配置类中配置.servletPath()是 mvcMatchers() 返回值特有的方法antMatchers()和 regexMatchers()没有这个方法。 在 servletPath()中配置了 servletPath 后,mvcMatchers()直接写 SpringMVC 中@RequestMapping()中设置的路径即可。
//路径/demo/image/rb.jpg
.mvcMatchers("/image/rb.jpg").servletPath("/demo").permitAll()
如果不习惯使用
mvcMatchers()
也可以使用
antMatchers()
,下面代码和上面代码是等效的
.antMatchers("/demo/image/rb.jpg").permitAll()
配置的时候有个报错
英文的意思就是antMatchers应该写在anyRequest
二.内置访问控制方法介绍
Spring Security
匹配了
URL
后调用了
permitAll()
表示不需要认证,随意访问。在 Spring Security
中提供了多种内置控制。
1.permitAll()
permitAll()
表示所匹配的
URL
任何人都允许访问。
2.authenticated()
authenticated()
表示所匹配的
URL
都需要被认证才能访问。
3.anonymous()
anonymous()
表示可以匿名访问匹配的
URL
。和
permitAll()
效果类似,只是设置为 anonymous()
的
url
会执行
filter
链中
4.denyAll()
denyAll()
表示所匹配的
URL
都不允许被访问。
5.rememberMe()
被“remember me”的用户允许访问
这个有点类似于很多网站的十天内免登录,登陆一次即可记住你,然后未来一段时间不用登录。
6.fullyAuthenticated()
如果用户不是被
remember me
的,才可以访问。也就是必须一步一步按部就班的登录才行。
三.角色权限判断
除了之前讲解的内置权限控制。
Spring Security
中还支持很多其他权限控制。
这些方法一般都用于用户已经被认证后,判断用户是否具有特定的要求。即用户已经成功登录之后。
1.hasAuthority(String)
判断用户是否具有特定的权限,用户的权限是在自定义登录逻辑
中创建
User
对象时指定的。
下图中
admin
就是用户的权限。
admin
严格区分大小写。
return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
在配置类中通过 hasAuthority(“admin”)设置具有 admin 权限时才能访问。
上面这句话的意思就是用户只有具有admin权限才有资格访问main1.html页面
.antMatchers("/main1.html").hasAuthority("admin")
修改main.html
main.html
然后再编写main1.html
main1.html
但是访问登录界面的时候却发现localhost:8080/login.html不好使了
是因为设置了servletPath的原因,于是我在表单认证和表单授权里都加了路径前缀/demo
先将配置文件中servletPath的配置去掉,方便后续操作
把登录成功之后的跳转页面切换一下
访问localhost:8080/login,输入正确的用户名和密码之后,出现如下界面
点击链接,因为我们已经配置了admin权限,所以可以成功跳转
2.hasAnyAuthority(String ...)
如果用户具备给定权限中某一个,就允许访问。
下面代码中由于大小写和用户的权限不相同,所以用户无权访问 /main1.html
上面这句话的意思就是用户只有具有adMin或者admiN权限才有资格访问main1.html页面,这个函数可以有多个参数
.antMatchers("/main1.html").hasAnyAuthority("adMin","admiN")
用了上面的这句代码之后,就访问不到main1.html了因为admin不是adMin和asmiN的其中之一了
3.hasRole(String)
如果用户具备给定角色就允许访问。否则出现
403
。
参数取值来源于自定义登录逻辑
UserDetailsService
实现类中创建 User
对象时给
User
赋予的授权。
在给用户赋予角色时角色需要以:
ROLE_
开头,后面添加角色名称。例如:ROLE_abc
其中
abc
是角色名,
ROLE_
是固定的字符开头。
使用
hasRole()
时参数也只写
abc
即可。否则启动报错。
给用户赋予角色:
在配置类中直接写
abc
即可
//定义角色
.antMatchers("main1.html").hasRole("abc")
4.hasAnyRole(String ...)
如果用户具备给定角色的任意一个,就允许被访问
//定义角色
.antMatchers("main1.html").hasAnyRole("abc","Abc")
这和hasAnyAuthority一个意思,只不过一个是定义权限,一个是定义角色
5.hasIpAddress(String)
如果请求是指定的
IP
就运行访问。
可以通过
request.getRemoteAddr()
获取
ip
地址。
需要注意的是在本机进行测试时
localhost
和
127.0.0.1
输出的
ip 地址是不一样的。
当浏览器中通过
localhost
进行访问时控制台打印的内容:
当浏览器中通过
127.0.0.1
访问时控制台打印的内容:
当浏览器中通过具体 ip 进行访问时控制台打印内容:
好文推荐
发表评论