使用shiro做权限管理的学习笔记整理
Shiro权限管理
参考:https://www.cnblogs.com/jpfss/p/8352031.html
Shiro解决的问题
授权和鉴别的问题:Authenrization(授权) Authentication(证明)
关键对象
Subject:主体
访问系统的用户,可以是用户、程序等
Principal:身份信息
主体(subject)进行身份认证的标识 ,具有唯一性。如:用户名、手机号、邮箱地址等
credential:凭证信息
只有主体自己知道的安全信息。如:密码、证书等
授权
主体 ------ 》身份认证------- 》分配权限 ------ 》访问系统的资源
授权操作
who: 主体是什么
what:主体要操作什么资源
how: 主体对资源进行什么操作
总结:who 对 what 进行 how操作
权限的分类
- 粗颗粒
对资源类型的权限 - 细颗粒
对资源实例的权限
权限模型
用户 (账号,密码)
角色(角色名称,角色id)
权限(权限名称,资源名称,资源url)
用户与角色关系
角色与权限关系
权限分配
- 主体只允许在权限范围内对资源进行操作
- 权限分配的数据通常需要持久化 ,根据上边的数据模型创建表并将用户的权限信息存储在数据库中
基于角色的访问控制
是以角色为中心进行访问控制
主体.hasRole("总经理角色id")
如:主体的角色为总经理
总经理可以查询企业运营报表,查询员工工资信息
判断主体的角色 = 总经理: ----->查询工资
现在我给部门经理也开放了查询工资的权限,需要更该代码,判断如果角色是部门经理,也可以进行查询操 作,因为需要更改代码,系统的可用性差。
主体.hasRole("总经理角色id") || 主体.hasRole("部门经理角色id")
基于资源的访问控制
是以资源为中心进行访问控制
如:主体.hasPermission("查询工资权限标识")
粗颗粒度
粗颗粒度:对资源类型的管理,控制到菜单、按钮、方法
例如:用户具有用户管理的权限,具有导出订单明细的权限
对系统功能操作使用统一的粗颗粒度的权限管理
细颗粒度
细颗粒度:对资源实例的控制 ,控制到数据级别的权限
例如:用户只允许修改本部门的员工信息,用户只允许导出自己创建的订单明细
基于url拦截的实现
原理: 将系统操作的每个url配置在权限表中,将权限对应到角色,将角色分配给用户,用户访问系统功能通过Filter进行过虑,过虑器获取到用户访问的url,只要访问的url是用户分配角色中的url则放行继续访问。
1.用户访问系统的资源 ------ 》经过身份拦截器-------》判断用户访问的资源url是否是公共资源-------》如果是,则予以放行 ------》如果不是 ------- 》对用户的身份进行验证-------》判断用户是否有session-------->有------>进入权限拦截器-------》没有,跳转登录页面,并将用户的账号,密码以及权限放在session中 ------ 》重新访问系统资源 ------- 》经过权限拦截器 ------->获取用户的资源url判断是否是公共资源 ------ 》如果是,直接访问 ------ 》如果不是,根据用户session中的权限,判断用户是否拥有访问该资源url的权限 ------ 》如果没有 ------->返回拒绝页面
用户登录(将用户的账号,密码,以及包含的而所有资源url放在session中)
身份认证拦截器(访问资源时判断是否访问公共资源,如如不是,则进行身份认证,即判断sessison是否存在)
权限认证拦截器(当用户通过身份认证后,再判断用户是否有访问该资源url的权限)
身份认证拦截器
Implement HandlerIntrceptor类
重写HandlerIntrceptor的PreHandle(request,resonse,Object handler)方法
使用权限框架的好处
1.节省系统开发时间
2.提供了完善的认证和授权功能
shiro的介绍
shiro:
- 将软件系统的安全认证相关的功能抽取出来
- 实现用户身份认证,权限授权、加密、会话管理等功能
- 是一个通用的安全认证框架
shiro就可以非常快速的完成认证、授权等功能
Shiro的架构
subject :
- subject记录了当前操作用户 ,可能是一个通过浏览器请求的用户,也可能是一个运行的程序
- subject是shiro的一个接口,定义了很多认证授相关的方法
- 外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
SecurityManager :安全管理器
- 对全部的subject进行安全管理,它是shiro的核心
- 通过SecurityManager可以完成subject的认证、授权
- SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理
Authenticator :认证器
- Authenticator是一个接口 ,shiro提供ModularRealmAuthenticator实现类
Authorizer :授权器
- 认证器认证通过 ,通过授权器判断用户是否有此功能的操作权限
realm :获取用户权限数据
- 比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
- 在realm中还有认证授权校验的相关的代码
sessionManager :会话管理
- 它不依赖web容器的session ,实现单点登录
SessionDAO :会话dao
- 对session会话操作的一套接口
- 如要将session存储到数据库,可以通过jdbc将会话存储到数据库
CacheManager :缓存管理
- 将用户权限数据存储在缓存
Cryptography :密码管理
- shiro提供了一套加密/解密的组件
- 比如提供常用的散列、加/解密等功能
Shiro的使用
引入jar包
shiro-core:核心包
shiro-web:与web整合
shiro-spring :与spring整合
shiro-ehcache :
shiro-quartz :任务调度quartz整合
注:可使用shiro-all 导入全部的包
引入shiro.ini文件
shiro的认证流程
securitymanger(构建securitymanger环境)--------》subject.login()(提交认证) ----------> securitymanger.login() (执行认证) --------》Authenticator (执行人认证) -----》Realm(根据身份获取验证消息)
shiro项目的搭建
(构建securitymanger对象)
创建factory 关联shiro配置文件 ------>通过工厂创建securitymanger ------》将securitymanger运行到环境中
------- 》 创建subject对象subject.login()(提交认证)
生成用户的token令牌 ------- 》将用户的令牌放在subject.login(token)中
执行认证,判断用户的身份
subject.isAuthenticated()
Authenticator(subject.isAuthenticated())的实现 :
- ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码 ,这里使用的是IniRealm(shiro自带)
- IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过
自定义Realm
- Shiro自带的IniRealm,是从ini配置文件中读取用户的信息
- 从系统的数据库中读取用户信息,所以需要自定义realm
- 自定义的realm继承AuthorizingRealm。(授权)
AuthorizingRealm的方法:boolean support(Authentication Token) // 支持UserPaswwordToken
AuthenticationInfo doGetAuhenticationInfo(AuthenticationToken Token) //认证
doGetAuthenticationInfo中方法的实现:
获取Token的username数据,--------》 拿token的username到数据库中去比对,-----》比对成功在从数据库中取出password与token的password比对---------》返回验证信息,由父类返回AuthenticationInfo------>SimpleAuthenticationInfo(username,password,getName())Authorization doGetAuthorizationInfo(principalCollection pricipal )//授权
String getName()
String getName(){
return "customRealm1";
}
自定义Realm的shiro.ini的配置
shiro-realm.ini文件
[main]
#自定义 realm,自定义的realm的类的路径
customRealm=cn.itcast.shiro.authentication.realm.CustomRealm1
#将realm设置到securityManager
securityManager.realms=$customRealm
散列算法
作用:生成一段文本的摘要信息
特点:不可逆,将内容可以生成摘要,无法将摘要转成原始内容
用途:常用于对密码进行散列
常用的散列算法:MD5、SHA
散列算法的实现:原始数据+salt(盐:即一个随机数) -------- 》生成一个散列值
例:11111(原始数据)+ salt(随机数) ---------》96e79218965eb72c92a549dd5a330112 (散列值)
使用 new Md5Hash()实现散列:
String hh = new Md5Hash("11111").toString(): 不加盐散列
String hh = new Md5Hash("1111","eteokeus",1.toString()):加盐散列
使用SimpleHash散列:
String hh = new SimpleHash("MD5","11111","eteokeus",1).toString()
散列算法在Realm的使用
将盐和散列后的值存在数据库中 ,自动从数据库取出盐和加密后的值,由shiro完成密码校验
增加散列算法后 shiro.ini文件的配置
shiro-cryptography.ini
shiro的授权方式
编程式:通过写if/else 授权代码块完成
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}
注解式:通过在执行的Java方法上放置相应的注解完成
@RequiresRoles("admin")
public void hello() {
//有权限
}
JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成
<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>
第一种:编程式授权方式
shiro配置文件:shiro-permission.ini
用户的配置规则:用户=密码,角色1,角色2,....
角色的配置规则:角色=权限1,权限2,....
权限的配置规则:资源标识符:操作:资源实例标识符
例:user(资源标识符):update:001 :修改表user实例001的权限
user:*:001:操作001的所有权限
基于角色授权
判断用户是否有某一角色:subject.hasRole("role1")
判断用户是否有多个角色:subject.hasAllRoles(Arrays.list("roles1","roles2"))
检查权限,判断是否授权成功:checkRole("roles1") , checkRoles("roles1","roles2")
基于资源授权
判断用户是否拥有某一权限:subject.isPermitted("user:create")
判断用户是否拥有多个权限:subject.idPermittedAll("user:create","user:delete:1")
检查权限,判断是否授权成功:subject.permission("user:create"),subject.perssmions("user:create","user:delete:1")
自定义Realm,实现资源的授权
完善自定义类的AuthorizationInfo()方法
根据用户身份信息从数据库查询权限字符串,由shiro进行授权
AuthorizationInfo()方法的实现
AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
- 从Principal中获取用户的身份信息
String username = (String)principals.getPrimaryPrincipal() - 根据用户信息到数据库查询用户的权限
- 将用户的所有权限放在一个AuthorizationInfo中,返回一个SimpleAuthorization对象
return new SimpleAuthorizationInfo().addPermission("权限名称")
用户授权:
subject.isPermitted("user:delete")
授权流程:
执行subject.isPermitted("user:delete") -------- >通过ModularRealmAuthorizer进行授权 --------->调用realm获取权限信息 ------ >通过permissionResolver解析权限字符串,校验是否匹配
shiro与spring web项目的整合
1.取消原springmvc认证和授权拦截器
去掉springmvc.xml中配置的LoginInterceptor和PermissionInterceptor拦截器
2.加入shiro的jar包
shiro - spring
shiro - web
3.Web.xml中添加shiro filter
3.配置applicationContext-shiro.xml
securityManager:这个属性是必须的。
loginUrl:没有登录认证的用户请求将跳转到此地址进行认证,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。
unauthorizedUrl:没有权限默认跳转的页面。
shiro在认证过程中发生错误后将异常类的路径通过request返回
session由shiro管理,需要修改首页的controller方法,将session中的数据通过model传到页面
获取用户权限对象
List permissions = SysService.findSysPermissionList(usrename);
permissions[0].getPercode(): 获取权限内容
- 对controller开启AOP
在springmvc.xml中配置shiro注解支持,可在controller方法中使用shiro注解配置权限
5.权限注解控制@RequiresPermissions ("资源权限")
必须拥有“item:query”权限方可执行该方法
shiro与Ehcache整合
shiro每次授权都会通过realm获取权限信息,为了提高访问速度需要添加缓存,第一次从realm中读取权限数据,之后不再读取
1.添加Ehcache jar包
ehcache-core.jar
shiro - ehcache.jar
- 在pplicationContext-shiro.xml中配置缓存管理器
3.配置shiro-ehcache.xml
清空缓存
claerCache(principals)
当用户权限修改后,用户再次登陆shiro会自动调用realm从数据库获取权限数据,如果在修改权限后想立即清除缓存则可以调用realm的clearCache方法清除缓存。
realm中定义clearCached方法:
Session管理
在校验账号之前校验验证码
写一个类 extend FormAuthenticationFilter
在boolean onAccessDenied()中进行验证操作
FormAuthenticationFilter配置
修改applicationContext-shiro.xml中对FormAuthenticationFilter的配置。
在shiroFilter中添加filters:
formAuthenticationFilter定义
自动登录
用户登陆选择“自动登陆”本次登陆成功会向cookie写身份信息,下次登陆从cookie中取出身份信息实现自动登陆
1.用户身份实现java.io.Serializable接口
2.配置rememberMeManager
3.FormAuthenticationFilter配置
修改formAuthenticationFitler添加页面中“记住我checkbox”的input名称
主体进行身份验证后需要分配权限才能访问资源
使用springmvc实现身份验证拦截和权限分配拦截
身份验证拦截和权限拦截的实现
extend HandelerInteceptor 实现preHandle()方法-------》在该方法里判断访问的是否是公有资源-------》是,则予以访问------》不是 则判断是否登录,即session是否有数据 ------>没有,跳转到登录页面 ------>有 ------》到达权限认证过滤器--------》判断用户访问的是否是公有资源 -----》是,直接访问-------》不是,判断是否是经过身份验证就可以访问的资源------->不是,根据用户的id获取用户的所有权限------》判断用户访问的资源url是否在用户的权限里
登录时对用户的账号密码进行认证
首先获取session中的验证码,判断验证码是否相等,------》根据用户的账号查询用户的信息 判断用户是否存在 ------》进而查询用户的权限信息,菜单信息 ------》将用户的username,password,权限菜单、权限url等记入activeUser类,并写入session
使用shiro实现身份验证拦截和权限分配拦截
将用户名和密码配置在shiro.ini文件中,从配置文件中读取用户信息
关联shiro.ini文件,创建Sercuritymanger工厂 ----- 》从工厂中创建一个securitymanger ------>将securitymanger运行到环境中 ------》创建subject --------》设置用户登录的Token(username,password) ------- >拿到用户的token ------- >subject.login(token) ------->使用subject.isAuthenticated()判断用户是否存在,底层调用realm从ini配置文件取用户真实的账号和密码 , IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。
系统的数据库中读取用户信息
获取认证信息:
Sysuer sysuer = SysService.findSysuserByUsercode("usercode")
使用shiro做权限管理的学习笔记整理的更多相关文章
- 2018/09/05《涂抹MySQL》【权限管理】学习笔记(二)
读 第四章<管理MySQL库与表> 第五章<MySQL的权限管理> 总结 1:当配置好 MySQL 数据库后,发现有几个默认的库,他们的意义和作用?(这里只做简单了解,之后用到 ...
- Dubbo学习系列之九(Shiro+JWT权限管理)
村长让小王给村里各系统来一套SSO方案做整合,隔壁的陈家村流行使用Session+认证中心方法,但小王想尝试点新鲜的,于是想到了JWT方案,那JWT是啥呢?JavaWebToken简称JWT,就是一个 ...
- springBoot2.0 配置shiro实现权限管理
一.前言 基于上一篇springBoot2.0 配置 mybatis+mybatisPlus+redis 这一篇加入shiro实现权限管理 二.shiro介绍 2.1 功能特点 Shiro 包含 10 ...
- SpringBoot&Shiro实现权限管理
SpringBoot&Shiro实现权限管理 引言 相信大家前来看这篇文章的时候,是有SpringBoot和Shiro基础的,所以本文只介绍整合的步骤,如果哪里写的不好,恳请大家能指出错误,谢 ...
- Laravel5做权限管理
关于权限管理的思考 最近用laravel设计后台,后台需要有个权限管理.权限管理实质上分为两个部分,首先是认证,然后是权限.认证部分非常好做,就是管理员登录,记录session.这个laravel中也 ...
- 【shiro】(5)---基于Shiro的权限管理
基于Shiro的权限管理项目搭建 前面写了四篇有关权限的文章,算是这篇文章的铺垫了.这篇文章采用 开发环境 JDK1.8 Eclipse Mav ...
- SpringBoot与Shiro整合权限管理实战
SpringBoot与Shiro整合权限管理实战 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] *观看本文章需要有一定SpringBoot整合经验* Shiro框架简介 Apach ...
- spring-boot-plus集成Shiro+JWT权限管理
SpringBoot+Shiro+JWT权限管理 Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以 ...
- 使用Laravel5做权限管理
https://www.imooc.com/article/18250 关于权限管理的思考 最近在用laravel设计后台,后台需要有个权限管理.权限管理实质上分为两个部分,首先是认证,然后是权限.认 ...
随机推荐
- jmeter-定时器使用
在一般性能测试过程中,往往在前一个请求之后等待一段时间再执行下一个请求,这时会用到定时器. 以下列举常用的3中: 1.固定定时器: 2.
- lnmp安装mysql
lnmp安装mysql 下载lnmp wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz 解压 tar ‐xf lnmp1..tar.gz 安装数据库 ./i ...
- vue 自定义侧边栏 递归无限子级菜单
有很多网站会涉及到导航栏,我自己在开发中用的是element导航组件,并且自定义事件,给大家分享一下. 1.使用递归方法,无限循环子级菜单. 2.使用组件封装,维护方便. 3.使用index作为路由跳 ...
- 百万年薪python之路 -- 前端CSS基础介绍
一. CSS介绍 CSS定义 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素,给HTML设置样式,让它更加美观. 语法结构 div{ color: green ...
- 百万年薪python之路 -- python2和python3的区别
python2和python3的区别: python2获取的是整数 python3获取的是浮点数 print函数:(Python3中print为一个函数,必须用括号括起来:Python2中print为 ...
- 【MongoDB详细使用教程】五、MongoDB的数据库管理
目录 1.数据库安全 1.1.创建管理员账号和密码 1.2.设置服务状态为需要验证用户 1.3.创建用户账户和密码 1.4.忘记密码/修改密码 2.主从服务器 2.1.创建服务器目录,用于分别存放主从 ...
- 个人记账app(一)需求设计
时间如流水,只能流去不流回. 学历代表你的过去,能力代表你的现在,学习能力代表你的将来. 学无止境,精益求精. 一.开发背景 Android应用市场记账的app那么多,我为什么还要再开发一个呢?重复造 ...
- 从Go语言编码角度解释实现简易区块链——实现交易
在公链基础上实现区块链交易 区块链的目的,是能够安全可靠的存储交易,比如我们常见的比特币的交易,这里我们会以比特币为例实现区块链上的通用交易.上一节用简单的数据结构完成了区块链的公链,本节在此基础上对 ...
- linux下安装配置svn服务器
linux下安装配置svn服务器 1. svn服务器安装 将subversion-1.4.0.tar.gz和subversion-deps-1.4.0.tar.gz传到服务器. tar xfvz su ...
- 【问题记录】VMware Tools是灰色的,不能安装
一.VMware Tools简介 VMware Tools 中包含一系列服务和模块,可在 VMware 产品中实现多种功能,从而使用户能够更好地管理客户机操作系统,以及与客户机操作系统进行无缝交互. ...