Apache Shiro权限框架理论介绍

Apache Shiro权限管理框架介绍

Apache Shiro的官网地址如下:

http://shiro.apache.org/

Apache Shiro是一个简单易用且强大而灵活的开源Java安全框架,以下简称Shiro。它干净利落地处理身份认证、授权以及企业会话管理和加密。Shiro拥有易于理解的API,你可以快速且容易地使用它来保护任何应用程序——从最小的移动应用程序到最大的web和企业应用程序。

Shiro权限基础概念:

  • 安全实体:就是被权限系统保护的对象,比如工资数据。  
  • 权限:就是需要被校验的行为,比如查看、修改等。
  • 分配权限:把对某些安全实体的某些权限分配给某些人员。是向数据库里面添加数据、或是维护数据的过程
  • 权限验证(权限匹配):判断某个人员或程序对某个安全实体是否拥有某个或某些权限。从数据库中获取相应数据进行匹配的过程。
  • 权限的继承性:如果多个安全实体存在包含关系,而某个安全实体没有权限限制,则它会继承包含它的安全实体的相应权限。
  • 权限的最近匹配原则:如果多个安全实体存在包含关系,而某个安全实体没有权限限制,那么它会向上寻找并匹配相应权限限制,直到找到一个离这个安全实体最近的拥有相应权限限制的安全实体为止。如果把整个层次结构都寻找完了都没有匹配到相应权限限制的话,那就说明所有人对这个安全实体都拥有这个相应的权限限制。

Shiro 能做什么:

  • 认证:验证用户的身份
  • 授权:对用户执行访问控制:判断用户是否被允许做某事
  • 管理:在任何环境下使用 Session API,即使没有 Web 或EJB 容器。
  • 加密:以更简洁易用的方式使用加密功能,保护或隐藏数据防止被偷窥
  • Realms:聚集一个或多个用户安全数据的数据源
  • 单点登录(SSO)功能:为没有关联到登录的用户启用 "Remember Me“ 服务

Shiro 的主要功能架构图:

从上图中可以看到 Shiro 的四大核心部分:

  • Authentication(身份验证):简称为“登录”,即证明用户是谁。
  • Authorization(授权):访问控制的过程,即决定是否有权限去访问受保护的资源。
  • Session Management(会话管理):管理用户特定的会话,即使在非 Web 或 EJB 应用程序。
  • Cryptography(加密):通过使用加密算法保持数据安全

其中 Shiro 还提供了以下扩展:

  • Web Support:主要针对web应用提供一些常用功能。
  • Caching:缓存可以使应用程序运行更有效率。
  • Concurrency:多线程相关功能。
  • Testing:帮助我们进行测试相关功能
  • "Run As":一个允许用户假设为另一个用户身份(如果允许)的功能,有时候在管理脚本很有用。
  • "Remember Me" :记住用户身份,提供类似购物车功能。

Shiro 概念层架构的 3 个核心组件图:

  • Subject :正与系统进行交互的人,或某一个第三方服务。所有 Subject 实例都被绑定到(且这是必须的)一个SecurityManager 上。
  • SecurityManager:Shiro 架构的心脏,用来协调内部各安全组件,管理内部组件实例,并通过它来提供安全管理的各种服务。当 Shiro 与一个 Subject 进行交互时,实质上是幕后的 SecurityManager 处理所有繁重的Subject 安全操作,可以将其概念比作为是SpringMVC中的前端控制器。
  • Realms :本质上是一个特定安全的 DAO。当配置 Shiro 时,必须指定至少一个 Realm 用来进行身份验证或授权。Shiro 提供了多种可用的 Realms 来获取安全相关的数据。如关系数据库(JDBC),INI 及属性文件等。可以定义自己 Realm 实现来代表自定义的数据源。

