我们前面讲的所有的例子,都是没有权限控制的,也就是只要登录就可以访问任何资源,不需要其它的权限。但是,现实生活中肯定不是这样。

比如你是普通员工,只能查看自己的工作记录;而部门经理作为领导,则可以查看整个部门员工的工作记录;再如企业老板,作为最大的权限拥有者,可以查看整个公司员工的工作记录。这就是所谓的权限控制,不同角色拥有的不同资源

而 Spring Security 框架最大的功用就在于此。当然,实现权限控制体系非常复杂,我们一步一步来,本次先讲一个如何通过注解实现权限控制需求。

Spring Security 配置类开启权限控制注解,即 @EnableGlobalMethodSecurity(prePostEnabled = true)

@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
    ......
}

在需要进行权限控制的 controller 方法上添加权限控制注解 @PreAuthorize

@PreAuthorize("hasRole('User')")
@RequestMapping("/index")
public String index() {
    return "/user/index";
}

这里解释一下 @PreAuthorize 注解的参数含义。先来看一下其注释:

spring security 403问题排查 spring security preauthorize_权限控制

从注释可以看到,value (可省略)属性是 Spring-EL 表达式类型的字符串。其值可参考类 SecurityExpressionRoot,这是Spring Security 框架封装的专门针对 Spring Security 框架本身的 Spring—EL表达式解析类。

spring security 403问题排查 spring security preauthorize_JAVA_02

分别介绍以下其中值选项。

  • hasRole,对应 public final boolean hasRole(String role) 方法,含义为必须含有某角色(非ROLE_开头),如有多个的话,必须同时具有这些角色,才可访问对应资源。
  • hasAnyRole,对应 public final boolean hasAnyRole(String... roles) 方法,含义为只具有有某一角色(多多个角色的话,具有任意一个即可),即可访问对应资源。
  • hasAuthority,对应 public final boolean hasAuthority(String authority) 方法,含义同 hasRole,不同点在于这是权限,而不是角色,区别就在于权限往往带有前缀(如默认的ROLE_)而角色只有标识
  • hasAnyAuthority,对应 public final boolean hasAnyAuthority(String... authorities) 方法,含义同 hasAnyRole,不同点在于这是权限,而不是角色,区别就在于权限往往带有前缀(如默认的ROLE_)而角色只有标识
  • permitAll,对应 public final boolean permitAll() 方法,含义为允许所有人(可无任何权限)访问
  • denyAll,对应 public final boolean denyAll() 方法,含义为不允许任何(即使有最大权限)访问
  • isAnonymous,对应 public final boolean isAnonymous() 方法,含义为可匿名(不登录)访问
  • isAuthenticated,对应 public final boolean isAuthenticated() 方法,含义为身份证认证后访问
  • isRememberMe,对应 public final boolean isRememberMe() 方法,含义为记住我用户操作访问
  • isFullyAuthenticated,对应 public final boolean isFullyAuthenticated() 方法,含义为非匿名且非记住我用户允许访问

设计者可选取适当的控制方式和级别进行控制,也可以事先定义好角色、权限等权限体系,供开发者使用。

接下来,启动系统,访问一下用户首页,看一下系统作何反应。

spring security 403问题排查 spring security preauthorize_User_03

果不其然,系统跳转到了403无权限页面(由于我们没有默认的403页面,也没有自定义403错误页面,所以系统展示报错信息页面)。于此同时,控制台也报了不允许访问的错误。

spring security 403问题排查 spring security preauthorize_JAVA_04

下面我们在配置文件中,给默认用户添加角色:User。

spring:
  security:
    user:
      name: zhangsan
      password: 123456
      roles:
        - User

 

再次启动系统,刷新一下页面,登录后,成功显示了用户个人中心页面。

spring security 403问题排查 spring security preauthorize_User_05

至此,用注解实现权限控制完成。

其它详细源码,请参考文末源码链接,可自行下载后阅读。

 

源码

 

github

 

https://github.com/liuminglei/SpringSecurityLearning/tree/master/12

 

gitee

 

https://gitee.com/xbd521/SpringSecurityLearning/tree/master/12