1、Shiro的三个核心组件
- Subject:正与系统进行交互的人,或某一个第三方服务。所有 Subject 实例都被绑定到一个SecurityManager 上,其实就是用于获取外部数据的主体。
- SecurityManager:Shiro 架构的心脏,用来协调内部各安全组件,管理内部组件实例,并通过它来提供安全管理的各种服务,负责和Shiro其他组件交互
- Realm:shiro 是从 Realm 来获取安全数据(用户,角色,权限)。就是说 SecurityManager要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm 得到用户相应的角色/权限进行验证用户是否能进行操作;可以把 Realm 看成 DataSource,即安全数据 源。
2、Shiro的运行流程
- 首先调用Subject.login(token)进行登录,他会委托给SecurityManager
- SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
- Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有就返回认证失败,有的话就继续执行操作。
3、Shiro认证策略
- AtLeastOneSuccessfulStrategy:只要有一个(或更多)的 Realm 验证成功,那么认证将视为成功
- FirstSuccessfulStrategy:第一个 Realm 验证成功,整体认证将视为成功,且后续 Realm 将被忽略
- AllSuccessfulStrategy:所有 Realm 成功,认证才视为成功
- 认证策略默认实现是 AtLeastOneSuccessfulStrategy 方式
5、JWT、cookie、session和token
- JWT:JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
简单说一下JWT、Cookie、Session和Token之间的联系: - 首先,Cookie可以被认为是将用户信息存储在客户端
- 但这种方法不安全,所以出现了Session,也就是将用户信息存储在服务端,然后客户端通过双方约定的Token来确认是服务端中的哪个用户信息
- 但后来出现了分布式服务器,这样就可能导致服务器并没有存储已登录的Session,所以出现了JWT,可以简单理解为将用户信息编码存储在客户端,随请求一起发送到服务端,服务端通过密钥验证判断是不是自己发出去的信息
6、JWT的三部分
- Header:包含算法名称和token的类型,如下
{
'alg': "HS256",
'typ': "JWT"
}
- Payload:是关于实体(通常是用户)和其他数据的信息,如下
{
"sub": '1234567890',
"name": 'john',
"admin":true
}
- Signature:签名,用于验证消息在传递过程中有没有被更改
7、整合Shrio和JWT
8、基于JWT技术的单点登录(SSO)
单点登录:一次登录后可免登陆访问其他的可信平台,例如登录百度后可直接访问百度文库等旗下网站
1. 用户登录流程
- 用户认证:用户首先访问SSO系统中的一个应用,并输入用户名和密码进行登录。
- 生成JWT:认证服务器验证用户的凭据。一旦认证成功,服务器将生成一个JWT,其中包含用户的身份信息(如用户ID)和其他声明(如角色、权限等),但不包含敏感信息。
- JWT签名:JWT通常使用HS256、RS256或ES256等算法进行签名,以确保其不可篡改性和可信度。
- 发送JWT:认证服务器将JWT作为响应的一部分发送给客户端(用户的浏览器)。
- 存储JWT:客户端将JWT存储在本地存储(如localStorage或sessionStorage)或HTTP Cookie中。
2、访问其他应用
- 携带JWT:当用户尝试访问SSO系统中的另一个应用时,客户端会在HTTP请求的Authorization头部携带JWT(通常以Bearer Token的形式)。
- 验证JWT:目标应用的服务器接收到请求后,会验证JWT的签名以确保其有效性,并解析JWT中的信息来识别用户。
- 授权访问:如果JWT验证成功,应用服务器将根据JWT中的信息授予用户相应的访问权限,而无需再次要求用户登录。
3、JWT刷新
- 检查过期时间:JWT通常有一个过期时间(exp),应用服务器在验证JWT时会检查这个字段。
- 刷新令牌:如果JWT接近过期或已经过期,客户端可以发送刷新请求到认证服务器,获取新的JWT。这通常涉及到另一个令牌(refresh token),它具有较长的有效期。
4、退出登录
- 清除JWT:当用户希望退出登录时,客户端需要清除存储的JWT,并可能需要通知所有相关应用服务器删除用户的会话信息。