Shiro 架构图:

  • Authenticator :执行对用户的身份验证(登录)的组件。Authenticator 从一个或多个 Realm 中获得数据以验证用户的身份。 若存在多个realm,则接口 AuthenticationStrategy 会确定什么样算是验证成功(例如,如果一个 Realm 成功,而其他的均失败,是否登录成功)。
  • Authorizer :权限管理器,主要用于用户的访问控制,验证用户能否访问应用中的受保护资源。
  • SessionManager :session管理器,可在任何应用或架构层一致地使用 Session API
  • SessionDAO:SessionManager 执行 Session 持久化(CRUD)操作。
  • CacheManager :对 Shiro 组件提供缓存支持。
  • Cryptography:Shiro 的 API 大幅度简化 Java API 中繁琐的密码加密
  • Realms:Shiro 通过 Realms 来获取相应的安全数据

Shiro 配置基础

Shiro 被设计成能够在任何环境下工作,从简单的命令行应用程序到企业群集应用。由于环境的多样性,使得 Shiro 可以使用多种配置机制。

users:

  • ini 配置:ini 实际上是一个文本配置,包含了由唯一命名的项来组织的键/值对。
  • [users] 部分允许定义一组静态的用户帐户
  • 每行的格式:username = password, roleName1, roleName2, …


roles:

  • [roles] 部分允许把定义在 [users] 部分中的角色与权限关联起来
  • 每行的格式:rolename = permissionDefinition1, permissionDefinition2, …
    • permissionDefinition 是一个任意的字符串,但大多数人将会使用符合 org.apache.shiro.authz.permission.WildcardPermission 格式的字符串。

注意:

  • 如果一个独立的 permissionDefinition 需要被内部逗号分隔(例如,printer:5thFloor:print,info),则需要用户双引号环绕该定义,以避免错误解析。  
  • 如果角色不想关联权限,则不需要在 [roles] 部分把它们列出来。只需定义在 [user] 部分中定义角色名就足以创建尚不存在的角色。
  • 仅定义非空的 [users] 或 [roles] 部分就将自动地触发org.apache.shiro.realm.text.IniRealm 实例的创建

Shiro 身份认证: Authentication

Authentication :身份验证——通过提交用户的身份和凭证给 Shiro,以判断它们是否和应用程序预期的相匹配。

基本概念:

  • Principals(身份):Subject 的 identifying attributes(标识属性)。比如我们登录提交的用户名。
  • Credentials(凭证):用来作为一种起支持作用的证据,此证据包含×××明。比如我们登录提供的密码

认证的基本步骤:

  • 收集Subjects 提交的Principals(身份)和Credentials(凭证);
  • 提交Principals(身份)和Credentials(凭证)进行身份验证;
  • 如果提交成功,则允许访问,否则重新进行身份验证或者阻止访问。
  • AuthenticationToken:Shiro 中代表提交的 Principals(身份) 和 Credentials (凭证) 的身份验证系统的最基本接口。
  • UsernamePasswordToken :AuthenticationToken 的接口的实现类,支持最常见的用户名/密码的身份验证

提交用户名/密码进行认证:

Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);

处理认证成功和失败

  • 认证成功:没有返回,也没有异常,通过。
  • 认证失败,拋出异常,可以在程序中捕获并处理

认证顺序:

认证过程:

Step 1:应用程序代码调用 Subject.login 方法,传递创建好的包含终端用户的 Principals(身份)和 Credentials(凭证)的 AuthenticationToken 实例

Step 2:Subject 实例,通常为 DelegatingSubject(或子类)委托应用程序的 SecurityManager 通过调用 securityManager.login(token) 开始真正的验证。

Step 3:SubjectManager 接收 token,调用内部的 Authenticator 实例调用 authenticator.authenticate(token)。 Authenticator 通常是一个 ModularRealmAuthenticator 实例,支持在身份验证中协调一个或多个Realm 实例。

Step 4:如果应用程序中配置了一个以上的 Realm,ModularRealmAuthenticator 实例将利用配置好的AuthenticationStrategy 来启动 Multi-Realm 认证尝试。在Realms 被身份验证调用之前,期间和以后,AuthenticationStrategy 被调用使其能够对每个Realm 的结果作出反应。

