shiro学习笔记_0500_授权
1,授权:给身份认证通过的人,授予他可以访问某些资源的权限。
2,权限粒度:分为粗粒度和细粒度。
粗粒度:例如对 user 的 crud,也就是通常所说的对表的操作。
细粒度:对表中记录的操作。如 只允许查询id为1的user的工资。Shiro一般管理的是粗粒度的权限。比如,菜单,按钮,url。一般细粒度的权限是通过业务来控制的。
3,角色:权限的集合。
角色有两个概念:
隐式角色,好像就是说传统的基于角色的访问控制。但是如果想添加或删除一个角色,或者重新定义一个角色的行为,需要修改大量代码,维护麻烦。
显式角色,基于资源的访问控制。
Shiro 团队提倡使用权限和显式角色,两者区别看这个家伙的文章:rbac新解
4,权限表示规则:资源:操作:实例。可以用通配符表示。
如:user:add 表示对user有添加的权限;user:* 表示对user有所有操作的权限;user:delete:100表示对user标识为100的记录有删除的权限。
5,shiro中的权限流程:

=======================================================================
6,例子程序:
(认证使用ini配置)
新建maven项目,项目结构:

maven依赖:
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency> <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
log4j配置:
log4j.rootLogger=info, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
shiro.ini配置:
定义了两个用户: zhangsan/1111,lisi/1111,两个角色:role1,role2,role1有对user的add、update、delete权限,role2有对user的所有权限。
[users]
zhangsan=1111,role1
lisi=1111,role2
[roles]
role1=user:add,user:update,user:delete
role2=user:*
测试程序:
package com.lhy.shiro; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory; public class AuthorizationDemo { public static void main(String[] args) {
//1,创建SecurityManager工厂 读取shiro配置文件
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2 通过securityManager工厂获取SecurityManager实例
SecurityManager securityManager = factory.getInstance();
//3 将SecurityManager 对象设置到运行环境
SecurityUtils.setSecurityManager(securityManager);
//4 通过SecurityUtils获取主体subject
Subject subject = SecurityUtils.getSubject();
try {
//5.假设登录名是zhangsan 密码是1111
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","1111");
//6,登录,进行用户身验证
subject.login(token);
//通过subject判断用户是否通过验证
if(subject.isAuthenticated()){
System.out.println("用户登录成功!");
}
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名或密码错误!");
}catch (IncorrectCredentialsException e) {
System.out.println("用户名或密码错误!");
} //****************基于【角色】的授权 *********************
//hasRole判断一个权限
boolean flag = subject.hasRole("role1");
System.out.println(flag); /**
* hasAllRoles:判断是否有给定的【全部角色】
* 参数类型:Collection<String>
* 返回 boolean
*/
flag = subject.hasAllRoles(Arrays.asList("role1","role2","role3"));
System.out.println("授权-hasAllRoles方法-是否有 role1,role2,role3全部角色---"+flag); /**
* hasRoles方法,逐个判断有给定【角色中的哪些】,返回boolean[]
* 参数类型:List<String>
*/
boolean[] flags = subject.hasRoles(Arrays.asList("role1","role2"));
for (int i = 0; i < flags.length; i++) {
System.out.println("授权--hasRoles--判断有给定角色中的哪些:"+flags[i]);
} /**
* hasRole 方法没有权限会返回false,不会抛异常,checkRole方法会抛异常
* 检查权限,没有相应角色会抛异常UnauthorizedException
*/ //检查一个权限
subject.checkRole("role2");
/**
* 检查多个权限
* 参数类型:1,可变参数String... ,2, Collection<String>
*/
subject.checkRoles("role1","role2");
subject.checkRoles(Arrays.asList("role1","role2")); //****************基于【资源】的授权 ********************* //isPermitted:判断单个权限:
boolean permitted = subject.isPermitted("user:add");
System.out.println("基于资源的权限--subject是否有-user:add权限-"+permitted);
/**
* isPermitted:判断是否有多个角色中的某些
* 参数类型:String... 可变参数
* 返回:boolean[]
*/
flags = subject.isPermitted("user:add","user:update","user:read");
for (int i = 0; i < flags.length; i++) {
System.out.println(flags[i]);
} /**
* isPermittedAll:判断是否有给定的【全部权限】
* 参数类型:String... permissions可变参数
* 返回:boolean
*/
flag = subject.isPermittedAll("user:add","user:update");
System.out.println(flag); /**
* 判断一个权限,会抛异常UnauthorizedException
*/
subject.checkPermission("user:read");
/**
* 判断多个权限:checkPermissions
* 参数类型:String... permissions
*/
subject.checkPermissions("user:add","user:update"); //7 退出
subject.logout(); }
}
shiro中的权限检查有三种方式:
a)编程式:
if(subject.hasRole("管理员")){
//操作某个资源
}
b)注解式:
@RequiresRoles("管理员")
public void list(){
//查询数据
}
c) 标签式:
<shiro:hasPermission name="user:update">
<a href="#">更新</a>
</shiro>
授权流程:
查看subject.isPermitted 源代码:

