【OIDC】基本概念

2022-10-04 22:34:57 浏览数 (1)

一、认证和授权

认证 (Authentication):告诉服务器“这个人代表谁”。

授权 (Authenrization):告诉服务器“这个人可以做什么”。

OAuth2.0 定义了【授权】框架;OpenID 为其扩展了【认证】的标准。

OAuth2.0 帮用户获得接口的调用权限;OpenID 为用户提供身份标识。

OpenID 和 OAuth2.0 有着相同的流程。

注意:不是 OAuth2.0 无法完成认证,而是 OAuth2.0 本身的认证过程缺乏统一的标准。

二、流程描述

OAuth2.0 如何完成授权?

所谓授权,就是指拿到令牌(Access Token)的方式。

令牌保存在每次调用 API 的请求中。

curl -H "Authorization: Bearer ACCESS_TOKEN" "https://资源服务器.com"

这里面涉及到几个角色:

资源拥有者:通常是正在操作系统的用户。加入这里的资源指“订单”,那资源所有者就是有权限查看订单数据的用户。

资源服务器:通常指业务系统。比如 B/S 架构的订单管理系统的 S 端。

客户端应用:通常指浏览器。比如 B/S 架构的订单管理系统的 B 端。

授权服务器:通常指认证中心。用户登录界面就是在此系统上。

OAuth2.0 有四种授权模式:

授权码:最完整的流程,适用于有服务端,可以安全存储 AccessToken 的场景。

隐式授权:简化的流程,适用于没有服务端的前端应用。

密码凭证:适用于应用可信任,可以代替服务端收集用户名密码的应用,

客户端凭证:适用于纯后台应用。

具体流程:

授权码(response_type=code):

1. 资源服务器 在 授权服务器 完成注册;

(ClientID、Secret、Callback URL等)

2. 资源拥有者 访问 资源服务器;

(业务的开端)

3. 资源服务器 提供链接,请 资源拥有者 去 授权服务器 完成认证;

代码语言:javascript复制
https://授权中心.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=SCOPE

4. 资源拥有者 完成认证后,在 授权服务器 上继续授权 资源服务器 用自己的身份调用资源;

(XX应用需要使用您的XX信息,是否同意授权?)

5. 授权服务器 将授权码 CODE 转发给第3步中的 REDIRECT_URI;

代码语言:javascript复制
https://REDIRECT_URI?code=CODE

6. 资源服务器 用 CODE 向 授权服务器 换取 Access Token,CODE 随即失效;

代码语言:javascript复制
https://授权中心.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

7. 授权服务器 颁发 Access Token 给 资源服务器,资源服务器 替 资源所有者 保存到 客户端应用 中;

8. 资源所有者 每次通过 客户端应用 访问 资源服务器 都携带此令牌,资源服务器 验证后提供资源服务。

隐式授权(repsonse_type=token):

1. 应用系统 请 资源所有者 访问 授权服务器 的链接;

代码语言:javascript复制
https://授权中心.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&
scope=SCOPE

2. 授权服务器 认证用户,返回 Access Token;

代码语言:javascript复制
https://应用系统.com/callback#token=ACCESS_TOKEN

注意,此时的 Token 存放在锚点中,而非查询参数里,这样可以在 http 协议时避免“中间人攻击”,因为锚点不会发送到服务端。

密码凭证(grant_type=password):

1. 应用系统 要求 资源所有者 提供 用户名 和 密码;

2. 应用系统 将 用户名密码 发送给 授权服务器 换取 Access Token;

代码语言:javascript复制
https://授权中心.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID

注意:这里的 Token 是直接在 JSON 响应中返还,而不需要再跳转。

客户端凭证(grant_type=client_credentials):

1. 应用系统 在后台直接向 授权服务器 索要 Access Token;

代码语言:javascript复制
https://oauth.b.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

OIDC 模式

OIDC 为 OAuth2.0 扩展了 scope=openid 的场景,在返回值中会额外增加 ID_TOKEN:

代码语言:javascript复制
https://授权服务器.com/authorize?
    response_type=code
    &scope=openid profile email
    &client_id=CLIENT_ID
    &state=STATE
    &redirect_uri=REDIRECT_URI

响应数据:

代码语言:javascript复制
{
   "access_token": ACCESS_TOKEN,
   "token_type": "Bearer",
   "refresh_token": REFRESH_TOKEN,
   "expires_in": EXPIRES_IN_SECOND,
   "id_token": JWT_ID_TOKEN
}

0 人点赞