Step 5:每个配置的 Realm 用来帮助看它是否支持提交的AuthenticationToken。如果支持,那么支持 Realm 的 getAuthenticationInfo 方法将会伴随着提交的 token 被调用。getAuthenticationInfo 方法有效地代表一个特定 Realm 的单一的身份验证尝试。


Shiro 授权

授权:又称访问控制—控制谁有权限在应用程序中做什么。在授权中,需要了解几个关键的对象:Subject 主体、Resource 资源、Permissions 权限、Role 角色:

  • Subject 主体:访问应用的用户,在 Shiro 中使用 Subject 代表该用户,用户需要授权后才能访问相应的资源
  • Resource 资源:在应用中用户访问的任何东西,例如:jsp、接口、图片等,都属于是资源
  • Permissions 权限:Shiro 安全机制最核心的元素。它在应用程序中明确声明了被允许的行为。一个格式良好的权限声明可以清晰表达出用户对该资源拥有的权限。在 Shiro 中主要通过通配符表达式来完成权限的描述
  • Role 角色:一个命名的实体, 通常代表一组行为或职责。 这些行为演化为在一个应用中能或者不能做的事情。角色通常分配给用户帐户。一个角色拥有一个权限的集合。授权验证时,需要判断当前角色是否拥有指定的权限。这种角色权限可以对该角色进行详细的权限描述。 Shiro官方推荐使用这种方式

授权检查的例子:用户是否能访问某个网页,编辑数据,或打使用这台打印机

授权的三要素:权限、角色和用户 。

需要在应用程序中对用户和权限建立关联:通常的做法是将权限分配给角色,然后将角色分配给一个或多个用户。

Shiro的三种授权方式:

  • 编写代码:在 Java 代码中用像 if 和 else 块的结构执行授权检查。
  • JDK 的注解:可以添加授权注解给 Java 方法
  • JSP 标签库:可以控制基于角色和权限的JSP 页面输出。

Shiro 授权顺序图:

时序图:

  • Step 1:应用程序或框架代码调用任何 Subject 的hasRole*, checkRole*, isPermitted*,或者checkPermission*方法的变体,传递任何所需的权限
  • Step 2:Subject 的实例—通常是 DelegatingSubject(或子类),调用securityManager 的对应的方法。
  • Step 3:SecurityManager 调用 org.apache.shiro.authz.Authorizer 接口的对应方法。默认情况下,authorizer 实例是一个 ModularRealmAuthorizer 实例,它支持协调任何授权操作过程中的一个或多个Realm 实例。
  • Step 4:每个配置好的 Realm 被检查是否实现了相同的 Authorizer 接口。如果是,Realm 各自的 hasRole*, checkRole*, isPermitted*,或 checkPermission* 方法将被调用。

Shiro 基础语法:Permissions的声明方式

