初识Shiro

Shiro是Apache的一个权限管理框架,鉴于不少人对权限管理的概念都不是很清楚,因此我在正式介绍Shiro前我会谈谈权限管理的概念。前端

1.权限管理

1.1什么是权限管理

只要有用户参与的系统通常都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户能够访问并且只能访问本身被受权的资源。权限管理包括用户认证用户受权两部分java

1.2用户认证

用户认证,用户去访问系统,系统要验证用户身份的合法性。最经常使用的用户身份验证的方法:一、用户名密码方式。二、指纹打卡机。三、基于证书验证方法。只有当系统验证用户身份合法,用户才可访问系统的资源。web

1.2.1用户认证流程

1.2.2关键对象

subject:主体,理解为用户,多是程序、网络爬虫等,都要去访问系统的资源,系统须要对subject进行身份认证。spring

principal:身份信息,一般是惟一的,一个主体还有多个身份信息,可是都有一个主身份信息(primary principal)。数据库

credential:凭证信息,能够是密码 、证书、指纹。缓存

总结:主体在进行身份认证时须要提供身份信息和凭证信息。安全

1.3用户受权

用户受权,简单理解为访问控制,在用户认证经过后(注意只有当用户认证经过后才能对用户进行受权),系统对用户访问资源进行控制,用户具备资源的访问权限方可访问。服务器

1.3.1受权流程

1.3.2关键对象

受权的过程理解为: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.3权限模型

对1.3.2节提到的主体、资源、权限经过数据模型表示,标准权限数据模型包括 :用户(帐号和密码)、角色(角色名称)、权限(包括资源和权限)、用户角色关系(用户id、角色id)、角色权限关系(角色id、权限id)。以下图:

而一般企业开发中将资源表和权限表合并为一张权限表,以下图:

上图常被称为权限管理的通用模型,不过企业在开发中根据系统自身的特色还会对上图进行修改,可是用户、角色、权限、用户角色关系、角色权限关系是须要去理解的。

1.3.4分配权限

用户须要分配相应的权限才可访问相应的资源。权限是对于资源的操做许可。

一般给用户分配资源权限须要将权限信息持久化,好比存储在关系数据库中。

把用户信息、权限管理、用户分配的权限信息写到数据库(权限数据模型)。

1.3.5权限控制(受权的核心)

权限的控制分为基于角色的访问控制和基于资源的访问控制。

基于角色的访问控制: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 ('用户报表查看(权限标识符)')){
	//系统资源内容
	//用户报表查看
}

 

上边的方法就能够解决用户角色变动不用修改上边权限控制的代码。若是须要变动权限只须要在分配权限模块去操做,给部门经理或总经理增或删除权限。因此在实际开发中咱们建议使用基于资源的访问控制实现权限管理。

1.4权限管理解决方案

1.4.1什么是粗粒度和细粒度权限

粗粒度权限管理:对资源类型的权限管理。资源类型好比:菜单、url链接、用户添加页面、用户信息、类方法、页面中按钮。粗粒度权限管理好比:超级管理员能够访问户添加页面、用户信息等所有页面。部门管理员能够访问用户信息页面包括 页面中全部按钮。

细粒度权限管理:对资源实例的权限管理。资源实例就资源类型的具体化,好比:用户id为001的修改链接,1110班的用户信息、行政部的员工。细粒度权限管理就是数据级别的权限管理。细粒度权限管理好比:部门经理只能够访问本部门的员工信息,用户只能够看到本身的菜单,大区经理只能查看本辖区的销售订单。

粗粒度和细粒度例子:系统有一个用户列表查询页面,对用户列表查询分权限,若是粗颗粒管理,张三和李四都有用户列表查询的权限,张三和李四均可以访问用户列表查询。
进一步进行细颗粒管理,张三(行政部)和李四(开发部)只能够查询本身本部门的用户信息。张三只能查看行政部 的用户信息,李四只能查看开发部门的用户信息。细粒度权限管理就是数据级别的权限管理。

1.4.2如何实现粗粒度和细粒度权限管理

如何实现粗粒度权限管理?

粗粒度权限管理比较容易将权限管理的代码抽取出来在系统架构级别统一处理。好比:经过springmvc的拦截器实现受权。

如何实现细粒度权限管理?

对细粒度权限管理在数据级别是没有共性可言,针对细粒度权限管理就是系统业务逻辑的一部分,若是在业务层去处理相对比较简单,若是将细粒度权限管理统一在系统架构级别去抽取,比较困难,即便抽取的功能可能也存在扩展不强。

建议细粒度权限管理在业务层去控制。好比:部门经理只查询本部门员工信息,在service接口提供一个部门id的参数,controller中根据当前用户的信息获得该 用户属于哪一个部门,调用service时将部门id传入service,实现该用户只查询本部门的员工。

2.什么是Shiro

Apache Shiro是Java的一个权限管理框架,相比Spring框架中的权限管理框架Spring Security,Spring Security和Spring的依赖过于紧密,没有Shiro使用简单,并且Shiro不依赖Spring,它不只能够实现web应用的权限管理,还能够实现c/s系统、分布式系统权限管理。

