使用 OIDC 授权

结合 Authing 实现 OIDC 授权的方法。

术语

  1. End-User:终端用户,也可以理解为使用你软件的人

  2. RP(Relying-Party):服务器后端

  3. AP(Authentication Provider): Authing 服务器

P.S. 文档中出现的 testapp.authing.cnexample.authing.cn 两个域名是可以在控制台配置的二级域名。

在 Authing 中创建一个应用

使用 OIDC 需要先注册一个 Authing 账号新建一个应用

创建 OIDC 应用

在完成了 Authing 应用的创建后相当于你拥有了一个用户池,接下来需要创建一个 OIDC 应用,这样你可以在其他第三方软件中读取用户池中的用户数据,其你给参考:

创建 OIDC 应用

OIDC 的基本流程

  1. 用户执行登录

  2. 登录成功后回调到开发者配置好的 redirect_uri 中并附带参数

  3. 如果返回类型是 code,那么开发者需要在后端使用 code 和 secret(用户创建完 OIDC 应用后会得到)换取 access_token

  4. 如果返回类型是 id_token token,那么在用户登录成功后的回调 URI 中会直接附带 id_token 和 access_token

  5. 使用 access_token 可以换取用户信息(userInfo)

如果你想直观的体验 OIDC 认证流程,请点击这里查看我们提供的示例点击这里可视化的理解 OIDC

如果你对如何在后端处理 OIDC 有困惑,请参考 Github 上的示例代码:oidc-demo

使用授权码模式(Authorization Code Flow)

这个小节介绍如何使用 code (response_type 为 code)换取 access_token(access_token 可用来换取用户信息)。

01 - 在控制台配置 OIDC 应用

打开 authorization_code 模式,并选择 code 返回类型。

02 - 发起登录请求

发起 OIDC 登录请求并让终端用户在浏览器中访问

GET https://<你的应用域名>.authing.cn/oauth/oidc/auth

发起授权需要拼接一个用来授权的 URL,并让终端用户在浏览器中访问,具体参数如下:

Query Parameters

Name
Type
Description

client_id

string

OIDC 应用的 app_id

redirect_uri

string

在控制台配置的 OIDC 回调 url 其中的一个值

scope

string

需要请求的权限,必须包含 openid。如果需要获取 unionid 需要包含 unionid;如果需要获取手机号email 需要包含 phone email;如果需要用户与 Authing 之间的 Token 需要包含 authing_token;如果需要 refresh_token 需要包含 offline_access。多个 scope 请用空格分隔。同时 id_token 中会包含相关的字段

response_type

string

OIDC 模式,可以为 code, id_token, id_token token, code id_token, code token, code id_token token

prompt

string

可以为 none,login,consent 或 select_account,指定 AP 与 End-User 的交互方式,如需 refresh_token,必须为 consent

state

string

一个随机字符串,用于防范 CSRF 攻击,如果 response 中的 state 值和发送请求之前设置的 state 值不同,说明受到攻击

nonce

string

一个随机字符串,用于防范 Replay 攻击

请求示例:

如需后续刷新 access_token,请按照以下方式拼接登录链接

带刷新 token 功能的登录请求示例:

参考资料:

03 - 用户登录

上一个请求验证通过后会重定向到 Authing 提供的登录框页面,此时用户需要输入他的用户名和密码进行登录。

你可以前往这个网址体验:https://sample-sso.authing.cn/login

此时 Authing 会验证此用户是否合法,如果合法则会跳到用户配置好的 redirect_uri 中并附带 code 参数。

04 - 使用 code 换取 token

client_secret_post 方式换取 token

POST https://<你的应用域名>.authing.cn/oauth/oidc/token

如果你在控制台配置 OIDC 时,换取 token 方式设置的为 client_secret_post,那么按照下面这种方法换取 token。

Headers

Name
Type
Description

Content-Type

string

application/x-www-form-urlencoded

Request Body

Name
Type
Description

