🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 1. 什么是shiro Shiro是Apache下的一个开源项目,我们称之为Apache Shiro。它是一个很易用与Java项目的的安全框架,提供了认证、授权、加密、会话管理,与 Spring Security 一样都是做一个权限的安全框架,但是与Spring Security 相比,在于 Shiro 使用了比较简单易懂易于使用的授权方式。 系统认证分为: 1. 用户认证(搞清楚你是谁) 2. 权限控制(搞清楚你在这能干嘛) ## 2. 三大核心组件 ### 2.1 组件介绍 ![](https://box.kancloud.cn/1fb8e11dce1d2799c52ebd1e6d3c2721_410x220.png) * subject:用户或者程序,可以是任何语言编写。(这个跟uel拦截器一样) * securityManager:安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。它自身只是一个接口。 - Realms 用于进行权限信息的验证,也是我们需要自己实现的。从数据源获取存入的权限信息(人员表,权限表等。。。) * Authentic:认证器,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自 定义认证器。(相当于ur权限l的登录拦截器哦) * Authorizer:Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限(相当于url权限系统的权限拦截器)。 * sessionManager:即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。(相当于ur权限系统里面自带的httpsession,而它可以独立) * sessionDao:SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。 * realms:领域相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。(相当于ur权限系统里面自带的mysql,而它还支持验证) * 注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。 * cacheManager: CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。 * Cryptography:Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。MD5即是散列(相当于ur权限系统里面MD5) - principal:身份信息 就是主体的身份标志,身份信息是一对多关系。上图你可以是群主,也是尊贵的QQ会员(身份体现)。 - credential:凭证信息 只要主体知道,或者主体提供的信息。例如我们的身份证凭证。上图为登录密码(身份证硬件)。 ### 2.2 验证流程图 1. 一般的验证流程(拦截器) ![](https://box.kancloud.cn/c1f2d1fbcc5acf988595790fa2e9951a_566x430.png) 2. shiro验证流程 ![](https://box.kancloud.cn/41c98e1cfb51b1c05447b34d58af9577_351x520.png) 来了一个人,首先判断是不是我的人 如果是我的人,再看看咱俩啥关系(权限认证) 根据咱俩啥关系,咱办啥事 用户认证通过之后,接下来就是主体subject访问资源resource的时候,这个时候就需要验证权限身份principal。如果拥有凭证credential就可以访问。 我们需要实现Realms的Authentication 和 Authorization。其中 Authentication 是用来验证用户身份,Authorization 是授权访问控制,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。 1、主体:(账户、密码) 2、资源:(资源名称、资源访问地址) 3、权限:(权限名称、资源id) 4、角色:(角色名称) 5、角色权限关系:(角色id、权限id) 6、主体角色关系:(主体id、角色id) ### 2.3 权限控制 了解了用户认证、用户授权、权限模型之后,我们来看看权限控制,就是我们上面我们看到的判断。 #### 2.3.1 基于角色控制权限 RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制 例如: ~~~ if(主体.hasRole("总经理角色id")){ 查询工资 } ~~~ 缺陷:如果懂事长秘书也有查询工资的权限呢??如下 if(主体.hasRole("总经理角色id")||主体.hasRole("懂事长秘书角色id")){ 查询工资 } 所有这种我们一般不建议!!! #### 2.3.2 基于资源控制权限 RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制 例如: ~~~ if(主体.hasPermission("查询工资权限标识")){ 查询工资 } ~~~ 优点:系统设计时定义好查询工资的权限标识,即使查询工资所需要的角色变化为总经理和部门经理也只需要将“查询工资信息权限”添加到“部门经理角色”的权限列表中,判断逻辑不用修改,系统可扩展性强。