接下来我们来从 Shiro 内部来看下 Shiro 的架构,如下图所示:
- Subject:主体,可以看到主体可以是任何可以与应用交互的 “用户”,所有的用户都需要受到 SecurityManager 的管理,Subject里面存储着当前“用户”的部分信息;
- SecurityManager:SecurityManager是Shiro的另一个核心模块,用于管理Subject的安全操作,包括身份认证、授权以及会话管理等。相当于 SpringMVC 中的 DispatcherServlet ,是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行控制;它管理着所有 Subject且负责进行认证和授权、会话、缓存的管理。Shiro提供了多种SecurityManager实现,开发者可以根据需要自行配置使用。
- Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得 Shiro 默认的不好,可以自定义实现;认证是需要设置认证策略(Authentication Strategy),即什么情况下算用户认证通过了
ModularRealmAuthenticator默认使用AtLeastOneSuccessfulStrategy策略。, - Authorizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能,授权大多数判断角色或者更细粒度的判断权限,基于RBAC权限认证机制进行实现;
- Realm:可以有 1 个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是 JDBC 实现,也可以是 LDAP 实现,或者内存实现等等;由用户提供;注意:Shiro 不知道你的用户 / 权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的 Realm;
shiro提供多种认证过滤方式
FirstSuccessfulStrategy:只要有一个 `Realm` 验证成功即可,只返回第一个 `Realm` 身份验证成功的认证信息,其他的忽略
AtLeastOneSuccessfulStrategy :只要有一个 `Realm` 验证成功即可;
AllSuccessfulStrategy:所有 `Realm` 验证成功才算成功,且返回所有 `Realm` 身份验证成功的认证信息,如果有一个失败就失败了;
- SessionManager:SessionManager是用于管理Subject的会话生命周期的组件。Session是指访问应用程序时,为了保持客户端和服务端的状态同步,将客户端信息存储到服务端并维持该信息状态的一种过程。而 Shiro 并不仅仅可以用在 Web 环境,也可以用在如普通的 JavaSE 环境、EJB 等环境;登录成功后使用 Subject.getSession() 即可获取会话;其等价于 Subject.getSession(true),即如果当前没有创建 Session 对象会创建一个;另外 Subject.getSession(false),如果当前没有创建 Session 则返回 null(不过默认情况下如果启用会话存储功能的话在创建 Subject 时会主动创建一个 Session)。 SessionManager主要有以下几个作用:
- 创建Session:SessionManager负责创建新的Session。
- 删除Session:SessionManager负责将过期的或不再需要的Session从底层的存储中删除。
- 管理Session状态:SessionManager负责管理Session的周期,包括Session的超时判断、立即失效、延迟过期等等。
- 绑定到Subject:SessionManager负责将Session与相应的Subject绑定。
- SessionDAO:DAO 大家都用过,数据访问对象,用于会话的 CRUD,比如我们想把 Session 保存到数据库,那么可以实现自己的 SessionDAO,通过如 JDBC 写到数据库;比如想把 Session 放到 Memcached 中,可以实现自己的 Memcached SessionDAO;另外 SessionDAO 中可以使用 Cache 进行缓存,以提高性能;
- CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能,Shiro 提供了 CachingRealm,其实现了 CacheManagerAware 接口,提供了缓存的一些基础实现;另外 AuthenticatingRealm 及 AuthorizingRealm 分别提供了对 AuthenticationInfo 和 AuthorizationInfo 信息的缓存。
- Cryptography:密码模块,Shiro 提供了一些常见的加密组件用于如密码加密和解密的。Shiro 提供了 base64 和 16 进制字符串编码和解码的 API 支持,方便一些编码解码操作。Shiro 内部的一些数据的存储表示都使用了 base64 和 16 进制字符串。Shiro 还提供对称式与非对称加密和解密算法的支持,如 AES、Blowfish,MD5、SHA 等;非对称加密采用的是散列算法,可以散列中加入加密数据、加密算法、salt、加密次数对数据进行加密。PasswordService 及 CredentialsMatcher 用于提供加密密码及验证密码服务。
从外部简单的来看主要就是 subject 、 SecurityManager 、 Realm 三部分
graph TD
ApplicationCode -->
subject --> SecurityManager --> Realm