其实调用的是DelegatingSubject类的isPermitted,DelegatingSubject 又交给了securityManager

ctrl+t,查看类关系,可知,securityManager是SecurityManager接口的实现类DefaultSecurityManager,而DefaultSecurityManager类继承了好多个父类


具体的是DefaultSecurityManager的父类 AuthorizingSecurityManager里有个Authorizer,

其具体调用的是ModularRealmAuthorizer 的方法,最终交给了realm

ModularRealmAuthorizer中有一个PermissionResolver,ctro+t 查看该Realm:它其实调用的是AuthorizingRealm,

而AuthorizingRealm里,有PermissionResolver,而实际调用的是其实现类 WildcardPermissionResolver

查看WildcardPermission:里边出现了熟悉的字符:就是来解析 shiro的权限的字符的。

总结:
a) 获取subject主体
b)判断主题是否通过认证
c)调用subject.isPermitted*/hasRole*进行授权的判断
i)subject是由其实现类DelegatingSubject 来调用方法的,该类将处理交给了SecurityManager。
ii)securityManager 是由其实现类 DefaultSecurityManager 来进行处理的,该类的isPermitted 来处理,其本质是父类AuthorizingSecurityManager来处理的。该类将处理交给了authorizer(授权器)
iii)Authorizer 由其实现类 ModularRealmAuthorizer 来处理,该类可以调用对应的Realm来获取数据,在该类有PermissionResolver 对权限字符串进行解析,在对应的Realm中也有对应的 PermissionResolver 交给 WildcardPermissionResolver 该类调用WildPermission 来进行权限字符串的解析。
iv) 返回处理结果
shiro学习笔记_0500_授权的更多相关文章
- shiro学习笔记_0600_自定义realm实现授权
博客shiro学习笔记_0400_自定义Realm实现身份认证 介绍了认证,这里介绍授权. 1,仅仅通过配置文件来指定权限不够灵活且不方便.在实际的应用中大多数情况下都是将用户信息,角色信息,权限信息 ...
- Shiro:学习笔记(2)——授权
Shiro:学习笔记(2)——授权 Shiro的三种授权方式 编程式: Subject subject = SecurityUtils.getSubject(); if(subject.hasRole ...
- Shiro学习笔记(5)——web集成
Web集成 shiro配置文件shiroini 界面 webxml最关键 Servlet 測试 基于 Basic 的拦截器身份验证 Web集成 大多数情况.web项目都会集成spring.shiro在 ...
- Shiro学习笔记总结,附加" 身份认证 "源码案例(一)
Shiro学习笔记总结 内容介绍: 一.Shiro介绍 二.subject认证主体 三.身份认证流程 四.Realm & JDBC reaml介绍 五.Shiro.ini配置介绍 六.源码案例 ...
- Shiro 学习笔记(一)——shiro简介
Apache Shiro 是一个安全框架.说白了,就是进行一下 权限校验,判断下这个用户是否登录了,是否有权限去做这件事情. Shiro 可以帮助我们完成:认证.授权.加密.会话管理.与web 集成. ...
- Shiro学习笔记 三(认证授权)
第一种首先基于角色的权限控制 1.由于不断的创建SecurityFactory工程等步骤重复多次,所以应该将这些步骤封装成一个工具类 还是首先看一下目录结构 主要用到文件 首先贴一下工具类的方法 pa ...
- [shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39933993 shiro官网:http://shiro.apache.org/ shi ...
- shiro学习笔记_0100_shiro简介
前言:第一次知道shiro是2016年夏天,做项目时候我要写springmvc的拦截器,申哥看到后,说这个不安全,就给我捣鼓了shiro,我就看了下,从此认识了shiro.此笔记是根据网上的视频教程记 ...
- Shiro学习笔记四(Shiro集成WEB)
这两天由于家里出了点事情,没有准时的进行学习.今天补上之前的笔记 -----没有学不会的技术,只有不停找借口的人 学习到的知识点: 1.Shiro 集成WEB 2.基于角色的权限控制 3.基于权限的控 ...
随机推荐
- eclipse mac
在mac下安装eclipse,挺简单的.只是字体会发虚,有点麻烦. 安装完成后,双击eclipse图标,显示包内容,contents--info.plist,在</dist>前加<k ...
- SQL描述(2)
很久之前就想写出来,就是因为自己太懒,憋了怎么久.本文关于使用ORACLE分析函数对一些经济指标进行计算.表indi_value有3个关键的字段:indi_date,indi_value,indi_i ...
- Hibernate实体类注解的问题
刚刚和八千哥弄一个问题,这个很诡异的问题,困扰了我这么长时间.哎,说来惭愧. 用三大框架写毕设,结果今天获取前台数的时候,发现传值有个传不到. 我一开始用的是名为cows的数据,后来换了个数据库,加了 ...
- HTML5、CSS3与响应式Web设计入门(1)
HTML5与CSS3已经当仁不让的成为了这两年Web界最火爆的词,他们似乎在HTML4和CSS2统治了Web很多年之后的某一天突然爆发,然 后一直占据着所有Web开发者的视野.HTML5本身就是一个很 ...
- jenkins Build Flow job 输入参数获取和传递
jenkins Build Flow job 输入参数获取和传递 如果设置Build Flow的job,怎样获取手工输入的参数. 1. 指定构建参数 job配置中,勾选"参数化构建" ...
- linux学习之vi文件编辑命令
如果文件为只读则无法使用普通用户编辑,需要切换到root用户,具体名称可参考: https://www.cnblogs.com/huangwei1992/p/9493443.html vi文件编辑命令 ...
- Visual Studio 2013的新特性介绍
cnbeta新闻:微软正式发布Visual Studio 2013 RTM版,微软还发布了Visual Studio 2013的最终版本..NET 4.5.1以及Team Foundation Ser ...
- Beginning Asp.Net Security 读书笔记-----XSS
几个月前通过Veracode对代码进行动态和静态安全扫描,扫出了数以千计的安全bug,基本上都是top 10的,安全漏洞. 其中CWE80,CWE601数量最多.具体CWE的定义可参考http://c ...
- python中的函数(基础)
1.什么是函数 函数是指将一组数据的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用函数名即可 (函数就是对功能或者动作的封装) 2.函数的语法和定义 def 函数名() 函数体 调用: ...
- cnVCL的安装
cnVCL是cnpack组件中的不可视组件库,里面包含很多有用的组件,网址:http://www.cnpack.org/showdetail.php?id=739&lang=zh-cn 安装步 ...