基础语法之简单的字符串:

  • 即用简单的字符串来表示一个权限,如:user (相当于:user:*

基础语法之多层次管理:

  • 例如:user:query、user:edit
  • 多个值:每个部件能够保护多个值。因此,除了授予用户 user:queryuser:edit 权限外,也可以简单地授予他们一个:user:query, edit
  • 还可以用 * 号代替所有的值,如:user:* , 也可以写:*:query,表示某个用户在所有的领域都有 query 的权限

基础语法之实例级访问控制:

  • 这种情况通常会使用三个部件:域、操作、被付诸实施的实例。如:user:edit:manager
  • 也可以使用通配符来定义,如:user:edit:*、user:*:*、user:*:manager
  • 部分省略通配符:缺少的部件意味着用户可以访问所有与之匹配的值,比如:user:edit 等价于 user:edit :*、user 等价于 user:*:*

注意:通配符只能从字符串的结尾处省略部件,也就是说 user:edit 并不等价于 user:*:edit


Shiro 注销

logout(注销):currentUser.logout();

  • 调用 logout() 方法时,现有 Session 将失效,而且身份将失去关联(在Web 应用程序中,RememberMe cookie 将被删除)。
  • 在 Subject 注销后,该 Subject 的实例被再次认为是匿名的。

注意:WEB 应用程序记住身份往往依靠 Cookie,然而Cookie 只能在 Response 被返回后被删除,所以建议在调用subject.logout() 后立即向终端重定向一个新的视图或页面。这样即能保证与安全相关的 Cookie 都能像预期的一样被删除。


Realm

  • Realm:访问应用程序安全数据(如用户、角色及权限)的组件。
  • Realm 通常和数据源是一对一的对应关系,如关系数据库、文件系统或其他类似资源。Realm 实质上就是一个访问安全数据的 DAO。
  • 数据源通常存储身份验证数据(如密码的凭证)以及授权数据(如角色或权限),所以每个Realm 都能够执行身份验证和授权操作。

Realms的认证实现

Shiro 的认证过程由 Realm 执行,SecurityManager 会调用 org.apache.shiro.realm.RealmgetAuthenticationInfo(AuthenticationToken token) 方法

实际开发中,通常会提供 org.apache.shiro.realm.AuthenticatingRealm 的实现类,并在该实现类中提供doGetAuthenticationInfo(AuthenticationToken token)方法的具体实现

  1. 检查提交的进行认证的令×××信息
  2. 根据令×××信息从数据源(通常为数据库)中获取用户信息
  3. 对用户信息进行匹配验证。
  4. 验证通过将返回一个封装了用户信息的 AuthenticationInfo 实例。
  5. 验证失败则抛出 AuthenticationException 异常信息。

Shiro权限拦截

Shiro和Spring Security一样,都是基于过滤器来实现权限拦截的。shiro中默认的过滤器:

过滤器链:

过滤器类图:


Shiro会话管理

Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如Tomcat),不管是J2SE还是J2EE环境都可以使用,提供了会话管理,会话事件监听,会话存储/持久化,容器无关的集群,失效/过期支持,对Web的透明支持,SSO单点登录的支持等特性。

建议在开发中,Controller层使用原生的HttpSession对象,在Service层中使用Shiro提供的Session对象。如果在Service层中使用HttpSession对象,那么属于侵入式,并不建议这么做。Shiro提供的Session能够很好的解决这个问题。

会话管理相关类图:


Shiro权限缓存

缓存是×××能的重要手段,对同一批数据进行多次查询时, 第一次查询走数据库,查询数据后,将数据保存在内存中,第二次以后查询可以直接从内存获取数据,从而不需要和数据库进行交互。这样减少了系统查询数据库的次数,提升了性能。

缓存适合那些经常不变动的数据,比如系统中用户的信息和权限不会经常改变,特别适合缓存起来供下次使用。其中我们的权限信息就是不怎么会改变的,对权限信息进行缓存可以提高我们系统的性能。不过 Shiro 自身不实现缓存,而是提供缓存接口,让其他第三方实现,默认支持EhCache和MapCache缓存。

Shiro 缓存相关的类图:

原文地址:http://blog.51cto.com/zero01/2171397

时间: 2024-10-13 15:20:35

Apache Shiro权限框架理论介绍的相关文章

Apache shiro权限基本使用

l shiro框架的核心功能:认证.授权.会话管理.加密 Application Code:应用程序代码,由开发人员负责开发的 Subject:框架提供的接口,代表当前用户对象 SecurityManager:框架提供的接口,代表安全管理器对象 Realm:可以开发人员编写,框架也提供一些,类似于DAO,用于访问权限数据 一 .在pom中引入相关依赖 1 <!-- 引入shiro框架的依赖 --> 2 <dependency> 3 <groupId>org.apache

关于Apache Shiro权限框架的一些使用误区的解释

多了不说了,进入正题,shiro是个权限框架提供权限管理等功能,网上的教程一般都是互相抄,比如<shiro:principal property="xxx"/>这个标签,网上教程告诉你可以用来获取登录用户的任何属性,但现实中如果你这么写,并且按照开涛教程上写的登陆逻辑,肯定百分百报错,这是为什么呢?因为网上教程的登录部分一般这么写: 这是重写authorizingrealm的dogetAuthenticationinfo方法: protected Authenticatio