client_id

string

OIDC 应用的 App ID

client_secret

string

OIDC 应用的 App Secret

grant_type

string

authorization_code

redirect_uri

string

在控制台配置的 OIDC 回调 url 中其中一个值

code

string

获取到的授权码,一个 code 仅限一次性使用,用后作废,有效期 10 分钟

这里有完整的 nodejs 示例代码

使用 curl 发送请求示例:

返回示例:

id_token 中会包含 scope 参数请求的信息,例如邮箱、手机号,解析后的 id_token:

client_secret_basic 方式换取 token

POST https://<你的应用域名>.authing.cn/oauth/oidc/token

如果你在控制台配置 OIDC 时,换取 token 方式设置的为 client_secret_basic,那么按照下面这种方法换取 token。(client_secret_basic 是使用 HTTP Basic authentication 模式进行认证。)

Headers

Name
Type
Description

Authorization

string

Basic NWNhNzY1ZTM5MzE5NGQ1ODxxxx

Content-Type

string

application/x-www-form-urlencoded

Request Body

Name
Type
Description

grant_type

string

authorization_code

redirect_uri

string

在控制台配置的 OIDC 回调 url 中其中一个值

code

string

获取到的授权码,一个 code 仅限一次性使用,用后作废,有效期 10 分钟

其中 Authorization 请求头 Basic<空格> 后的值为 <client_id>:<client_secret> 的 base64 值。

none 方式换取 token

POST https://<你的应用域名>.authing.cn/oauth/oidc/token

如果你在控制台配置 OIDC 时,换取 token 方式设置的为 none,那么换取 token 时无需传递 client_secret,其他参数和上表一样。

Headers

Name
Type
Description

Content-Type

string

application/x-www-form-urlencoded

Request Body

Name
Type
Description

client_id

string

OIDC 应用的 App Secret

grant_type

string

authorization_code

redirect_uri

string

在控制台配置的 OIDC 回调 url 中其中一个值

code

string

获取到的授权码,一个 code 仅限一次性使用,用后作废,有效期 10 分钟

如果你想了解其他换取 Token 的方式,请参考 OIDC 规范

05 - 验证 access_token 和 id_token 的合法性

使用 OIDC 应用的 App Secret 检验

OIDC 默认使用 OIDC 应用的 secret 对 token 进行验证(也就是在创建应用时默认选择 HS256 算法)。

如果你使用 javascript 那么可以使用 jsonwebtoken 进行验证:

如果是其他语言,那么你在服务端需要用 app_secret 作为 HS256 签名参数来计算签名和 JWT 中的签名进行对比,伪代码如下:

如果是 RS256 等非对称加密算法,需要使用公钥验证签名。Authing 将使用私钥进行签名,请使用 Authing 的公钥来验证签名:

将 token 或 id_token 发送到 Authing 提供的 token 验证接口进行验证

在线验证 access_token / id_token 合法性

GET https://<你的应用域名>.authing.cn/oauth/oidc/validate_access_token

Authing 提供了接口用于直接在线验证 access_token 或 id_token 的合法性。

Path Parameters

Name
Type
Description

access_token

string

值为 access_token 或 id_token

参考链接

  1. jwks 参考规范

  2. 可以检验 jwt 的签名的 playground:https://jwt.io

  3. RSA 的 pem 格式 与 jwk 格式互转:https://8gwifi.org/jwkconvertfunctions.jsp

  4. 生成 jwk:https://mkjwk.org/

06 - 使用 access_token 换取用户信息

开发者在自己的服务中可以使用 access_token 换取用户信息。根据 scope 的不同,这里的返回信息也会有所不同,字段符合 OIDC 规范,字段解释请参考用户信息字段含义

使用 access_token 换取用户信息

GET https://users.authing.cn/oauth/oidc/user/userinfo

Query Parameters

Name
Type
Description

access_token

string

access_token