Shiro属于轻量框架,能够帮助咱们完成:认证、受权、加密、会话管理、与Web集成、缓存等功能,因此愈来愈多企业项目开始使用Shiro。并且Shiro的API也是很是简单,其基本功能点以下图:

解释:

  • Authentication:身份认证/登陆,验证用户是否是拥有相应的身份。
  • Authorization:受权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能作事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具备某个权限。
  • Session Manager:会话管理,即用户登陆后就是一次会话,在没有退出以前,它的全部信息都在会话中;会话能够是普通JavaSE环境的,也能够是如Web环境的。
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文(所谓明文,就是咱们输入的文字例如登陆列表的用户名和密码)存储。
  • Web Support:Web支持,能够很是容易的集成到Web环境。
  • Caching:缓存,好比用户登陆后,其用户信息、拥有的角色/权限没必要每次去查,这样能够提升效率。
  • Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另外一个线程,能把权限自动传播过去。
  • Testing:提供测试支持。
  • Run As:容许一个用户伪装为另外一个用户(若是他们容许)的身份进行访问。
  • Remember Me:记住我,这个是很是常见的功能,即一次登陆后,下次再来的话不用登陆了。

记住一点:Shiro不会去维护用户、维护权限,这些须要咱们本身去设计/提供;而后经过相应的接口注入给Shiro便可。

接下来咱们分别从外部和内部来看看Shiro的架构,对于一个好的框架,从外部来看应该具备很是简单易于使用的API,且API契约明确;从内部来看的话,其应该有一个可扩展的架构,即很是容易插入用户自定义实现,由于任何框架都不能知足全部需求。

3.Shiro架构

3.1从外部看Shiro架构

从外部看Shiro,即从应用程序的角度来观察如何使用Shiro完成工做。以下图Apache官网为咱们提供的一张Shiro的架构图:

解释:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject;图中每一个API的含义:

  • Subject:主体,表明了当前“用户”,这个用户不必定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;全部Subject都绑定到SecurityManager,与Subject的全部交互都会委托给SecurityManager;能够把Subject认为是一个门面;SecurityManager才是实际的执行者。
  • SecurityManager:安全管理器;即全部与安全有关的操做都会与SecurityManager交互;且它管理着全部Subject;能够看出它是Shiro的核心,它负责与后边介绍的其余组件进行交互,若是学习过SpringMVC,你能够把它当作DispatcherServlet前端控制器。
  • Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它须要从Realm获取相应的用户进行比较以肯定用户身份是否合法;也须要从Realm获得用户相应的角色/权限进行验证用户是否能进行操做;能够把Realm当作DataSource,即安全数据源。

也就是说对于咱们而言,最简单的一个Shiro应用都是通过以下步骤:

一、应用代码经过Subject来进行认证和受权,而Subject又委托给SecurityManager。

二、咱们须要给Shiro的SecurityManager注入Realm,从而让SecurityManager能获得合法的用户及其权限进行判断。

从以上也能够看出,Shiro不提供维护用户/权限,而是经过Realm让开发人员本身注入。

3.2从内部看Shiro架构

架构图以下:

分析:

  • Subject:主体,能够看到主体能够是任何能够与应用交互的“用户”。
  • SecurityManager:至关于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心脏;全部具体的交互都经过SecurityManager进行控制;它管理着全部Subject、且负责进行认证和受权、及会话、缓存的管理。
  • Authenticator:认证器,负责主体认证的,这是一个扩展点,若是用户以为Shiro默认的很差,能够自定义实现;其须要认证策略(Authentication Strategy),即什么状况下算用户认证经过了。
  • Authrizer:受权器,或者访问控制器,用来决定主体是否有权限进行相应的操做;即控制着用户能访问应用中的哪些功能。
  • Realm:能够有1个或多个Realm,能够认为是安全实体数据源,即用于获取安全实体的;能够是JDBC实现,也能够是LDAP实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;因此咱们通常在应用中都须要实现本身的Realm。
  • SessionManager:若是写过Servlet就应该知道Session的概念,Session呢须要有人去管理它的生命周期,这个组件就是SessionManager;而Shiro并不只仅能够用在Web环境,也能够用在如普通的JavaSE环境、EJB等环境;全部呢,Shiro就抽象了一个本身的Session来管理主体与应用之间交互的数据;这样的话,好比咱们在Web环境用,刚开始是一台Web服务器;接着又上了台EJB服务器;这时想把两台服务器的会话数据放到一个地方,这个时候就能够实现本身的分布式会话(如把数据放到Memcached服务器)。
  • SessionDAO:DAO你们都用过,数据访问对象,用于会话的CRUD,好比咱们想把Session保存到数据库,那么能够实现本身的SessionDAO,经过如JDBC写到数据库;好比想把Session放到Memcached中,能够实现本身的Memcached SessionDAO;另外SessionDAO中可使用Cache进行缓存,以提升性能;
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;由于这些数据基本上不多去改变,放到缓存中后能够提升访问的性能。
  • Cryptography:密码模块,Shiro提升了一些常见的加密组件用于如密码加密/解密的。
相关文章
相关标签/搜索