Shiro是Apache的一个权限管理框架,鉴于不少人对权限管理的概念都不是很清楚,因此我在正式介绍Shiro前我会谈谈权限管理的概念。前端
只要有用户参与的系统通常都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户能够访问并且只能访问本身被受权的资源。权限管理包括用户认证和用户受权两部分java
用户认证,用户去访问系统,系统要验证用户身份的合法性。最经常使用的用户身份验证的方法:一、用户名密码方式。二、指纹打卡机。三、基于证书验证方法。只有当系统验证用户身份合法,用户才可访问系统的资源。web
subject:主体,理解为用户,多是程序、网络爬虫等,都要去访问系统的资源,系统须要对subject进行身份认证。spring
principal:身份信息,一般是惟一的,一个主体还有多个身份信息,可是都有一个主身份信息(primary principal)。数据库
credential:凭证信息,能够是密码 、证书、指纹。缓存
总结:主体在进行身份认证时须要提供身份信息和凭证信息。安全
用户受权,简单理解为访问控制,在用户认证经过后(注意只有当用户认证经过后才能对用户进行受权),系统对用户访问资源进行控制,用户具备资源的访问权限方可访问。服务器
受权的过程理解为:who对what(which)进行how操做。网络
who:主体即subject,subject在认证经过后系统进行访问控制。多线程
what(which):资源(Resource),subject必须具有资源的访问权限才可访问该 资源。资源好比:系统用户列表页面、商品修改菜单、商品id为001的商品信息。资源分为资源类型和资源实例:系统的用户信息就是资源类型,至关于java类;系统中id为001的用户就是资源实例,至关于new的java对象。
how:权限/许可(permission) ,针对资源的权限或许可,subject具备permission访问资源,如何访问/操做须要定义permission,权限好比:用户添加、用户修改、商品删除。
对1.3.2节提到的主体、资源、权限经过数据模型表示,标准权限数据模型包括 :用户(帐号和密码)、角色(角色名称)、权限(包括资源和权限)、用户角色关系(用户id、角色id)、角色权限关系(角色id、权限id)。以下图:
而一般企业开发中将资源表和权限表合并为一张权限表,以下图:
上图常被称为权限管理的通用模型,不过企业在开发中根据系统自身的特色还会对上图进行修改,可是用户、角色、权限、用户角色关系、角色权限关系是须要去理解的。
用户须要分配相应的权限才可访问相应的资源。权限是对于资源的操做许可。
一般给用户分配资源权限须要将权限信息持久化,好比存储在关系数据库中。
把用户信息、权限管理、用户分配的权限信息写到数据库(权限数据模型)。
权限的控制分为基于角色的访问控制和基于资源的访问控制。
基于角色的访问控制:RBAC((role based access control)。好比:系统角色包括 :部门经理、总经理。(角色针对用户来划分)。
系统代码中的实现为:
1 2 3 4 5 |
//若是该user是部门经理则能够访问if中的代码 if(user.hasRole('部门经理')){ //系统资源内容 //用户报表查看 } |
基于角色的访问控制出现的问题:角色针对人划分的,人做为用户在系统中属于活动内容,若是该 角色能够访问的资源出现变动,须要修改你的代码了,好比:须要变动为部门经理和总经理均可以进行用户报表查看,代码改成:
1 2 3 4 |
if(user.hasRole('部门经理') || user.hasRole('总经理') ){ //系统资源内容 //用户报表查看 } |
可知基于角色的访问控制是不利于系统维护(可扩展性不强)。
而对于基于资源的访问控制:RBAC(Resource based access control)。由于资源在系统中是不变的,好比资源有:类中的方法,页面中的按钮。对资源的访问须要具备permission权限,代码能够写为:
1 2 3 4 |
if(user.hasPermission ('用户报表查看(权限标识符)')){ //系统资源内容 //用户报表查看 } |
上边的方法就能够解决用户角色变动不用修改上边权限控制的代码。若是须要变动权限只须要在分配权限模块去操做,给部门经理或总经理增或删除权限。因此在实际开发中咱们建议使用基于资源的访问控制实现权限管理。
粗粒度权限管理:对资源类型的权限管理。资源类型好比:菜单、url链接、用户添加页面、用户信息、类方法、页面中按钮。粗粒度权限管理好比:超级管理员能够访问户添加页面、用户信息等所有页面。部门管理员能够访问用户信息页面包括 页面中全部按钮。
细粒度权限管理:对资源实例的权限管理。资源实例就资源类型的具体化,好比:用户id为001的修改链接,1110班的用户信息、行政部的员工。细粒度权限管理就是数据级别的权限管理。细粒度权限管理好比:部门经理只能够访问本部门的员工信息,用户只能够看到本身的菜单,大区经理只能查看本辖区的销售订单。
粗粒度和细粒度例子:系统有一个用户列表查询页面,对用户列表查询分权限,若是粗颗粒管理,张三和李四都有用户列表查询的权限,张三和李四均可以访问用户列表查询。
进一步进行细颗粒管理,张三(行政部)和李四(开发部)只能够查询本身本部门的用户信息。张三只能查看行政部 的用户信息,李四只能查看开发部门的用户信息。细粒度权限管理就是数据级别的权限管理。
如何实现粗粒度权限管理?
粗粒度权限管理比较容易将权限管理的代码抽取出来在系统架构级别统一处理。好比:经过springmvc的拦截器实现受权。
如何实现细粒度权限管理?
对细粒度权限管理在数据级别是没有共性可言,针对细粒度权限管理就是系统业务逻辑的一部分,若是在业务层去处理相对比较简单,若是将细粒度权限管理统一在系统架构级别去抽取,比较困难,即便抽取的功能可能也存在扩展不强。
建议细粒度权限管理在业务层去控制。好比:部门经理只查询本部门员工信息,在service接口提供一个部门id的参数,controller中根据当前用户的信息获得该 用户属于哪一个部门,调用service时将部门id传入service,实现该用户只查询本部门的员工。
Apache Shiro是Java的一个权限管理框架,相比Spring框架中的权限管理框架Spring Security,Spring Security和Spring的依赖过于紧密,没有Shiro使用简单,并且Shiro不依赖Spring,它不只能够实现web应用的权限管理,还能够实现c/s系统、分布式系统权限管理。
Shiro属于轻量框架,能够帮助咱们完成:认证、受权、加密、会话管理、与Web集成、缓存等功能,因此愈来愈多企业项目开始使用Shiro。并且Shiro的API也是很是简单,其基本功能点以下图:
解释:
记住一点:Shiro不会去维护用户、维护权限,这些须要咱们本身去设计/提供;而后经过相应的接口注入给Shiro便可。
接下来咱们分别从外部和内部来看看Shiro的架构,对于一个好的框架,从外部来看应该具备很是简单易于使用的API,且API契约明确;从内部来看的话,其应该有一个可扩展的架构,即很是容易插入用户自定义实现,由于任何框架都不能知足全部需求。
从外部看Shiro,即从应用程序的角度来观察如何使用Shiro完成工做。以下图Apache官网为咱们提供的一张Shiro的架构图:
解释:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject;图中每一个API的含义:
也就是说对于咱们而言,最简单的一个Shiro应用都是通过以下步骤:
一、应用代码经过Subject来进行认证和受权,而Subject又委托给SecurityManager。
二、咱们须要给Shiro的SecurityManager注入Realm,从而让SecurityManager能获得合法的用户及其权限进行判断。
从以上也能够看出,Shiro不提供维护用户/权限,而是经过Realm让开发人员本身注入。
架构图以下:
分析: