使用 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 可用来换取用户信息)。

发起授权

发起授权需要拼接一个用来授权的 URL,具体参数如下:

参数名

意义

client_id

OIDC 应用的 app_id

redirect_uri

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

scope

需要请求的权限,如果需要获取 unionid 需要包含 unionid,如果需要获取手机号和 email 需要有 phone email,如果需要 refresh_token 需要包含 offline_access 参考 scope 表格

response_type

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

prompt

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

state

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

nonce

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

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

用户登录

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

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

使用 code 换取 token

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

body 参数

参数名

意义

client_id

OIDC 应用的 app_id

client_secret

OIDC 应用的 app_secret

code

授权码,从 redirect_uri 中可直接读取

redirect_uri

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

grant_type

授权类型,此处填写为 authorization_code

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

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

P.S. client_secret_basic 是使用 HTTP Basic authentication 模式进行认证。

请求头

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

body 参数

参数名

意义

code

授权码

redirect_uri

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

grant_type

授权类型,此处填写 authorization_code

其他 Token 换取方式

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

返回示例

验证 access_token 和 id_token 的合法性

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://<appDomain>.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/

使用 access_token 换取用户信息

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

请求链接

返回示例

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

刷新 token

刷新 token 请使用 token 接口返回的 refresh_token.

请求链接

其中 Content-Type 需为 application/x-www-form-urlencoded

body 部分携带参数如下表

参数名

意义

client_id

OIDC 应用的 app_id

client_secret

OIDC 应用的 app_secret

grant_type

refresh_token

refresh_token

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

返回示例

使用隐式流程(Implicit Flow)

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

发起授权

发起授权需要拼接一个用来授权的 URL,具体参数如下:

参数名

意义

client_id

OIDC 应用的 app_id

redirect_uri

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

scope

需要请求的权限

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)

隐式流程将不获取 code,直接在回调地址中附带 codeaccess_tokenid_token,且都以 URL Hash 的形式传递。

发起授权

发起授权需要拼接一个用来授权的 URL,具体参数如下:

参数名

意义

client_id

OIDC 应用的 app_id

redirect_uri

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

scope

需要请求的权限

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 应用,那么授权网址是:

跳转后链接示例:

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

退出 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?