使用 AD FS 的 OpenID Connect 单个注销

概述

AD FS 2016 基于 Windows Server 2012 R2 中 AD FS 对 Oauth 的初始支持,引入了对 OpenId Connect 登录的支持。 借助 KB4038801,AD FS 2016 现在支持 OpenId Connect 单一注销方案。 本文概述了 OpenId Connect 单一注销方案,并提供有关如何在 AD FS 中将其用于 OpenId Connect 应用程序的指南。

发现文档

OpenID Connect 使用名为“发现文档”的 JSON 文档来提供有关配置的详细信息。 这包括身份验证、令牌、用户信息和公共终结点的 URI。 下面是发现文档的示例。

{
"issuer":"https://fs.fabidentity.com/adfs",
"authorization_endpoint":"https://fs.fabidentity.com/adfs/oauth2/authorize/",
"token_endpoint":"https://fs.fabidentity.com/adfs/oauth2/token/",
"jwks_uri":"https://fs.fabidentity.com/adfs/discovery/keys",
"token_endpoint_auth_methods_supported":["client_secret_post","client_secret_basic","private_key_jwt","windows_client_authentication"],
"response_types_supported":["code","id_token","code id_token","id_token token","code token","code id_token token"],
"response_modes_supported":["query","fragment","form_post"],
"grant_types_supported":["authorization_code","refresh_token","client_credentials","urn:ietf:params:oauth:grant-type:jwt-bearer","implicit","password","srv_challenge"],
"subject_types_supported":["pairwise"],
"scopes_supported":["allatclaims","email","user_impersonation","logon_cert","aza","profile","vpn_cert","winhello_cert","openid"],
"id_token_signing_alg_values_supported":["RS256"],
"token_endpoint_auth_signing_alg_values_supported":["RS256"],
"access_token_issuer":"http://fs.fabidentity.com/adfs/services/trust",
"claims_supported":["aud","iss","iat","exp","auth_time","nonce","at_hash","c_hash","sub","upn","unique_name","pwd_url","pwd_exp","sid"],
"microsoft_multi_refresh_token":true,
"userinfo_endpoint":"https://fs.fabidentity.com/adfs/userinfo",
"capabilities":[],
"end_session_endpoint":"https://fs.fabidentity.com/adfs/oauth2/logout",
"as_access_token_token_binding_supported":true,
"as_refresh_token_token_binding_supported":true,
"resource_access_token_token_binding_supported":true,
"op_id_token_token_binding_supported":true,
"rp_id_token_token_binding_supported":true,
"frontchannel_logout_supported":true,
"frontchannel_logout_session_supported":true
}

以下附加值将在发现文档中提供,以指示对 Front Channel 注销的支持:

  • frontchannel_logout_supported:值为“true”
  • frontchannel_logout_session_supported:值为“true”。
  • end_session_endpoint:这是客户端可用于在服务器上启动注销的 OAuth 注销 URI。

AD FS 服务器配置

默认情况下,将启用 AD FS 属性 EnableOAuthLogout。 此属性告知 AD FS 服务器浏览具有 SID 的 URL (LogoutURI),以在客户端上启动注销。 如果未安装 KB4038801,则可以使用以下 PowerShell 命令:

Set-ADFSProperties -EnableOAuthLogout $true

注意

安装 KB4038801 后,EnableOAuthLogout 参数标记为已过时。 EnableOAUthLogout 始终为 true,并且不会影响注销功能。

注意

仅在安装 KB4038801 后才支持 frontchannel_logout

客户端配置

客户端需要实现“注销”已登录用户的 URL。 管理员可以使用以下 PowerShell cmdlet 在客户端配置中配置 LogoutUri。

  • (Add | Set)-AdfsNativeApplication
  • (Add | Set)-AdfsServerApplication
  • (Add | Set)-AdfsClient
Set-AdfsClient -LogoutUri <url>

LogoutUri 是 AF FS 用于“注销”用户的 URL。 若要实现 LogoutUri,客户端需要确保清除应用程序中用户的身份验证状态,例如删除其拥有的身份验证令牌。 AD FS 将浏览到该 URL,并将 SID 作为查询参数,从而向信赖方/应用程序发出注销用户的信号。

AD FS log off user diagram

  1. 具有会话 ID 的 OAuth 令牌:AD FS 在颁发 id_token 令牌时在 OAuth 令牌中包含会话 ID。 稍后,AD FS 将使用它来标识要为用户清理的相关 SSO Cookie。
  2. 用户在 App1 上启动注销:用户可以从任何已登录的应用程序启动注销。 在此示例方案中,用户从 App1 启动注销。
  3. 应用程序将注销请求发送到 AD FS:用户启动注销后,应用程序向 AD FS 的 end_session_endpoint 发送 GET 请求。 应用程序可以选择性地包含 id_token_hint 作为此请求的参数。 如果存在 id_token_hint,AD FS 会将其与会话 ID 结合使用,以确定在注销后客户端应重定向到哪个 URI (post_logout_redirect_uri)。 post_logout_redirect_uri 应是使用 RedirectUris 参数向 AD FS 注册的有效 URI。
  4. AD FS 向登录的客户端发送注销:AD FS 使用会话标识符值查找用户登录的相关客户端。 标识的客户端在注册到 AD FS 的 LogoutUri 上发送请求,以在客户端启动注销。

常见问题

问:我在发现文档中看不到 frontchannel_logout_supported 和 frontchannel_logout_session_supported 参数。
答:请确保已在所有 AD FS 服务器上安装 KB4038801。 请参阅带有 KB4038801 的 Server 2016 中的单一注销。

问:我已按照指示配置了单一注销,但用户在其他客户端上仍保持登录状态。
答:确保为用户登录的所有客户端设置 LogoutUri。 此外,AD FS 会在最佳情形时尝试在已注册的 LogoutUri 上发送注销请求。 客户端必须实现处理请求的逻辑,并采取措施从应用程序注销用户。

问:如果在注销后,其中一个客户端使用有效的刷新令牌返回到 AD FS,AD FS 是否会颁发访问令牌?
答:会。 在注册的 LogoutUri 处收到注销请求后,客户端应用程序负责删除所有经过身份验证的项目。

后续步骤

AD FS 开发