协议概述
OIDC(OpenID Connect)是一个基于OAuth 2.0协议的身份认证标准协议,增加了 Id Token。
名词解释
- OpenID Provider(OP): OIDC 授权服务器,负责签发 ID Token。
- End-User(EU):用户,ID Token 的信息中会包含终端用户的信息。
- ID Token 由 OpenID Provider 颁发,包含关于终端用户的信息字段。
- UserInfo Endpoint:用户信息接口,通过 ID Token 访问时返回用户信息。
- Claims 指终端用户信息字段。
登录流程
- 用户尝试登录应用系统。
- 应用系统发送认证请求到OIDC 授权服务器。
- OIDC 授权服务器对用户进行认证与授权。
- OIDC 授权服务器返回认证信息,包含 ID Token、Access Token和Refresh Token。
- 应用系统获取认证信息后,再携带Access Token 发送请求到 UserInfo Endpoint。
- UserInfo Endpoint 返回 End-User 的 Claims。
- 应用系统验证End-User信息是否有效,有效则登录成功,反之失败。
开发详情
开发详情以授权码模式为例。
应用系统可以通过此接口获取 OIDC 授权服务器的基本配置信息。
HTTP Method:GET
https://demo.cloudentify.com/api/oauth/oidc/{appkey}/.well-known/openid-configuration
返回示例:
{
"issuer" : "https://test.cloudentify.com",
"authorization_endpoint" : "https://test.cloudentify.com/api/oauth/authorize",
"token_endpoint" : "https://test.cloudentify.com/api/oauth/token",
"token_endpoint_auth_methods_supported" : [ "client_secret_basic"],
"jwks_uri" : "https://test.cloudentify.com/api/oauth/oidc/{appkey}/.well-known/jwks.json",
"response_types_supported" : [ "code" ],
"grant_types_supported" : [ "authorization_code", "refresh_token" ],
"subject_types_supported" : [ "public" ],
"id_token_signing_alg_values_supported" : [ "RS256" ],
"scopes_supported" : [ "openid","username","email","phone","address","profile","offline_access"]
}
步骤1:
- 获取用户授权,如果用户未登录系统,则要求用户进行身份认证(跳转至授权服务器进行认证),应用发起重定向至授权服务器的以下地址。接口支持 PKCE 模式,如需进行 PKCE 模式的校验,可传入相应的参数。
HTTP Method:GET
https://demo.cloudentify.com/api/oauth/authorize
请求参数:
- client_id:必填,客户端 ID,从管理平台-应用管理-企业应用列表的App ID处获取;
- response_type:必填,固定值“code”;
- redirect_uri:必填,授权成功后的重定向地址;
- state:非必填,应用系统提供的一个随机字符串,服务器会原样重定向给应用系统,防止 CSRF、XSRF;
- scope:必填,参数值应以 openid 开头;
- code_challenge_method:非必填,PKCE 模式的必要参数,即 code_challenge 值的计算方法,目前仅支持 SHA256;
- code_challenge:非必填,PKCE 模式的必要参数,计算方式:code_challenge = code_challenge_method(code_verifier)。code_verifier 为校验码原文,应用系统需要自行保存code_verifier,并在获取授权令牌的请求中带上,用作验证,code_challenge_method使用SHA256。
请求示例:
https://demo.cloudentify.com/api/oauth/authorize?client_id=EFTDBB&response_type=code&redirect_uri=http%3A%2F%2Fwww.test.com&scope=openid%20phone%20profile%20offline_access%20email&code_challenge_method=S256&code_challenge=FWOeBX6Qw_krhUE2M0lOIH3jcxaZzfs5J4jtai5hOX4&state=123456
- 授权服务器进行认证后,将通过redirect_uri传入的重定向地址,向应用下发授权码。
HTTP Method:GET
http://www.test.com?code=b9eb0dc233&state=123456
步骤2:
- 应用获取到授权码后,使用授权码换取访问令牌。
HTTP Method:POST
https://demo.cloudentify.com/api/oauth/token
请求参数:
- Authorization:必填,存放Header中, 接口鉴权值,Basic base64encode(client_id:client_secret);
- grant_type:必填,固定值“authorization_code”;
- redirect_uri:必填,授权成功后的重定向地址。如果“oauth/authorize”请求带有 redirect_uri 参数,则本步骤请求必须上送 redirect_uri 参数;
- code:必填,授权码;
- scope:必填,参数值应以 openid 开头;
- code_verifier:非必填,PKCE 模式必要参数,code_verifier 校验码原文。
请求示例:
Authorization: 'Basic MTIzNDU2OjEyMzQ1Ng=='
https://demo.cloudentify.com/api/oauth/token?grant_type=authorization_code&redirect_
uri=http%3A%2F%2Fwww.baidu.com&code=123456&code_verifier=2D9RWc5iTdtejle7GTMzQ9Mg15InNmqk3GZL-Hg5Iz0&scope=openid
返回参数:
- access_token:access_token令牌;
- expires_in:access_token有效时间;
- token_type:固定值“bearer”;
- refresh_token:刷新令牌;
- id_token:id_token。
返回示例:
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"id_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdGV2ZW4iLCJBQ0NPVU5UIjoic3RldmVuIiwi
aXNzIjoiaHR0cDpcL1wvd3d3LmJhaWR1LmNvbSIsImV4cCI6MTY1MDA5NTIzOX0.r7NCR3LF3ZoyhlX9UMERt6H_-DFCo6gcuTwsoTmI33U"
}
步骤3:
- 访问令牌过期后,可使用刷新令牌置换新的访问令牌。
HTTP Method:POST
https://demo.cloudentify.com/api/oauth/token
请求参数:
- Authorization:必填,存放Header中, 接口鉴权值,Basic base64encode(client_id:client_secret);
- grant_type:必填,固定值“refresh_token”;
- refresh_token:必填,refresh_token;
- scope:必填,参数值应以 openid 开头。
请求示例:
Authorization: 'Basic MTIzNDU2OjEyMzQ1Ng=='
https://demo.cloudentify.com/api/oauth/token?grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&scope=openid
返回参数:
- access_token:access_token令牌;
- expires_in:access_token有效时间;
- token_type:固定值“bearer”;
- refresh_token:刷新令牌;
- id_token:id_token。
返回示例:
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "id_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdGV2ZW4iLCJBQ0NPVU5UIjoic3RldmVuIiwiaXNzIjoiaHR0cDpcL1wvd3d3LmJhaWR1LmNvbSIsImV4cCI6MTY1MDA5NTIzOX0.r7NCR3LF3ZoyhlX9UMERt6H_-DFCo6gcuTwsoTmI33U"
}
- 如果后台id_token 签名算法设置为RS256,可通过该接口获取算法信息和JWT 公钥对ID Token进行验证。
HTTP Method:GET
https://demo.cloudentify.com/api/oauth/oidc/{appkey}/.well-known/jwks.json
返回示例:
{
"keys": [
{
"kid": "d98f49bc6ca4581eae8dfadd494fce10ea23aab0",
"use": "sig",
"kty": "RSA",
"alg": "RS256",
"e": "AQAB",
"n":"tCwhHOxX_ylh5kVwfVqW7QIBTIsPjkjCjVCppDrynuF_3msEdtEaG64eJUz84ODFNMCC0BQ57G7wrKQVWkdSDxWUEqGk2BixBiHJRWZdof
z1WOBTdPVicvHW5Zl_aIt7uXWMdOp_SODw-O2y2f05EqbFWFnR2-1y9K8KbiOp82CD72ny1Jbb_3PxTs2Z0F4ECAtTzpDteaJtjeeueRjr7040J
AjQ-5fpL5D1g8x14LJyVIo-FL_y94NPFbMp7UCi69CIfVHXFO8WYFz949og-47mWRrID5lS4zpx-QLuvNhUb_lSqmylUdQB3HpRdOcYdj3xwy4M
HJuu7tTaf0AmCQ"
}
]
}
步骤4:
- 应用可通过访问令牌获取用户信息。
HTTP Method:POST
https://demo.cloudentify.com/api/oauth/oidc/me?access_token=f148b9b4-2f02-42dd-8a59-4ca92a12c48b
返回示例:
{
"sub": "steven",
"name": "steven",
"preferred_username": "steven",
"given_name": "",
"family_name": "",
"middle_name": "",
"nickname": "steven",
"profile": "profile",
"picture": "picture",
"website": "",
"gender": "U",
"zoneinfo": "",
"locale": "",
"birthdate": "",
"email": "",
"email_verified": false,
"phone_number": "",
"phone_number_verified": false,
"address": {
"country": "",
"region": "",
"locality": "",
"street_address": "",
"formatted": "",
"postal_code": ""
},
"authorization": {
"roleList": [
{
"roleCode": "OrderAdmin",
"descp": "订单管理员"
},
…
],
"ruleList": [
{
"accessmode": 0,
"accessmodeStr": "允许",
"resourceName": "订单管理",
"resourceCode": "1000",
"parentResourceCode": ""
},
…
]
}
}
登录态注销(退出登录):
- 业务系统主动调用飞天云信注销Access Token。
HTTP Method:POST
https://demo.cloudentify.com/api/oauth/oidc/endsession
Header Content-Type:application/x-www-form-urlencoded
FORM表单提交,请求参数:
id_token_hint:必填,填入id_token;
- 业务系统被动等待飞天云信调用注销用户登录状态。
业务系统提供登出回调URL,接口描述如下:
HTTP Method:POST
Header Content-Type:application/x-www-form-urlencoded
接口参数:
- id:UUID;
- principal:登录业务系统的用户名;
- request:固定值“logoutRequest”;
- issueInstant:请求时间,格式为yyyy-MM-dd’T’HH:mm:ss.SSS’Z;
- online_ticket:id_token。