OIDC¶
最后更新:2021-12-03
应用介绍¶
OIDC是什么?¶
OIDC,是OpenID Connect的简称,它是基于OAuth2协议的身份认证授权标准协议。 可以简单理解为:OIDC = OAuth2 + (Identity或Authentication)。
使用OIDC的前提是已经掌握了OAuth2。OAuth2是一个授权(Authorization)协议,
但它无法提供完善的身份认证信息(一般使用时将OAuth2与其他框架如Spring Security整合起来对外提供身份认证授权服务)。
OIDC在OAuth2基础上提供了ID Token
(OAuth2中有Access Token
)来解决用户身份认证的问题,
ID Token
一般使用JWT格式数据,由于JWT有自包含性,防篡改机制以及适合于网络上传输等特点,使得ID Token
能
安全地传递给第三方客户端并能进行校验(verify)。
此外,在OIDC中还提供了诸如Userinfo Endpoint
,Discovery Endpoint
等接口扩展了协议的适用性。
更多关于OIDC的介绍请查看官方站点http://openid.net/connect/。
IDaaS平台OIDC概述¶
在IDaaS平台中,我们把OIDC作为标准应用协议进行实现,只要部署了IDaaS产品就能在’添加应用’的’标准协议’中找到OIDC的身影,可直接使用。
平台提供的OIDC支持能力如下:
Grant Type
,支持authorization_code
,implicit
与PKCE
。密钥轮转
,支持不自动轮转
,每月轮转
,每季度轮转
与每年轮转
。Response Mode
,支持query
,fragment
与form_post
。支持自定义
access_token
,id_token
,refresh_token
有效时间。支持配置应用IP白名单。
如何使用¶
管理OIDC应用¶
创建OIDC应用¶
以IT管理员登录IDaaS平台,依次进入:添加应用 -> 标准协议,找到 OIDC应用,点击’添加应用’,如下图:
在打开的添加应用界面上填入需要对应的应用提供的相关信息,主要参数说明:
Redirect URI,应用接收
code
的URI地址,对应OAuth2中参数redirect_uri
。Response Mode,选择一种即可。
Grant Type,选择具体的值即可,若选择
PKCE
具体请查看’PKCE使用说明’部分内容。轮转类型,选择OIDC密钥轮换的策略,具体请查看’密钥轮转’部分内容。
输入完各项信息后,点击’提交’即创建完成OIDC应用(若配置有错误在提交时会进行校验并提示信息)。
修改OIDC应用¶
提示:默认创建应用成功后的状态为’启用’的,要修改应用需要先把状态禁用。
应用状态可修改为启用或禁用。
可开启或关闭应用二次认证。
点击’修改应用’可更新应用的信息。
点击’删除应用’可删除已有的数据。
查看OIDC应用¶
在上图的’应用信息’一栏中点击’查看详情’进入OIDC应用详细信息,如下图:
详情中的很多信息需要复制下来,在调用OIDC API进行集成时需要使用到。
Client Id,Client Secret。
Discovery Document URL,对应OIDC协议中的
Discovery Endpoint
。OIDC PublicKey,OIDC中第三方客户端用于校验
id_token
。Authorize URL,SP发起认证的URL。
各类
token
的有效时间值。应用IP白名单(可选 )。
IDP SLO 地址,OIDC退出时的URL地址格式。
OIDC中的API¶
在IDaaS平台上创建OIDC应用后,并获取到各类信息后(如 Client Id, Client Secret),需要通过API来进行集成。 下面对提供的各类API进行介绍。
Discovery Endpoint¶
Discovery Endpoint
是OIDC协议中规定的用于获取OIDC各类信息的接口。
URL定义
GET /public/api/application/plugin_oidc/oidc/.well-known/openid-configuration HTTP/1.1
请求示例
https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/.well-known/openid-configuration
响应示例
{
"response_types_supported": [
"id_token",
"code",
"id_token token"
],
"claims_supported": [
"sub",
"aud",
"scope",
"iss",
"nonce",
"exp",
"iat",
"enterpriseId"
],
"jwks_uri": "https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/jwks",
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"PKCE"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": "RS256",
"scopes_supported": [
"OPENID"
],
"issuer": "https://{IDaaS_server}/",
"authorization_endpoint": "https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/authorize",
"token_endpoint": "https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/token",
"userinfo_endpoint": "https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/user_info"
}
对于各字段的含义请查看OIDC协议中相关文档:https://openid.net/specs/openid-connect-discovery-1_0.html。
提示:Discovery Endpoint 完整地址可在应用详情中获取到(即 Discovery Document URL)。
通过code获取token API¶
通过code获取token API使用在当
Grant Type
为authorization_code
时,这是第二步骤(第一步骤是上面的’SP发起认证’)。
URL定义
POST /public/api/application/plugin_oidc/oidc/token HTTP/1.1
请求参数:
client_id
,对应应用的Client Id值。client_secret
,对应应用的Client Secret值。code
,SP发起认证成功后获取到的code值。grant_type
,应用的Grant Type值,如authorization_code
。redirect_uri
,应用的Redirect URL值。
响应示例
响应的数据包括以下几部分内容:
access_token
id_token
expires_in,
access_token
有效时间,单位:秒,过期了需要通过refresh_token
去刷新。token_type,固定值
Bearer
。refresh_token,刷新token时使用。
此API一般是通过httpclient等工具由第三方应用内部调用IDaaS的API完成,用户使用无感知。
说明:在请求URL中同时未获取到client_id
和client_secret
时,会采用Oauth2
协议的client_secret_basic
方式在请求头中继续获取。刷新token
接口同理适用。
请求示例
实现方式
HTTP Basic authentication scheme.
提供一个http header:Authorization,
其中内容是:Authorization: Basic Base64_Encoder(<client_id> + ":" + <client_secret>)
刷新token API¶
刷新token API与 通过code获取token API是同一个,只是参数有些区别。
URL定义
POST /public/api/application/plugin_oidc/oidc/token HTTP/1.1
请求参数:
client_id
,对应应用的Client Id值。client_secret
,对应应用的Client Secret值。grant_type
,固定值refresh_token
。refresh_token
,认证成功后响应的refresh_token
值。
响应示例
响应的数据包括以下几部分内容:
access_token
id_token
expires_in,
access_token
有效时间,单位:秒,过期了需要通过refresh_token
去刷新。token_type,固定值
Bearer
。refresh_token,刷新token时使用。
此API一般是通过httpclient等工具由第三方应用内部调用IDaaS的API完成,用户使用无感知。
简化模式(implicit)获取token API¶
简化模式(implicit)获取token API 与 SP发起认证API(Authorize URL)是一样的,只是参数有些区别。
URL定义
GET /public/api/application/plugin_oidc/oidc/authorize HTTP/1.1
请求参数:
scope
,一般值为openid
。response_type
,可选id_token,code,id_token token
(Grant Type为implicit时)。client_id
,对应应用的Client Id值。state
,会话状态值,由发起方提供,认证完成后响应一致的值,防篡改。redirect_uri
,应用的Redirect URL值。
请求示例
https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/authorize?response_type=token&scope=openid&client_id=g4lzUvgXgO1KkABsXfJbZyDH&state=xxx&redirect_uri=https://….
响应示例
https://localhost:8082/myoidc-client/implicit#access_token=eyJraWQiOiJteW...&expires_in=7200&state=28dd5xxx
SP发起认证时通过浏览器或webview触发,会跳转到IDaaS登录进行认证,认证通过后跳转会redirect_uri
,通过hash形式传递token值。
Userinfo Endpoint¶
Userinfo Endpoint 用于第三方应用获取更多的用户信息,需要有
access_token
才能访问。
URL定义
GET /public/api/application/plugin_oidc/oidc/user_info HTTP/1.1
请求示例
https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/user_info?access_token={access_token}
响应示例
{
"sub": "admin",
"iss": "http://xxxxxx/public/api/application/plugin_oidc/oidc",
"aud": "xxxxxxx6CPpztCvzN6tjB",
"uuid": "xxxxxxx2baed8e7a77zqtOGeqBXbm",
"username": "admin",
"displayname": "默认管理员",
"email": "xxxxxx@qq.com",
"enterpriseuuid": "xxxxxxxxx2680db8c5vO0sEI4Zo",
"ouid": "xxxxxxxxx2474493775",
"enterprisename": "test",
"ouname": "test"
}
主要响应参数说明:
sub,一般是IDaaS账户名。
email,IDaaS账户邮箱。
ouid,账户所在IDaaS组织机构唯一标识。
externalId,账户在IDaaS平台的外部Id(可用作账户的唯一标识)。
说明:一般通过校验id_token
后可获取用户基本信息(如用户名),需要更多用户信息时才调用此API获取。
GET /public/api/application/plugin_oidc/oidc/user_info/extra HTTP/1.1
请求示例
https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/user_info/extra?access_token={access_token}
响应示例
{
"extendFields": {
"age": "30",
"major": "计算机"
}
}
主要响应参数说明:
extendFields,扩展字典信息
说明:如果需要获取账户的扩展属性(如扩展字典),可通过此接口获得
PKCE使用说明¶
什么是PKCE¶
PKCE是Proof Key for Code Exchange的缩写,PKCE模式属于授权码(authorization_code
)模式的一个扩展,主要适用于无后端服务器来接收和处理Authorization Code授权码的应用。
应用决定加密方式并生成密文,IDP通过校验密文的合法性来判断应用的身份,以此来增强应用端和IDP之间的校验,防止通信劫持。
整体的流程如下图:
更多PKCE信息请访问 https://tools.ietf.org/html/rfc7636。
如何使用PKCE¶
1.在创建OIDC应用时将Grant Type
选择为PKCE
。
2.在SP发起认证API(Authorize URL)时增加PKCE的参数:
code_challenge,加密后的密文
code_challenge_method,加密方式,可选值
S256
或plain
(不加密)
一个请求示例:
https://{IDaaS_server}/public/api/application/plugin_oidc/oidc/authorize?response_type=code&scope=openid&client_id=g4lzUvgXgO1KkABsXfJbZyDH&state=xxx&redirect_uri=https://...&code_challenge=NWI1YTUxMzgxMjkxNTNlOTdhNjQwMjI3NDYzNDg1ZmM5YTNjZjBjYTk4MTdiZmJiYzU5NmM0MzU4Y2Q5Njc1Yw&code_challenge_method=S256
发起请求后,会跳转到IDaaS登录认证成功后响应code。
3.在IDaaS响应返回code
值后,调用获取token的API时要增加PKCE参数:
code_verifier,加密的字符串
请求示例如下图:
密钥轮转¶
密钥轮转作用¶
密钥轮转一般用于定期更新用于加密/解密(或签名/验签)的Key,以防止Key泄漏增强系统安全性。
OIDC中的密钥轮转需要使用到JWT
,JWK
相关知识,可参考相关协议介绍。
如何使用¶
整体的流程图如下所示:
当SP应用获取到
id_token
后,会从header中获取到kid
值。通过
kid
去检查使用的JWK
的kid是否一致(在SP应用中会缓存一份从IDaaS中获取到的JWK)。若一致则使用对应的
JWK
进行校验id_token
。若不一致则通过
kid
值通过jwks_uri
(Discovery Endpoint中提供)去获取新的JWK
值并校验id_token
。
OIDC应用中支持两种方式进行密钥轮转。
方式一:立即轮转。
在应用详情的OIDC PublicKey
处点击’立即轮转密钥’即可。
方式二:定时轮转。
定时轮转需要在添加应用时选择具体的’轮转类型’,如下图:
在选定具体的轮转周期后,在到期时的当天凌晨3点IDaaS平台通过定时任务去更新新的密钥。
说明:轮转开始时间以应用的创建时间来计算。
常见QA¶
第三方客户端(SP)如何校验id_token
?¶
对
id_token
的校验首先要通过jwks_uri
(Discovery Endpoint中响应)获取到 PublicKey,也可以在OIDC应用详情里复制OIDC PublicKey
。访问网站https://jwt.io/libraries找到各种开发语言的library,并根据里面提供的使用文档对
id_token
进行校验。
如何判断轮转密钥成功?¶
轮转密钥后可将新生成的id_token
中的kid
值与之前已有的JWK
中的kid
值进行对比,不一致则说明轮转成功。
也可通过访问网站https://jwt.io复制id_token
到 Encoded 框中查看header内容进行查看,如下图:
提示:轮转成功后不能再使用旧的
JWK
校验id_token
,会校验失败。