写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。
上一篇提到通常WebSecurityConfigurerAdapter (spring security的配置)和ResourceServerConfigurerAdapter会配合来对url进行访问控制,本篇通过示例细化一下它们两者的使用。
常用访问控制方法
在这之前,先回顾一下Security中的几个方法:
requestMatchers()与authorizeRequests()区别
anyRequest、antMatcher、mvcMatchers区别
requestMatchers()与authorizeRequests()
SpringSecurity中,每声明一个adapter实例,就会产生一条过滤器链,一个请求过来要走哪个过滤器链就是由requestMatchers()方法配置的url决定的。请求匹配上requestMatchers()配置的过滤器链后,在进一步的详细控制则是authorizeRequests()决定的。
一句话概括就是requestMatchers()配置的是哪些url进行安全控制,authorizeRequests()配置的是如何进行控制,其他url可直接访问。
anyRequest、antMatcher、mvcMatchers
anyRequest():表示匹配所有的请求。
antMatcher():可接受多个参数,每一个参数是一个ant表达式,用于匹配URL规则。规则如下:
- ?:匹配一个字符。
- *:匹配0个或多个字符。
- **:匹配0或多个目录。
在实际项目中经常需要放行所有静态资源,下面演示放行 js 文件夹下所有脚本文件。
.antMatchers("/js/**","/css/**").permitAll() // 或 .antMatchers("/**/*.js").permitAll()
mvcMatchers():mvcMatchers()适用于配置了servletPath 的情况。servletPath 就是所有的 URL 的统一前缀。在SpringBoot整合SpringMVC 的项目中可以在 配置文件中 配置
context-path ,访问的时候需要在端口后面加上次配置的值。在Spring Security的配置类 中配置 .servletPath() 是 mvcMatchers()返回值特有的方法,在servletPath()中配置了 servletPath 后,mvcMatchers()直接写 SpringMVC 中@RequestMapping()中设置的路径即可,如下两种写法等效:
.mvcMatchers("/test").servletPath("/xxxx").permitAll() .antMatchers("/xxxx/test").permitAll()
资源服务器配置
之前使用的默认配置所有的资源都需要授权后才能访问,如下:
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
修改如下:
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/test","/uaa").and()
.authorizeRequests().antMatchers("/test").permitAll()
.anyRequest().authenticated();
}
如上,我们配置资源/test不需要授权就可以访问,其它任何资源都需要授权后才可以访问。
WebSecurity配置
同上一篇,不变。
测试一
完善一下测试类,完整代码如下:
@RestController
public class TestController {
@RequestMapping(value = "/uaa")
public String test() {
return "oauth";
}
@RequestMapping(value = "/ignore")
public String ignore() {
return "ignore";
}
@RequestMapping(value = "/test")
public String test1() {
return "test";
}
@RequestMapping(value = "/no")
public String no() {
return "no";
}
}
测试
访问 localhost:9004/ignore 可以直接访问,因为在WebSecurity中配置了忽略。
访问 localhost:9004/test 可以直接访问,因为在资源服务器中配置了此资源permitAll()。
访问 localhost:9004/no 需要授权才可以访问,如果没有WebSecurity的配置,是可以直接访问的,但是因为有WebSecurity的默认配置(所有资源都需要认证访问)所以不能直接访问。
从上面还可以看出另一个问题,那就是优先级的问题,当资源服务器和WebSecurity同时存在的时候,资源服务器的配置优先级更高,因为在资源服务器中配置的资源/test是可以直接访问的。
测试二
修改资源服务器配置如下:
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/test","/uaa","/test1").and()
.authorizeRequests().antMatchers("/test").permitAll()
.anyRequest().authenticated();
}
完善一下测试类,完整代码如下:
@RestController
public class TestController {
@RequestMapping(value = "/uaa")
public String test() {
return "oauth";
}
@RequestMapping(value = "/ignore")
public String ignore() {
return "ignore";
}
@RequestMapping(value = "/test")
public String test1() {
return "test";
}
@RequestMapping(value = "/no")
public String no() {
return "no";
}
@RequestMapping(value = "/test1")
public String test2() {
return "test1";
}
}
测试
访问 localhost:9004/ignore 可以直接访问,因为在WebSecurity中配置了忽略。
访问 localhost:9004/test 可以直接访问,因为在资源服务器中配置了此资源permitAll()。
访问 localhost:9004/test1 需要授权才可以访问。
访问 localhost:9004/no 可以直接访问。
虽然/test1在WebSecurity中设置了permitAll(),在资源服务器中配置需要授权才能访问,结果是需要授权才可以访问,可以得出结论资源服务器的配置优先于WebSecurity。
至于/no可以直接访问,因为WebSecurity没使用默认配置拦截所有,这里就以资源服务器中配置的为准,而资源服务器中/no不在antMatchers()之中可以直接访问。
WebSecurityConfigurerAdapter与ResourceServerConfigurerAdapter区别
1.ResourceServerConfigurerAdapter用于保护oauth要开放的资源(哪些需要token验证后才能访问),主要作用于client端以及token的认证(Bearer auth)。
2.WebSecurityConfigurerAdapter主要作用于用户的登录(form login,Basic auth),不用设置拦截oauth要开放的资源,如果同时设置了对某一资源的访问控制,会以ResourceServerConfigurerAdapter设置的为准,因为ResourceServerConfigurerAdapter优先级更高,他会优先处理,而WebSecurityConfigurerAdapter会失效;