请求链接示例:https://users.authing.cn/oauth/oidc/user/userinfo?access_token=<access_token>

返回示例:

更多字段解释请参考用户信息字段含义

07 - 刷新 token

07- 刷新 token

POST https://<你的应用域名>.authing.cn/oauth/oidc/token

如需使用刷新 token 功能,需要进入控制台 > 第三方登录 > OIDC 应用,点击你的 OIDC 应用,在 OIDC 应用设置中勾选 refresh_ token。 发起登录请求时必须填写正确 URL 的参数,scope 参数中必须有 offline_accessprompt 参数值必须为 consent。带刷新 token 权限的登录请求示例: https://example.authing.cn/oauth/oidc/auth?client_id=5c9b079883e333d55a101082&redirect_uri=https://example.com&scope=openid profile offline_access&response_type=code&prompt=consent&state=235345

Headers

Name
Type
Description

Content-Type

string

application/x-www-form-urlencoded

Request Body

Name
Type
Description

client_id

string

OIDC 应用的 App Id

client_secret

string

OIDC 应用的 App Secret

grant_type

string

refresh_token

refresh_token

string

code 换 token 接口返回的 refresh_token。例:WPsGJbvpBjqXz6IJIr1UHKyrdVF

开启 refresh_token 功能

使用隐式模式(Implicit Flow)

隐式模式将不获取 code,直接在回调地址中附带 access_tokenid_token

在控制台配置 OIDC 应用

选择 implicit 模式,并在下方选择 id_token tokenid_token

配置 OIDC implicit 模式

发起授权

发起授权需要拼接一个用来授权的 URL,并让终端用户在浏览器中访问,具体参数如下:

参数名

意义

client_id

OIDC 应用的 app_id

redirect_uri

在控制台配置的 OIDC 回调 url 其中的一个值。启用隐式模式时,控制台配置的所有 redirect_uri 必须都为 https 协议

scope

需要请求的权限,必须包含 openid。如果需要获取 unionid 需要包含 unionid;如果需要获取手机号email 需要包含 phone email;如果需要用户与 Authing 之间的 Token 需要包含 authing_token;多个 scope 请用空格分隔。同时 id_token 中会包含相关的字段。隐式模式不能刷新 token,所以 offline_access 字段无效。

response_type

OIDC 模式,可以为 id_token, id_token token。参考 OIDC 规范

prompt

可以为 none,login,consent 或 select_account,指定 AP 与 End-User 的交互方式。参考 OIDC 规范

state

一个随机字符串,用于防范 CSRF 攻击,如果 response 中的 state 值和发送请求之前设置的 state 值不同,说明受到攻击。

nonce

一个随机字符串,用于防范 Replay 攻击,implicit 模式下必须填。

假设你创建了一个域名为 example 的 OIDC 应用,那么授权网址是:

获取 id_token 和 access_token

id_token、access_token 会以 URL hash 的形式传递,跳转后链接示例:

换取用户信息的流程和授权码模式相同。

参考资料:

使用混合模式(Hybrid Flow)

混合模式直接在回调地址中附带 codeaccess_tokenid_token,且都以 URL Hash 的形式传递。

在控制台配置 OIDC 应用

选择 authorization_codeimplicit,并在下方勾选 code id_token tokencode id_tokencode token

配置 OIDC Hybrid 模式

发起授权

发起授权需要拼接一个用来授权的 URL,并让终端用户在浏览器中访问,具体参数如下:

参数名

意义

client_id

OIDC 应用的 app_id

redirect_uri

在控制台配置的 OIDC 回调 url 其中的一个值。启用隐式模式时,控制台配置的所有 redirect_uri 必须都为 https 协议。

scope

需要请求的权限,必须包含 openid。如果需要获取 unionid 需要包含 unionid,如果需要获取手机号email 需要包含 phone email,如果需要用户与 Authing 之间的 Token 需要包含 authing_token。多个 scope 请用空格分开。同时 id_token 中会包含相关的字段。如果需要刷新 token,需要有 offline_access 参数,同时 response_type 参数中必须包含 code并使用 code 换取 token,否则 offline_access 字段无效。