Apache Shiro 使用手册(一)Shiro架构介绍

一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录": 授权 - 访问控制: 密码加密 - 保护或隐藏数据防止被偷窥: 会话管理 - 每用户相关的时间敏感的状态. 对于任何一个应用程序,Shiro都可以提供全面的安全管理服务.并且相对于其他安全框架,Shiro要简单的多. 二.Shiro的架构介绍 首先,来了解一下Shiro的三个核心组件:Subject. Security

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(四)基于Shiro验证用户权限,且给用户授权

最新项目比较忙,写文章的精力就相对减少了,但看到邮箱里的几个催更,还是厚颜把剩下的文档补上. 一.修改ShiroDbRealm类,实现它的doGetAuthorizationInfo方法 package org.shiro.demo.service.realm; import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; import org.apache.commons.lang.St

Shiro权限控制框架入门1:Shiro的认证流程以及基本概念介绍

前言:我在最开始学习Shiro这个框架时,在网上搜索到的一个介绍比较全面的教程是:<跟我学Shiro>系列教程.但是在我看了他写的前几篇文章后,我发现虽然他在这个系列教程中把shiro的一些特性介绍地非常全面详细,但是整个教程的叙述方式还是有很大缺陷的.文章与文章之间并没有很好地串联起来,每篇文章介绍的东西都过于分散了,如果是对shiro完全不了解的新手来看的话完全是一场噩梦.就像一个网友评价的这样: 看了看这个教程,看完之后都想放弃shiro了,完全看不懂,后来百度了很多别的资料才理解了sh

【Shiro】Apache Shiro架构之权限认证(Authorization)

上一篇博文总结了一下Shiro中的身份认证,本文主要来总结一下Shiro中的权限认证(Authorization)功能,即授权.如下: 本文参考自Apache Shiro的官方文档:http://shiro.apache.org/authorization.html. 本文遵循以下流程:先介绍Shiro中的权限认证,再通过一个简单的实例来具体说明一下API的使用(基于maven). 1. 权限认证的核心要素 权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源.在权限认证中,最核心的三个要素

【转】Apache shiro集群实现 (一) shiro入门介绍

近期在ITOO项目中研究使用Apache shiro集群中要解决的两个问题,一个是Session的共享问题,一个是授权信息的cache共享问题,官网上给的例子是Ehcache的实现,在配置说明上不算很详细,我在我们的项目中使用的是nosql(Redis)替代了ehcache做了session和cache的存储,接下来从shiro.Cas.redis.session等等基础知识.基本原理集成的角度来不断的深入分析,系列文章篇幅很长,很丰富,尽请期待! Apache shiro集群实现 (一) sh

Apache shiro集群实现 (一) shiro入门介绍

近期在ITOO项目中研究使用Apache shiro集群中要解决的两个问题,一个是Session的共享问题,一个是授权信息的cache共享问题,官网上给的例子是Ehcache的实现,在配置说明上不算很详细,我在我们的项目中使用的是nosql(Redis)替代了ehcache做了session和cache的存储,接下来从shiro.Cas.redis.session等等基础知识.基本原理集成的角度来不断的深入分析,系列文章篇幅很长,很丰富,尽请期待! 今天我们先来介绍shiro的基本概念 一.sh

Spring Security和Apache Shiro开发企业级权限管理系统

原理回顾什么是权限管理?权限管理是系统的安全范畴,要求必须是合法的用户才可以访问系统(用户认证),且必须具有该 资源的访问权限才可以访问该 资源(授权).认证:对用户合法身份的校验,要求必须是合法的用户才可以访问系统.授权:访问控制,必须具有该 资源的访问权限才可以访问该 资源.权限模型:标准权限数据模型包括 :用户.角色.权限(包括资源和权限).用户角色关系.角色权限关系.权限分配:通过UI界面方便给用户分配权限,对上边权限模型进行增.删.改.查操作.权限控制:基于角色的权限控制:根据角色判断