SpringSecurity
核心功能
- 认证
- 授权
- 攻击防护(防止伪造身份)
SpringSecurity的核心是一组过滤器链,项目启动后会自动配置。最核心的是Basic Authentication Filter用于认证用户身份,是一个在框架中一种过滤处理的认证方式。
以上绿色过滤器可以配置是否生效,其他的不可配置。
Oauth2
Oauth
Oauth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分析他们数据的所有内容。
Oauth2是Oauth协议的延续版本,但不向后兼容。
角色
- 资源所有者: 可以授权的实体。(微博要求QQ授权个人信息中的 QQ)
- 资源服务器: 托管受保护资源的服务器,可以接受并使用访问令牌响应的受保护资源请求。(微博要求QQ授权个人信息中的 QQ的存放个人信息的服务器)
- 客户: 提出授权的应用请求的客户端。(微博要求QQ授权个人信息中的 微博)
- 授权服务器: 用于发布访问令牌。(微博要求QQ授权个人信息中的 QQ发放令牌的服务器)
流程
1. 流程图
授权模式
- 授权码模式:功能最完整,流程最严密。
- 简化模式:不通过第三方的服务器,直接在浏览器想认证服务器申请令牌,跳过授权码步骤,所有步骤在浏览器完成,令牌对访问者可见,且客户端不需要认证。
- 密码模式
- 客户端模式
1. 授权码模式
(1)用户访问客户端,后者将前者导向认证服务器,如果用户同意授权,认证服务器将用户导向客户端事先指定的“重定向URI”,同时附上授权码。
(2)客户端收到授权码,附上早先的“重定向URI”,向认证服务器申请令牌:GET /oauth/token?response_type=code&client_id=test&redirect_uri=重定向页面链接。请求成功返回code授权码,一般有效时间为10分钟。
(3)认证服务器核对授权码和uri,确认无误后发送访问令牌和更新令牌。POST /oauth/token?response_type=authorization_code&code=XXX&redirect_uri=XXXlink。
2. 简化模式
(A)客户将用户导向认证服务器。
(B)用户决定是否给客户授权。
(C)用户给予授权,认证服务器将用户导向客户端指定的“重定向URI”,并在URI的Hash部分包含了访问令牌。
(D)浏览器向服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
请求URI:GET /authorize?response_type=token&client_id=XXX&state=XXX&redirect_uri=https://XXX
3. 用户密码模式
(A)用户向客户端提供账号密码。
(B)客户端将账号密码发送给资源服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
**4. 客户端模式
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,想客户端提供访问令牌。
Token
单点登录(SSO模式)
- Session广播
- Cookie+Redis
- 使用Token
1. Session广播
Session是用户的全局变量,在整个会话期间都有效。在微服务中可以把Session复制到所有微服务中获取用户信息。不适合多模块开发,因为会造成内存资源浪费。
2. Cookie+Redis
把redis键值对(key:唯一值,value:用户信息)放入Cookie,每次发送请求都带着cookie发送。缺点是:Cookie不安全,不能跨域实现免登录。
3. Token
登录后按规则生成字符串,然后返回这个字符串。有两种返回方式:① 字符串通过Cookie返回;② 通过地址栏返回。
JWT生成token规则
token包含三个部分:
- header
{
"alg": "HS256", //alg声明加密算法
"type": "token" //type声明类型
}
-
payload(有效载荷)
存放有效信息的地方,包含三部分:①标准中注册的声明;②公共的声明;③ 私有的声明。标准中注册是声明(建议但不强制使用):
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。公共的声明:
可以添加任何信息,一般是用户相关信息和业务的必要信息。私有的声明:
私有声明是提供者和消费所共同定义的声明。
{
"jss": "i",
"useName": "heby",
"admin": true
}
signatrue(签名哈希)
组成包括加密后的header、加密后的载荷、secret三个部分。前两个部分的json拼接中间加一点,再将这个拼接后的字符串用alg中的算法处理。
HMACSHA256(
base64UrlEncode(header) + '.' +
base64UrlEncode(payload),
secret
)