Apache Shiro是很流行的一个java安全框架,可以帮助我们完成认证、授权、加密、会话管理、与web继承、缓存
等操作。虽然没有Spring Security的功能那么强大,但是在实际工作中很多时候使用小而简单的shiro就足够了。
在开始学习shiro之前,我们先从宏观上介绍一下shiro的架构,让大家对shiro有个整体印象。
对于一个好的框架,要满足对外能够提供简单易用的API,对内应该有一个可扩展的架构。任何框架都不能满足所
有需求,所以对内要可以非常容易插入用户自定义实现。那么我们就分别从外部和内部看一下shiro架构。
外部架构
从外部即从应用程序的角度来观察shiro架构可以看到,应用代码直接交互的对象是Subject,也就是说shiro的对
外API核心为Subject;
Subject
主体,代表当前“用户"。这里的"用户"是一个抽象概念,不一定是具体的某个人,与当前应用交互的任何东西都
是一个Subject。
SecurityManager
安全管理器,相当于SpringMVC中的DispatcherServlet前端控制器,是shiro的核心;所有具体的交互都通过
securityManager进行控制。
每个subject都必须与一个securityManager进行绑定,我们访问subject对象其实都是在于securityManager的特
定subject进行交互;另外,securityManager还负责进行认证和授权、及会话、缓存的管理。
Realm
Realm实质上是一个安全相关的DAO,充当shiro与应用安全数据间的桥梁,封装了数据源的连接细节,并在需要
时将相关数据提供给shiro,因此可以把它看成DataSource安全数据源。
shiro从realm获取安全数据(如用户、角色、权限),也就是说如果securityManager要验证用户身份,它需要从
Realm获取相应的用户信息进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用
户是否能进行操作;
1、应用代码通过subject来进行认证和授权,而subject又委托给securityManager;
2、我们需要给shiro的securityManager注入Realm,从而让securityManager能得到合法的用户及其权限进行判断。
通过以上两点,从某些角度或许我们可以简单地把它理解为是一种MVC的实现:subject是负责与外界交互的视图
层U层,securityManager是负责处理一系列操作的业务逻辑层B层,Realm是负责与数据库交互的数据访问层D层。
内部架构
同上述说明类似,subject是应用代码交互的主体;securityManager典型的外观模式,是所有交互的核心;Realm
是安全实体数据源。
需要注意的是,Realm是可插拔的可以有1个或多个,且支持多种实现:可以是JDBC实现,也可以是LDAP实现,或
者内存实现等等。shiro不知道你的用户、权限存储在哪及以何种格式存储,所以我们一般在应用中都需要实现自己
的Realm;
Authenticator
对“Who are you ?”进行核实。通常涉及用户名和密码。负责收集principals 和 credentials,并将它们提交
给应用系统。如果提交的 credentials 跟应用系统中提供的 credentials吻合,就能够继续访问,否则需要重新提
交 principals 和 credentials,或者直接终止访问。
Authorizer
身份份验证通过后,由这个组件对登录人员进行访问控制的筛查,比如“who can dowhat”, 或者“who can do
which actions”。Shiro 采用“基于 Realm”的方法,即用户(又称Subject)、用户组、角色和 permission 的聚
合体。
SessionManager
session控制器,管理session的生命周期。shiro可以用在web、J2SE、EJB等很多环境,因此shiro抽象了一个自己
的session来管理主体与应用之间交互的数据。例如,一台web服务器,一台EJB服务器,我们想把两台服务器的会话
数据放到一个地方,这时候就可以实现自己的分布式会话,如把数据放到memcached服务器。
sessionDAO
DAO我们都不陌生。比如我们想把session保存到数据库,可以实现自己的sessionDAO;如果想把session存
memcached中,那么可以实现自己的Memcached SessionDAO.
CacheManager
缓存控制器,来管理如用户、角色、权限等的缓存。这些数据很少改变,放到缓存中后可以提高访问性能。可以
放在SessionDAO中使用。
Cryptography
密码模块,shiro提供了一些常见的加密组件用于如密码加密解密的。
由上可以看出,shiro既对外提供了简单易用的API,对内又可以扩展自己的实现,是一个很好的安全框架。
记住一点:shiro不会维护用户、维护权限;这些需要我们自己去设计提供,然后通过相应的接口注入给shiro即可。