Shiro权限管理

参考:https://www.cnblogs.com/jpfss/p/8352031.html

Shiro解决的问题

授权和鉴别的问题:Authenrization(授权) Authentication(证明)

关键对象

Subject:主体

访问系统的用户,可以是用户、程序等

Principal:身份信息

主体(subject)进行身份认证的标识 ,具有唯一性。如:用户名、手机号、邮箱地址等

credential:凭证信息

只有主体自己知道的安全信息。如:密码、证书等

授权

主体 ------ 》身份认证------- 》分配权限 ------ 》访问系统的资源

授权操作

who: 主体是什么

what:主体要操作什么资源

how: 主体对资源进行什么操作

总结:who 对 what 进行 how操作

权限的分类

  1. 粗颗粒

    对资源类型的权限
  2. 细颗粒

    对资源实例的权限

权限模型

用户 (账号,密码)

角色(角色名称,角色id)

权限(权限名称,资源名称,资源url)

用户与角色关系

角色与权限关系

权限分配

  1. 主体只允许在权限范围内对资源进行操作
  2. 权限分配的数据通常需要持久化 ,根据上边的数据模型创建表并将用户的权限信息存储在数据库中

基于角色的访问控制

是以角色为中心进行访问控制

主体.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:

  1. 将软件系统的安全认证相关的功能抽取出来
  2. 实现用户身份认证,权限授权、加密、会话管理等功能
  3. 是一个通用的安全认证框架

shiro就可以非常快速的完成认证、授权等功能

Shiro的架构

subject :

  1. subject记录了当前操作用户 ,可能是一个通过浏览器请求的用户,也可能是一个运行的程序
  2. subject是shiro的一个接口,定义了很多认证授相关的方法
  3. 外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权

SecurityManager :安全管理器

  1. 对全部的subject进行安全管理,它是shiro的核心
  2. 通过SecurityManager可以完成subject的认证、授权
  3. SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理

Authenticator :认证器

  1. Authenticator是一个接口 ,shiro提供ModularRealmAuthenticator实现类

Authorizer :授权器

  1. 认证器认证通过 ,通过授权器判断用户是否有此功能的操作权限

realm :获取用户权限数据

  1. 比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
  2. 在realm中还有认证授权校验的相关的代码

sessionManager :会话管理

  1. 它不依赖web容器的session ,实现单点登录

SessionDAO :会话dao

  1. 对session会话操作的一套接口
  2. 如要将session存储到数据库,可以通过jdbc将会话存储到数据库

CacheManager :缓存管理

  1. 将用户权限数据存储在缓存

Cryptography :密码管理

  1. shiro提供了一套加密/解密的组件
  2. 比如提供常用的散列、加/解密等功能

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对象)

  1. 创建factory 关联shiro配置文件 ------>通过工厂创建securitymanger ------》将securitymanger运行到环境中

    ------- 》 创建subject对象

    subject.login()(提交认证)

  2. 生成用户的token令牌 ------- 》将用户的令牌放在subject.login(token)中

执行认证,判断用户的身份

subject.isAuthenticated()

Authenticator(subject.isAuthenticated())的实现 :

  1. ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码 ,这里使用的是IniRealm(shiro自带)
  2. IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过

