还在亲手写Filter进行权限校验?尝试一下Shiro吧|应用程序|数据源|spring|session

  前言

  权限管理是每个系统不可缺少的,它隶属于系统安全的范畴,实现对用户访问系统的控制,按照指定的安全策略控制用户对资源的访问。

  权限管理通常包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源,需先进行用户身份认证,认证通过后用户具有该资源的访问权限便可进行访问。

  针对权限管理,在Java体系中,常见的权限框架有Shiro和Spring Security,当然在一些简单或古老的系统中可能还在用手写的filter来进行权限的管理和控制。本文先从Shiro的功能、组件、架构等方面来带大家了解一下Shiro框架。

  Shiro简介

  Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。与之相对应的便是Spring Security,但在大多数项目中开发人员更愿意使用Shiro来管理权限。

  主要原因是使用起来比较简单,而Spring Security相对来说更重量级一些,学习曲线比较陡峭,而实际环境中也并不需要Spring Security那么多功能。所以,一般情况下,使用Shiro便足够了。

  Shiro可以快速、轻松的运用于任何应用程序中,从最小的移动应用程序到最大的网络和企业应用程序。

  Shiro能做什么

  Shiro提供了以下功能:认证(Authentication)、授权(Authorization)、加密(Cryptography)、Session管理(Session Management)、Web集成(Web Support)、缓存(Caching)等。可用于保护任何应用程序:从命令行应用程序、移动应用程序到最大的Web和企业应用程序。

  关于Shiro的核心功能,官方提供了下图:

  

  使用Shiro我们可以实现以下功能:

  

  • 用户认证;
  • 用户访问控制:判断用户是否拥有特定的角色;判断用户是否可执行某个操作;
  • 在任何环境下使用Session API,即使在Web或EJB容器之外的应用;
  • 可在认证、访问控制和会话期间,对事件做出响应;
  • 汇总一个或多个用户安全数据的数据源,并将其全部显示为单个复合用户“视图”;
  • 支持单点登录(SSO)功能;
  • 支持登录时的“记住”功能;
  • 其他应用程序;
  • Shiro特点

  Shiro的目标是:在各类应用(从命令行到大型企业应用)中,做到不依赖其他三方框架、容器或应用程序本身的依赖,可以在任何环境中直接使用。同时它又具有以下特点:

  

  • 易于理解的Java Security API;
  • 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
  • 对角色的简单的签权(访问控制),支持细粒度的签权;
  • 支持一级缓存,以提升应用程序的性能;
  • 内置的基于POJO企业会话管理,适用于Web以及非Web的环境;
  • 异构客户端会话访问;
  • 非常简单的加密 API;
  • 不跟任何的框架或者容器捆绑,可以独立运行;
  • Shiro各模块功能

  结合下图,我们来细化一下Shiro各个模块对应的功能:

  

  Authentication:身份认证/登录,验证用户是不是拥有相应的身份;

  Authorization:授权,即权限验证。验证某个用户是否有操作某个功能的权限。如:验证用户是否拥有某个角色、是否有操作某个资源的权限;

  Session Management:Session管理,存储用户登录信息于会话当中,支持Web环境和非Web环境;

  Cryptography:加密数据,并保持易用性,比如密码加密后存储到数据库;

  Web Support:Web支持,可以方便的集成到Web环境;

  Caching:缓存,比如用户登录后,对用户信息、角色/权限进行缓存;

  Concurrency:Shiro支持多线程场景下的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

  Testing:提供测试支持;

  Run As:允许一个用户假装为另一个用户(如果他们允许)进行访问;

  Remember Me:记住我,登录之后,下次可直接进入系统。

  看了上面的组件是不是突然觉得Shiro在实际应用中被小看了?虽然Shiro为我们提供了这么多功能,但它并不会帮我们实现具体的用户、权限等体系,关于用户、角色、权限等需要自行设计,然后在Shiro中进行处理即可。

  核心组件

  Shiro包括三大核心组件:Subject,SecurityManager和Realms。这三个组件的关系如下图:

  

  Subject:主体,即“当前操作用户”。在Shiro中Subject并不仅仅指人,是一个抽象概念,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物(如爬虫、机器人等)。也就是说它仅仅意味着“当前跟软件交互的东西”。所有Subject都绑定到SecurityManager上,SecurityManager才是实际的执行者。

  SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例(包括所有的Subject),并通过它来提供安全管理的各种服务。类似SpringMVC中的DispatcherServlet的作用。

  Realm:域,充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。从这个意义上讲,Realm本质上是一个安全相关的DAO:它封装了数据源的连接细节,在需要时将相关数据提供给Shiro。当配置Shiro时,至少指定一个Realm,用于认证和(或)授权。

  Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果默认的Realm不能满足需求,还可以自定义Realm实现。

  Shiro架构概览

  分析了上述组件,我们梳理一下Shiro使用的简单场景:应用程序通过Subject来进行认证和授权,而Subject是委托给SecurityManager管理的。SecurityManager进行认证和授权又需要Authenticator和Realm的支持,因此需将Realm注入给SecurityManager。

  那么,Shiro内部的架构又是如何呢?

  

  上图中,Subject、SecurityManager、Realm我们在前面已经讲到过了,这里再看看其他模块:

  Authenticator:认证器,负责Subject的认证,支持自定义实现;需要认证策略(Authentication Strategy),即认证通过的条件。

  Authrizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作。

  SessionManager:SessionManager用于管理Session的生命周期。Shiro可用在Web环境和非Web环境,所以Shiro就抽象出一个Session来管理主体与应用之间交互的数据,这样就可以将不同应用的Session进行集中管理,从而实现分布式会话。

  SessionDAO:如果想把Session存储到数据库或Memcached当中,则可实现对应的SessionDAO来实现会话的CRUD。SessionDAO中可以使用Cache进行缓存,来提高性能;

  CacheManager:缓存控制器,用来管理用户、角色、权限等缓存。

  Cryptography:密码模块,提供了常见的加解密组件。

  了解了上述组件的功能,再回想一下在实践中的应用,是不是有点豁然开朗了?

  小结

  看到很多朋友在使用shiro时往往是在网上找到一段代码,然后进行简单的修改便运用起来了,而各个组件之间什么关系,实现这个功能的原理是什么等信息却没有进行深入探究。这样即便实践了很多项目,依旧无法提升自身的技能。本篇文章从shiro的功能、架构、组件等方面进行讲解,经过本篇文章的学习,想必大家已经掌握了使用Shiro的基本原理和概念,这也是为后续深入学习和实践做好准备了。

(0)

相关推荐