layout: docs-default
Federated 的登出后重定向
当客户端程序登出IdentityServer的时候,一个"post-logout redirect uri"会被发送给用户,以便在完全退出后重定向回客户端。这个信息维护在"sign out message"cookie里,通过唯一的"sign out message id"来标识。这个标识通过查询字符串来传给”logged out"页面,这样可以访问这个cookie来重定向用户回客户端应用。
如果IdentityServer使用一个上游的身份认证,当用户从IdentityServer 登出的时候,也会重定向到第三方认证来退出。如果第三方认证提供 "post logout redirect uri" 功能, 那么一旦用户被重定向回IdentityServer,这个"sign in message id" 会丢掉.
IdentityServer支持在重定向到第三方认证前获取和保存 "sign out message id"。一旦用户被重定向回IdentityServer,可以使用这个"sign out message id" 来显示IdentityServer的登出界面,这个界面有一个链接可以退回到用户程序。
这种方式需要托管程序在重定向前拿到"sign out message id"。通过调用 IdentityServer OWIN environment extensions的 GetSignOutMessageId
方法。我们的逻辑代码需要保存这个标识(比如到cookie)
这个同样需要在托管程序中定义个 "post logout redirect" endpoint (这个endpoint需要在尚有的认证服务注册). 当第三方认证登出时,这个endpoint像一个回调函数一样。当这个回调被调用的时候,可以显示一个IdentityServer的“logged out page"(通过调用IdentityServer OWIN environment extensions的RenderLoggedOutViewAsync
).这个"sign in message id" 会做为参数传过来。
详情可以参考下面的代码:
public void Configuration(this IAppBuilder app)
{
app.Map("/core", coreApp =>
{
var factory = new IdentityServerServiceFactory();
// ...
coreApp.UseIdentityServer(idsrvOptions);
coreApp.Map("/signoutcallback", cleanup =>
{
cleanup.Run(async ctx =>
{
var state = ctx.Request.Cookies["state"];
await ctx.Environment.RenderLoggedOutViewAsync(state);
});
});
});
}
public static void ConfigureIdentityProviders(IAppBuilder app, string signInAsType)
{
var oidc = new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
Caption = "External IdP",
SignInAsAuthenticationType = signInAsType,
// ...
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.LogoutRequest)
{
// ...
var signOutMessageId = n.OwinContext.Environment.GetSignOutMessageId();
if (signOutMessageId != null)
{
n.OwinContext.Response.Cookies.Append("state", signOutMessageId);
}
}
return Task.FromResult(0);
}
}
};
app.UseOpenIdConnectAuthentication(oidc);
}
网友评论