Spring Security的权限管理入门

515 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

Spring Security的权限管理(上)

\quadSpring Security的两大核心功能是认证和授权,身份认证,就是判断一个用户是否为合法用户的处理过程。Spring Security中支持多种不同方式的认证,但是无论开发者使用何种方式认证,都不会影响授权功能使用。因为SpringSecurity已经很好做到了认证和授权解耦。
\quad授权,即访问控制,控制哪些权限能访问哪些对应的资源。简单的理解授权就是根据系统提前设置好的规则,给用户分配可以访问某一个资源的权限,用户必须根据自己所持有的权限,去执行相应操作。
\quad权限管理核心概念是角色和权限,在用户认证成功之后会将当前登录的用户信息保存到Authentication对象中,Authentication 对象中存在getAuthorities()方法,用来返回当前登录用户具备的权限信息,也就是当前用户具有权限信息。该方法的返回值为Collection<?extends GrantedAuthority>,当需要进行权限判断时,就会根据集合返回权限信息调用相应方法进行判断。那么这个返回值该如何理解呢?

1. 理解角色和权限

\quad我们针对于授权的理解可以分为两种,一种基于角色权限管理(RBAC),另一种是基于资源权限管理。从设计的角度上看,角色和权限是两个完全不同的东西,可以理解为权限是一些具体操作(读操作,写操作),角色则是某些权限集合(一个角色可以拥有读操作/写操作/删除操作等权限)。举几个例子:

●基于角色权限设计就是:用户<=>角色<=>资源三者关系返回就是用户的角色。
●基于资源权限设计就是:用户<=>权限<=>资源三者关系返回就是用户的权限(某个资源对应的权限字符串)。
●基于角色和资源权限设计就是:用户<=>角色<=>权限<=>资源返回统称为用户的权限。

\quad需要注意的是:在Spring Security中,角色和权限在代码层面没有太大不同,都是可以理解为权限,它们处理方式基本一致,唯一的区别SpringSecurity在会自动给角色添加一个ROLE_前缀,而权限则不会自动添加。

2. 权限策略

2.1 基于URL的权限管理策略

\quad在基于URL的权限管理中,请求首先到达过滤器FilterSecurityInterceptor,实际上就是拦截请求URL地址,在其执行过程中,首先会由前置处理器去判断发起当前请求的用户是否具备相应的权限,如果具备,则请求继续向下走,到达目标方法并执行完毕。在响应时,又会经过FilterSecurityInterceptor过滤器,此时由后置处理器再去完成一些其他工作。配置起来很容易,举个例子:

//此处有三个controller对应三个权限
public class HelloController {

    @RequestMapping("/admin") //roles admin
    public String hello(){
        return "hello admin";
    }

    @RequestMapping("/dba") //roles admin
    public String abd(){
        return "hello abd";
    }

    @RequestMapping("/user") //roles admin
    public String user(){
        return "hello user";
    }
}

//配置类里
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .mvcMatchers("/admin").h```
hasAnyRole(String... roles)
```asRole("admin")
            .mvcMatchers("/dba").hasRole("dba")
            .mvcMatchers("/user").hasRole("user")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .csrf().disable();
}

\quad配置类里的方法mvcMatchers是用来进行URL的匹配。如果我写的是"/admin",则匹配的不仅是"/admin",还有"/admin/"以及"/admin.html",较广,适合SpringMVC的匹配。还有一个是antMatchers,它与mvcMatchers的区别是antMatchers只能进行精准匹配,也就是antMatchers("/admin")只能匹配"/admin"这一个url。最后一个是regexMatchers,它的优点是支持正则表达式,适合更加复杂的匹配规则。
\quadhasRole()是指含有某个角色才能访问对应的url,hasAnyRole(String... roles)的参数是可变的,可以传递多个,表示含有任何一个角色就可以访问对应的url。同理,hasAuthority和hasAnyAuthority也是一样的,只不过由角色变成了权限。

2.2 基于方法的权限管理策略

\quad基于方法的权限管理主要是通过AOP来实现的,Spring Security中通过MethodSecurityInterceptor 来提供相关的实现。不同在于FilterSecurityInterceptor只是在请求之前进行前置处理,MethodSecurityInterceptor 除了前置处理之外还可以进行后置处理。
\quad需要了解的是以下几个注解:
@EnabLeGLobaLMethodSecurity:EnableGLobaMethodSecurity该注解是用来开启权限注解:

@Configuration
@EnableGlobalMethodSecurity (prePostEnabLed=true , securedEnabled=true, jsr250EnabLed=true)
public class SecurityConfig extends WebsecurityConfigurerAdapter{}

\quad参数的含义如下:

  • perPostEnabLed: 开启Spring Security 提供的四个权限注解,@PostAuthorize、 @PostFilter、@PreAuthorize 以及@PreFilter。

@PostAuthorize: 在目前标方法执行之后进行权限校验。
@PostFiter:在目标方法执行之后对方法的诞回结果 进行过滤。
@PreAuthorize:在目标方法执行之前进行权限校验。
@PreFiter:在目前标方法执行之前对方法参数进行过滤。

  • securedEnabled: 开启Spring Security 提供的@Secured 注解支持,该注解不支持权限表达式

@Secured表示访问目标方法必须具各相应的角色。

  • jsr250EnabLed: 开启JSR-250 提供的注解,主要是@DenyALl、@PermitALl、@RoLesAll同样这些注解也不支持权限表达式

@DenyALl:拒绝所有访问。
@PermitAll:允许所有访问。
@RoLesAllowed:访问目标方法必须具备相应的角色。

\quad一般来说,基于方法的注解,只要设置prePostEnabLed=true就可以,满足大部分场景。具体的功能可以自己动手试试。