Spring Security OAuth2
OAuth 是一种用来规范令牌(Token)发放的授权机制,主要包含了四种授权模式: 授权码模式、简化模式、密码模式、客户端模式。
OAhuth 在
客户端
与服务提供伤
之间,设置了一个授权层(authorization layer),客户端
不能直接登录服务提供商
只能登陆授权层,以此将用户与客户端区分开。客户端
登陆授权层所用到的令牌(token),与用户密码不同。用户可以在登陆的时候,指定授权层令牌的权限范围,和有效期。
名称 简单说明 Third-party application 第三方应用程序,例如虎牙直播 HTTP service HTTP 服务供应商,例如:腾讯 qq Resource Owner 资源所有者,例如: 我的qq User Agent 用户代理,浏览器 Authorization server 认证服务器,第三方登录服务 Resource server 资源服务器,需要认证之后才可以提供服务的服务器 认证服务器和资源服务器可以在同一台服务器上
四种授权模式
授权码模式 ‼️
最严格,最完整的授权模式。最能体现OAuth2协议
步骤1中URL携带参数 | 描述 |
---|---|
response_type | 授权类型,固定为code :标识授权码模式。必须项 |
client_id | 客户端ID。必须项 |
redirect_uri | 重定向URl |
scope | 申请到权限范围 |
state | 客户端当前状态,指定任意值,认证服务会返回这个值 |
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
步骤3 服务器回应客户端URL参数 | 描述 |
---|---|
code | 授权码。必选项 该码有效期通常设置10分钟,客户端只能使用一次。该码与客户端ID和重定向URI,是一一对应 |
state | 如果客户端请求中包含这个参数,认证服务器回应也必须一摸一样包含这个参数 |
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
步骤4 客户端向认证服务器申请令牌携带参数 | 描述 |
---|---|
grant_type | 使用的授权模式,固定为authorization_code 。必须项 |
code | 上一步获得授权码。必须项 |
redirect_uri | 重定向URL,且必须与 1步骤中的该参数保持一致。必选项 |
client_id | 客户端ID。必须项 |
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
步骤5 认证服务发送HTTP回复 参数 | 描述 |
---|---|
access_token | 访问令牌。必选项 |
token_type | 令牌类型,不区分大小写,bearer/mac 类型。必选项 |
expires_in | 过期时间单位秒,如果省略该值,必须其他方式设置过期时间 |
refresh_token | 更新令牌,用来获取下一次访问令牌。 |
scope | 权限范围,如果与客户端申请的范围一致,可省略 |
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
密码模式
Resource Owner Password Credentials Grant ,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务提供商"索要权限
用户必须把自己的秘密给客户端,但客户端不得存储秘密。
步骤2 客户端 发出HTTP 参数 | 描述 |
---|---|
grant_type | 授权类型,固定值password 。必选项 |
username | 用户名。必选项 |
password | 密码。必选项 |
scope | 权限范围 |
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w
步骤3 认证服务器向客户端发访问令牌
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
简化模式
implicit grant type 不通过第三方应用程序服务器,直接在浏览器中向认证服务器申请令牌,跳过了
授权码
这个步骤。所有的步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
客户端模式
Client Credentials Grant ,客户端用自己的名义,向
服务提供商
进行认证。
更新令牌
用户访问时,
访问令牌
过期。客户端发起更新请求,包含一下参数
- granttype: 授权模式,固定
refreshtoken
。必选项- refresh_token: 标识早前收到的更新令牌。必选项
- scope:标识申请的权限范围,不可以超过上一次申请的范围。默认和上次一样
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA