前言

  这篇是很久之前学习Spring Security整理的博客,发现浏览量都1000多了,一个赞都没有,那说明写得确实不怎么样,哈哈。应该很多初学者对这个接口存在疑问,特别是如果学习这个框架之前还了解过Shiro,可能会因为这两个框架角色、权限的表示方式,产生困惑。现在重新整理一下。

GrantedAuthority接口

我们知道UserDeitails接口里面有一个getAuthorities()方法。这个方法将返回此用户的所拥有的权限。这个集合将用于用户的访问控制,也就是Authorization。

所谓权限,就是一个字符串。一般不会重复。

所谓权限检查,就是查看用户权限列表中是否含有匹配的字符串。

package org.springframework.security.core;

import java.io.Serializable;

public interface GrantedAuthority extends Serializable {
String getAuthority();
}

"角色"如何表示?与Shiro有何不同?

在Security中,角色和权限共用GrantedAuthority接口,唯一的不同角色就是多了个前缀"ROLE_",而且它没有Shiro的那种从属关系,即一个角色包含哪些权限等等。在Security看来角色和权限时一样的,它认证的时候,把所有权限(角色、权限)都取出来,而不是分开验证。

所以,在Security提供的UserDetailsService默认实现JdbcDaoImpl中,角色和权限都存储在auhtorities表中。而不是像Shiro那样,角色有个roles表,权限有个permissions表。以及相关的管理表等等。

GrantedAuthority接口的默认实现SimpleGrantedAuthority

package org.springframework.security.core.authority;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert; public final class SimpleGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = 500L;
private final String role; public SimpleGrantedAuthority(String role) {
Assert.hasText(role, "A granted authority textual representation is required");
this.role = role;
} public String getAuthority() {
return this.role;
} public boolean equals(Object obj) {
if (this == obj) {
return true;
} else {
return obj instanceof SimpleGrantedAuthority ? this.role.equals(((SimpleGrantedAuthority)obj).role) : false;
}
} public int hashCode() {
return this.role.hashCode();
} public String toString() {
return this.role;
}
}

注意,在构建SimpleGrantedAuthority对象的时候,它没有添加任何前缀。所以表示"角色"的权限,在数据库中就带有"ROLE_"前缀了。所以authorities表中的视图可能是这样的。

角色和权限能否分开存储?角色能不能不带"ROLE_"前缀

当然可以分开存储,你可以定义两张表,一张存角色,一张存权限。但是你自定义UserDetailsService的时候,需要保证把这两张表的数据都取出来,放到UserDails的权限集合中。当然你数据库中存储的角色也可以不带"ROLE_"前缀,就像这样。

 

但是前面说到了,Security才不管你是角色,还是权限。它只比对字符串。

比如它有个表达式hasRole("ADMIN")。那它实际上查询的是用户权限集合中是否存在字符串"ROLE_ADMIN"。如果你从角色表中取出用户所拥有的角色时不加上"ROLE_"前缀,那验证的时候就匹配不上了。

所以角色信息存储的时候可以没有"ROLE_"前缀,但是包装成GrantedAuthority对象的时候必须要有。

权限检查/访问控制方式

权限检查有两种方式,一种是在配置类中,指定粗粒度的访问控制,另一种是使用注解细粒度的控制访问。

粗粒度访问控制,所有URL以"/admin"开头的用户必须拥有角色"ADMIN"才能访问。实际上操作的时候hasRole表达式,会判断参数是否包含"ROLE_"前缀,如果没有则加上去,然后再去校验。有这个前缀则直接校验。

protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.antMatchers("/user/**").access("hasRole('USER')")
.anyRequest().authenticated(); }

细粒度的访问控制

注:需要使用注解@EnableGlobalMethodSecurity(prePostEnabled=true) 开启

@PreAuthoritze("hasAuthority('readArtical')")
public List<Artical> getAll() {
//...
}

这个注解,会从SecurityContext中取出Authencation对象,然后再取出Collection<GrantedAuthority> authorites集合。然后比对当前用户是否有权限"readArtical"。实际上就是比对集合中是否有那个GrantedAuthority的getAuthority()方法返回的字符串与"radArtical"匹配。

 
 

