Shiro 系列 - 基本知识

 和 Spring Security 项目一样, Apache Shiro 也是一个被广泛使用安全框架, 它们都能完成认证、授权、会话管理等. 简单对比一下 Apache Shiro 和 Spring Security:

1. 适用范围: Spring Security 必须和 Spring MVC 一起使用, 而 Shiro 是一个通用的安全框架, 可以用在 Spring MVC 或 JavaEE/JavaSE 环境中.
2. 复杂程度: Spring Security 是一个非常复杂的架构, 虽然搭配 Spring Boot 后, 使用的难度小了些, 但是还是很复杂. Shiro  概念少, 使用也简单了很多.
3. 版本变动: Spring Security 变化很频繁, 网上教程多是基于 Spring Boot 1.x 的, 在 Spring Boot 2.x 下很多都不适用了. Shiro 从 2010 年发展到现在, 功能和代码已经相当成熟了, 几乎不会有大的变动.
4. 功能多少方面, 方面: Spring Security 内置支持 CSRF 保护, Shiro 没有开箱即用, 基于 Shiro 的项目 buji-pac4j 实现了 CSRF 保护.


==========================
Shiro 的几个概念
==========================
Subject: Subject 代表当前登录系统的主体对象, 比如 username 或 appId.
Realm: 负责提供认证和授权的信息源, 数据源可以来源 Jdbc 数据库或其他.
SecurityManager: Shiro 的核心, 我们需要将 Realm 注入到 SecurityManager, 然后 SecurityManager 为我们提供授权功能. SecurityManager 同时也是内部各个组件的组装器, 如果我们要实现自己的 Cache 或 Session 管理器, 也是通过 SecurityManager 注入.
SecurityManager的两个实现类:
1. DefaultSecurityManager: 用于 JavaSE 环境
2. DefaultWebSecurityManager: 用于 Web 环境的实现, 对应底层使用的是 ServletContainerSessionManager 类 Session 管理器.

--------------------------
内部架构:
--------------------------
Authenticator: 认证器, 内置一个实现类是 ModularRealmAuthenticator, ModularRealmAuthenticator 默认的认证策略是 AtLeastOneSuccessfulStrategy, 在这个策略下, 如果我们提供了多个 Realm, 只要一个 Realm 认证通过, 即表示最终认证通过. 可选的认证策略有: AllSuccessfulStrategy(全部认证通过), AtLeastOneSuccessfulStrategy(至少一个认证通过), FirstSuccessfulStrategy (首个认证通过).

Authorizer: 授权器, 或者访问控制器, 用来决定主体是否有权限对某个资源有操作权限.

Cache manager, 用来管理用户、角色、权限缓存, 通常这些配置信息不会频繁改变, 使用 cache 可以提高性能. Shiro 不提供 cache DAO 实现, 如果我们要使用 cache 功能, 需要自己实现.

Session Manager, Shiro 使用 session 来管理 subject 的生命周期, 包括: 创建/停止/过期 等等, shiro 内置了三个实现:
1. DefaultSessionManager, DefaultSecurityManager 使用的默认 Session Manager,用于 JavaSE 环境.
2. ServletContainerSessionManager, DefaultWebSecurityManager 使用的默认 Session Manager,用于 Web 环境,其直接使用 Servlet 容器的会话.
3. DefaultWebSessionManager, 用于 Web 环境的实现,可以替代 ServletContainerSessionManager, 自己维护着会话, 直接废弃了 Servlet 容器的会话管理.


--------------------------
认证和赋权相关几个术语:
--------------------------
AuthenticationInfo 接口: 认证通过的身份和凭证. 在 realm 类中, 需要实现一个 doGetAuthenticationInfo(AuthenticationToken) 方法, 在该方法中, 先验证用户密码是否 OK, 验证通过后需要返回 AuthenticationInfo 接口的实现, 通常使用的实现类是 SimpleAccount 或 SimpleAuthenticationInfo. SimpleAccount 和 SimpleAuthenticationInfo 中包含着 Principal[身份] 和 Credentials[凭证] 信息.

Principal[身份] 和 Credentials[凭证]  : Principal 基本等同于 Username, Credentials 往往等同于 password, 需要说明的是, Shiro 支持使用多个 realm 作为认证数据源, 所以一个 subject 有可能会有多个 Principal 的. Principal 是通过验证后才被创建的对象, 可以通过 subject 对象获取 Principal.

AuthorizationInfo 接口: 包含用户所属的角色和具备的权限. 在 realm 类中, 需要实现一个 doGetAuthorizationInfo(PrincipalCollection principals) 方法.

AuthenticationToken: 是用来提交验证的 token 值, 经常使用的实现类是 UsernamePasswordToken.

==========================
使用 Shiro 的一般过程是:
==========================
1. 创建 SecurityManager 对象
    对于 Web 项目可以直接 new DefaultWebSecurityManager 子类, ini 文件的realm也可以使用 IniSecurityManagerFactory 工厂方法创建.
2. 在程序中注入 SecurityManager 对象,
    对于 Spring 项目, 需要定义一个 ShiroFilterFactoryBean bean, 然后通过该bean来注册 SecurityManager, shiroFilterFactoryBean.setSecurityManager(securityManager) .
    对于其他项目, 可以使用 SecurityUtils.setSecurityManager(securityManager) 注入.
3. 进行资源授权配置.
    对于 Spring 项目, 可以用 ShiroFilterFactoryBean bean来设置拦截器;
    也可以在 ini 文件的 url 节中定义资源授权配置.
4. 定义 Realm, 实现 doGetAuthenticationInfo(AuthenticationToken) 和 doGetAuthorizationInfo() 方法. doGetAuthenticationInfo( authcToken)
     对于 JDBC , 一般是 user/role/permission 三张表, 以及 user_role/role_permssion 两个关系表.
    也可以在 Ini 文件中定义, 基本用作demo.
5. 使用 SecurityUtils.getSubject() 获取 subject, 然后调用 subject.login(), 该方法将触发 realm 的 doGetAuthenticationInfo(AuthenticationToken authcToken) 方法, 进行身份验证
6. 在进行权限验证的时候, 会触发 realm 的 doGetAuthorizationInfo(PrincipalCollection principals) 函数, 由该函数进行角色和权限的验证.

猜你喜欢

转载自www.cnblogs.com/harrychinese/p/shiro_basics.html
今日推荐