自定义Realm

  1. Shiro自带的IniRealm,是从ini配置文件中读取用户的信息
  2. 从系统的数据库中读取用户信息,所以需要自定义realm
  3. 自定义的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)

  1. 从Principal中获取用户的身份信息

    String username = (String)principals.getPrimaryPrincipal()
  2. 根据用户信息到数据库查询用户的权限
  3. 将用户的所有权限放在一个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(): 获取权限内容

  1. 对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

  1. 在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做权限管理的学习笔记整理的更多相关文章

  1. 2018/09/05《涂抹MySQL》【权限管理】学习笔记(二)

    读 第四章<管理MySQL库与表> 第五章<MySQL的权限管理> 总结 1:当配置好 MySQL 数据库后,发现有几个默认的库,他们的意义和作用?(这里只做简单了解,之后用到 ...

  2. Dubbo学习系列之九(Shiro+JWT权限管理)

    村长让小王给村里各系统来一套SSO方案做整合,隔壁的陈家村流行使用Session+认证中心方法,但小王想尝试点新鲜的,于是想到了JWT方案,那JWT是啥呢?JavaWebToken简称JWT,就是一个 ...

  3. springBoot2.0 配置shiro实现权限管理

    一.前言 基于上一篇springBoot2.0 配置 mybatis+mybatisPlus+redis 这一篇加入shiro实现权限管理 二.shiro介绍 2.1 功能特点 Shiro 包含 10 ...

  4. SpringBoot&Shiro实现权限管理

    SpringBoot&Shiro实现权限管理 引言 相信大家前来看这篇文章的时候,是有SpringBoot和Shiro基础的,所以本文只介绍整合的步骤,如果哪里写的不好,恳请大家能指出错误,谢 ...

  5. Laravel5做权限管理

    关于权限管理的思考 最近用laravel设计后台,后台需要有个权限管理.权限管理实质上分为两个部分,首先是认证,然后是权限.认证部分非常好做,就是管理员登录,记录session.这个laravel中也 ...

  6. 【shiro】(5)---基于Shiro的权限管理

    基于Shiro的权限管理项目搭建 前面写了四篇有关权限的文章,算是这篇文章的铺垫了.这篇文章采用 开发环境           JDK1.8          Eclipse          Mav ...

  7. SpringBoot与Shiro整合权限管理实战

    SpringBoot与Shiro整合权限管理实战 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] *观看本文章需要有一定SpringBoot整合经验* Shiro框架简介 Apach ...

  8. spring-boot-plus集成Shiro+JWT权限管理

    SpringBoot+Shiro+JWT权限管理 Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以 ...

  9. 使用Laravel5做权限管理

    https://www.imooc.com/article/18250 关于权限管理的思考 最近在用laravel设计后台,后台需要有个权限管理.权限管理实质上分为两个部分,首先是认证,然后是权限.认 ...

随机推荐

  1. C#方法的定义、调用与调试

    本节内容 1.方法的由来: 2.方法的定义与调用: 3.构造器(一种特殊的方法): 4.方法的重载(Override): 5.如何对方法进行debug: 6.方法的调用与栈* *推荐书目:CLR vi ...

  2. redis之Scan

    scan 相比keys 具备有以下特点:1.复杂度虽然也是 O(n),但是它是通过游标分步进行的,不会阻塞线程;2.提供 limit 参数,可以控制每次返回结果的最大条数,limit 只是一个 hin ...

  3. MD5收集整理

    MD5如何生成的 百度百科 生成MD5 1.通过摘要生成MD5 MessageDigest md = MessageDigest.getInstance("MD5"); md.up ...

  4. 【Bug】解决 java.sql.SQLSyntaxErrorException 异常

    java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax 错误 错误详情: Caused by: java.sql. ...

  5. ElasticSearch - ElasticSearch和kinaba的简单使用

    ElasticSearch和kinaba的简单使用 ElasticSeatch 文档推荐 ElasticSearch 下载 (端口 9200) 安装好es,可以访问 http://localhost: ...

  6. Shiro learning - 入门学习 Shiro中的基础知识(1)

    Shiro入门学习 一 .什么是Shiro? 看一下官网对于 what is Shiro ? 的解释 Apache Shiro (pronounced “shee-roh”, the Japanese ...

  7. beanfactory中单例bean的初始化过程(一)

    Date 10.06 pm Point 完成beanfactory中单例bean的初始化 beanFactory.preInstantiateSingletons() 拿到所有的bean定义信息(在 ...

  8. JVM(6) 字节码执行引擎

    编译器(javac)将Java源文件(.java文件)编译成Java字节码(.class文件). 类加载器负责加载编译后的字节码,并加载到运行时数据区(Runtime Data Area) 通过类加载 ...

  9. node.js的File模块

    1.Node.js是什么? (1) Nodejs是为了开发高性能的服务器而诞生的一种技术 (2) 简单的说 Node.js 就是运行在服务端的 JavaScript,基于V8进行运行 (3) Node ...

  10. 设计模式C++描述----07.建造者(Builder)模式

    一. 概述 Builder 模式要解决的问题是:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分离开 来,这样做的好处就是通过一步 ...