【详解】GrantedAuthority(已授予的权限)的更多相关文章

  1. 网卡配置文件详解 用户管理与文件权限篇 文件与目录权限 软连接 tar解压命令 killall命令 linux防火墙 dns解析设置 计划任务crond服务 软件包安装 阿里云 yum源 安装

    Linux系统基础优化及常用命令 Linux基础系统优化 引言没有,只有一张图. Linux的网络功能相当强悍,一时之间我们无法了解所有的网络命令,在配置服务器基础环境时,先了解下网络参数设定命令. ...

  2. tomcat 详解五 tomcat页面设置访问权限

    转自:http://blog.knowsky.com/191233.htm 在web应用中,对页面的访问控制通常通过程序来控制,流程为:登录 -> 设置session -> 访问受限页面时 ...

  3. Cron 表达式详解(已整理、很清晰)

    Cron表达式是一个字符串,字符串分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: Seconds Minutes Hours DayofMonth Month DayofWeek ...

  4. Linux文件权限与属性详解 之 一般权限

    目录 一般属性 1. iNode: 3152621 2. 文件类型 3.文件访问权限 4. 链接数目: 5. 文件所有者 6. 文件所属组 7. 文件大小 8. 修改时间 9. 文件名称 Linux文 ...

  5. Linux文件权限与属性详解 之 ACL

    Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...

  6. MySQL权限授权认证详解

    MySQL权限授权认证详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL权限系统介绍1>.权限系统的作用是授予来自某个主机的某个用户可以查询.插入.修改.删除 ...

  7. MySQL权限详解

    MySQL权限级别介绍 MySQL权限级别 全局性的管理权限,作用于整个MySQL实例级别 数据库级别的权限,作用于某个指定的数据库上或者所有的数据库上 数据库对象级别的权限,作用于指定的数据库对象上 ...

  8. Linux 用户及权限详解

    Linux 用户及权限详解 用户 , 组 ,权限 安全上下文(secure context): 权限: r,w,x 文件: r : 可读,可以使用类似cat 等命令查看文件内容. w : 可写,可以编 ...

  9. Linux文件权限与属性详解 之 SUID、SGID & SBIT

    Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...

随机推荐

  1. Hausdorff Distance(豪斯多夫距离)

    Hausdorff Distance(豪斯多夫距离) 参考博客:http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/98/normand/ma ...

  2. Codeforces Round #265 (Div. 2) D. Restore Cube 立方体判断

    http://codeforces.com/contest/465/problem/D 给定8个点坐标,对于每个点来说,可以随意交换x,y,z坐标的数值.问说8个点是否可以组成立方体. 暴力枚举即可, ...

  3. ios 百度地图,火星坐标,地球坐标互转

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  4. ubuntu 安装CUDA 8.0

    安装CUDA 8.0 1) 在终端运行指令 sudo sh cuda_8.0.44_linux.run --no-opengl-libs 不加这个选项会进入循环登陆 2) 之后是一些提示信息,输入ac ...

  5. 如何把jar包发布到maven私服

    1.格式 mvn deploy:deploy-file -DgroupId=com.qiyi -DartifactId=sphinx -Dversion=1.0 -Dpackaging=jar -Df ...

  6. CentOS 7安装fail2ban+Firewalld防止SSH爆破与CC攻击

    准备工作 1.检查Firewalld是否启用 #如果您已经安装iptables建议先关闭 service iptables stop #查看Firewalld状态 firewall-cmd --sta ...

  7. [转载]DevOps建立全生命周期管理

    全生命周期管理(ALM)领域作为企业DevOps实践的总体支撑,应该说是DevOps领域中最为重要的实践领域,也是所有其他实践的基础设施.现在很多企业都非常重视CI/CD自动化工具的引入和推广,但是对 ...

  8. JS学习笔记8_错误处理

    1.错误处理语法:(js没有异常exception一说,都是错误error) try{ //throw new Error(msg); //throw '错误'; //throw false; //t ...

  9. C#调用接口注意要点

    在用C#调用接口的时候,遇到需要通过调用登录接口才能调用其他的接口,因为在其他的接口需要在登录的状态下保存Cookie值才能有权限调用, 所以首先需要通过调用登录接口来保存cookie值,再进行其他接 ...

  10. WPF实战案例-MVVM模式下在Xaml中弹出窗体

    相信很多学习和开发wpf项目的同学都了解过mvvm模式,同样,在mvvm模式下会有一个不可忽视的问题,就是怎么在xaml中弹出窗体,而不破坏MVVM本身的结构. 关于弹出窗体的方式还是很多的,本文先讲 ...