介绍
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 [[RFC6749]]( https://openid.net/specs/openid-connect-session-1_0.html#RFC6749) protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
OIDC协议在OAuth2的基础上,增加了一个简单的身份验证,从而支持多种场景下身份单点登录(Single Sign On
,SSO)认证。在真实业务场景中,除了SSO外,还是需要支持单点登录(Single Logout,SLO)。当前OIDC协议设计了4种关于会话管理和SLO的协议标准,分别适用于不同场景,下文将对这4种标准方案做个对应的简单介绍。
术语
名词 | 解释 |
---|---|
OIDC | OpenID Connect |
RP | Relying Party,依赖方,也就是依赖身份提供方的应用服务。 |
OP | OpenID Provider,openid提供方,也就是身份提供方。 |
Session | 会话。在此期间,终端用户根据OpenID提供方执行的终端用户身份验证访问依赖方。 |
OIDC协议的4中会话管理机制
OIDC Session Management 1.0
How to monitor the End-User's login status at the OpenID Provider on an ongoing basis so that the Relying Party can log out an End-User who has logged out of the OpenID Provider.
协议地址:OIDC Session Management 1.0
解决问题:让RP持续监控终端用户在OP中的登录状态,以便RP可以注销在OP已经退出的终端用户会话状态。
直接解决思路:
- RP持续访问OP的某个接口,纯后端交互;在混合流或者其它场景下,RP和OP网络不互通。
- RP持续发起重复的认证请求(指定参数prompt=none);可能导致网络流量风暴;
协议实现机制:
RP和OP各自提供一个iframe,RP以用户不可见的方式把两个iframe都加载到页面中,其中RP iframe不断的post message请求OP iframe,OP iframe根据请求参数中的session_state和当前User Agent中的状态来计算得出当前终端用户的登录会话状态。
OIDC RP-initiated Logout 1.0
Enabling the Relying Party to request that an End-User be logged out by the OpenID Provider.
协议地址:OpenID Connect RP-Initiated Logout 1.0
解决问题:让RP主动发起请求退出终端用户在OP的会话。
新增Endpoint:Logout Endpoint,在OpenID Configuration中称为:end_session_endpoint。
Logout Endpoint Parameter Definition:
参数 | 级别 | 描述 |
---|---|---|
id_token_hint | RECOMMENDED | 终端用户在SSO时,OP签发给RP的id_token,这个参数可以让OP来识别当前RP请求退出的终端会话信息。 |
logout_hint | OPTIONAL | 参数含义由OP自定义实现,如参数取值可以是username、email、phone number,类似于SSO时的login_hint参数,指定终端用户登录和退出。 |
client_id | OPTIONAL | OAuth2 Client标识。当client_id和id_token_hint参数同时存在时,OP必须验证id_token是否由该client identifier签发。通用使用Case是当id_token_hint参数不存在的时候,配合post_logout_redierct_uri参数确定Client身份。 |
post_logout_redirect_uri | OPTIONAL | 当OP退出终端用户后,重定向到RP的地址,应该是https格式,并且对应的uri需要在OP提前注册,如果OP匹配不通过,不允许退出终端用户登录后重定向到改地址。 |
state | OPTIONAL | 类似于Login中的State,如果存在必须在重定向到post_logout_redirect_uri时返回。 |
ui_locales | OPTIONAL | 终端用户的偏好语言等个性化内容支持。 |
请求如下所示:
GET https://example.aliyunidaas.com/<instance_id>/<application_id>/logout
?id_token_hint=${id_token}
&post_logout_redirect_uri=${post_logout_redirect_uri}
&state=${state}
OIDC Back-Channel logout 1.0
A logout mechanism that uses direct back-channel communication between the OP and RPs being logged out.
协议地址:OIDC Back-Channel logout
解决问题:OP主动通知RP退出登录会话。
要求:OP可以直接访问到RP,并且必须实现一个指定应用的方法来终结RP上的终端用户会话。
OpenID Configuration新增:
- back_channel_logout_supported:true or false,OP是否支持后端退出会话机制
- back_channel_logout_session_supported:true or false,OP是否支持指定sid在Logout Token中。
- backchannel_logout_uri:RP支持后端退出时的被访问url
- backchannel_logout_session_required:RP是否要求OP必须传递sid
Logout Token:
claim | 级别 | 描述 |
---|---|---|
iss | REQUIRED | Issuer Identifier |
sub | OPTIONAL | Subject Identifier |
aud | REQUIRED | Audience |
iat | REQUIRED | Issued at time |
jti | REQUIRED | Unique identifier for the token |
events | REQUIRED | 包含成员:http://schemas.openid.net/event/backchannel-logout的JSON 字符串。 |
sid | OPTIONAL | Session ID |
Logout Token Example:
{
"iss": "https://server.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"iat": 1471566154,
"jti": "bWJq",
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
"events": {
"http://schemas.openid.net/event/backchannel-logout": {}
}
}
Logout Request Example:
POST /backchannel_logout HTTP/1.1
Host: rp.example.org
Content-Type: application/x-www-form-urlencoded
logout_token=eyJhbGci ... .eyJpc3Mi ... .T3BlbklE ...
OIDC Front-Channel Logout 1.0
A logout mechanism that uses front-channel communication via the User Agent between the OP and RPs being logged out that does not need an OpenID Provider iframe on Relying Party pages.
协议地址:OIDC Front-Channel Logout
解决问题:OP主动通知RP退出登录会话,但是通过User Agent来实现这个退出,所以不要求OP和RP可以直接通信。
OpenID Configuration新增:
- frontchannel_logout_uri:RP提供
- frontchannel_logout_session_required:RP是否强制要求Logout提供issuer和sid信息
- frontchannel_logout_supported:OP显示是否支持前端退出
- frontchannel_logout_session_supported:OP是否支持提供会话信息issuer和sid
实现机制:
通过iframe方式来加载对应RP的logout uri
注意事项:
- 一些浏览器可能会禁止加载第三方内容;
- 用户可能会关闭浏览器,导致logout请求中断;
总结
方法 | 问题 | 实现方式 |
---|---|---|
Session Management | 让RP持续监控终端用户在OP中的登录状态,以便RP可以注销在OP已经退出的终端用户会话状态。 | 通过RP嵌入OP iframe来实现。OP的终端用户会话状态由自己的iframe实现。 |
RP-initiated Logout | 让RP主动发起请求退出终端用户在OP的会话。 | RP发起请求到logout endpoint,主动退出OP中的终端用户会话。 |
Back-Channel Logout | OP主动通知RP退出登录会话。 | OP直接后台访问RP logout地址,提供Logout Token参数实现后端退出。 |
Front-Channel Logout | OP主动通知RP退出登录会话。 | OP前端通过iframe方式加载RP logout uri,实现前端退出。 |
IDaaS EIAM当前实现
IDaaS EIAM 当前支持RP-Initiated Logout,支持自研应用主动发起访问Logout Endpoint退出IDaaS EIAM登录回话,具体对接流程和接口调用示意如下:
Logout Endpoint:/login/app/app_mmvgv7hzfej3slqed3tmmfhixa/oauth2/logout
Get https://<your idaas domain>/login/app/app_mmvgv7hzfej3slqed3tmmfhixa/oauth2/logout?
id_token_hint=<id_token>&post_logout_redirect_uri=<post_logout_reidrect_uri>&state=<>
参数名称 | 可选 | 描述 |
---|---|---|
id_token_hint | Optional | 终端用户SSO登录到应用时,返回的id_token。如果id_token有效,EIAM登录会话会直接退出。否则会重定向到登出确认页面,由用户主动选择退出。 |
post_logout_redirect_uri | Optional | Logout重定向到应用的目标地址,如果指定,必须在应用管理侧添加对应的目标地址白名单。 |
state | Optional | 重定向到应用的Logout回调地址时,如果指定会原样传递回去。 |
post_logout_redirect_uri配置页面:
登出流程:
参考文档
- OpenID Connect Session Management 1.0:https://openid.net/specs/openid-connect-session-1_0.html
- OpenID Connect RP-Initiated Logout 1.0 :https://openid.net/specs/openid-connect-rpinitiated-1_0.html
- OpenID Connect Back-Channel Logout 1.0 :https://openid.net/specs/openid-connect-backchannel-1_0.html
- OpenID Connect Front-Channel Logout 1.0 :https://openid.net/specs/openid-connect-frontchannel-1_0.html