response_type

OIDC 模式,此处为 code id_token token。参考 OIDC 规范

prompt

可以为 none,login,consent 或 select_account,指定 AP 与 End-User 的交互方式。参考 OIDC 规范

state

一个随机字符串,用于防范 CSRF 攻击,如果 response 中的 state 值和发送请求之前设置的 state 值不同,说明受到攻击。

nonce

一个随机字符串,用于防范 Replay 攻击,混合模式下必填。

假设你创建了一个域名为 example 的 OIDC 应用,那么授权网址是:

code、access_token 和 id_token 通过 URL hash 传递,跳转后链接示例:

换取用户信息的流程和授权码模式相同。

参考资料:

使用 Password 模式

不推荐使用此模式,尽量使用其他模式。

在控制台配置 OIDC 应用

控制台 > 第三方登录 > OIDC 应用,打开 OIDC 应用详情,在表单的授权模式中勾选「password」。

password 模式选项框打勾。点击「确定」。

开启 Password 模式

使用登录凭据换取 token

POST https://<你的应用域名>.authing.cn/oauth/oidc/token

在 Password 模式中,可以直接使用用户的登录凭据换取 OIDC token

Request Body

Name
Type
Description

scope

string

授权域,一个字符串,openid 为必选,可选值有 profile email address phone offline_access。不同的值之间用空格分开。profile 是用户基本信息,email 是用户邮箱,address 是用户地址,phone 是用户手机号,offline_access 会返回 refresh_token,用于后续刷新 OIDC Token。默认为 openid profile。

password

string

密码,当没有填写 unionid 时必填。

unionid

string

三方身份提供商身份 ID,与手机号、邮箱、用户名互斥。

phone

string

手机号,与邮箱、用户名、unionid 互斥。

email

string

邮箱,与用户名、手机号、unionid 互斥。

username

string

用户名,与邮箱、手机号、unionid 互斥。

grant_type

string

必须填 password

client_secret

string

OIDC 应用 secret。

client_id

string

OIDC 应用 id。

当使用 unionid 作为用户标识时,可以不传 password 字段。其他标识 email、phone、username 必须传入用户密码 password 字段。

参考资料

使用 authingToken 模式

在控制台配置 OIDC 应用

控制台 > 第三方登录 > OIDC 应用,打开 OIDC 应用详情,在表单的授权模式中勾选「authingToken」。

开启 authingToken 授权模式

使用 Authing Token 换取 OIDC token

POST https://<你的应用域名>.authing.cn/oauth/oidc/token

在 authingToken 模式中,可以直接使用用户的 Authing Token 换取 OIDC token。

Request Body

Name
Type
Description

scope

string

授权域,一个字符串,openid 为必选,可选值有 profile email address phone offline_access。不同的值之间用空格分开。profile 是用户基本信息,email 是用户邮箱,address 是用户地址,phone 是用户手机号,offline_access 会返回 refresh_token,用于后续刷新 OIDC Token。默认为 openid profile。

authingToken

string

用户的 Authing Token。

grant_type

string

必须填 authingToken

client_secret

string

OIDC 应用 secret。

client_id

string

OIDC 应用 id。

退出 SSO

如果你使用了 OAuth、OIDC 或 SAML 实现了单点登录,那么使用户退出登录需要跳转到一个 URL:

https://<你的域名>.authing.cn/login/profile/logout?app_id=<OAuth 应用 ID>&redirect_uri=<退出之后的回调地址>

其中 app_idredirect_uri 都是必填选项,redirect_uri 是退出后你想要返回的地址。

如果你想要在后端退出 SSO,可以自行维护一个 Cookie - Session 的状态,然后设置 Cookie 过期即可。

接下来你可能需要

OIDC 常见问题

Last updated

Was this helpful?