简体   繁体   English

BackChannelLogoutUri与多租户方案

[英]BackChannelLogoutUri with multi-tenant scenario

I am currently working with Identity server 4, where i am trying to enable BackChannelLogoutUri . 我当前正在使用身份服务器4,在其中尝试启用BackChannelLogoutUri

Each client has been given a BackChannelLogoutUri in the config of the client 在客户端的配置中为每个客户端提供了BackChannelLogoutUri

BackChannelLogoutUri = "http://localhost:44322/home/LogoutBackChannel",

Each client application has registered the cookieEventHandler and LogoutSessionManager. 每个客户端应用程序都注册了cookieEventHandler和LogoutSessionManager。

services.AddTransient<CookieEventHandler>();
        services.AddSingleton<LogoutSessionManager>();

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = "oidc";
        })
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
                options.Cookie.Name = "mvchybridbc";

                options.EventsType = typeof(CookieEventHandler);
            })

My logout view on the identity server contains the Iframe 我在身份服务器上的注销视图包含Iframe

@if (Model.PostLogoutRedirectUri != null)
{
    <div>
        Click <a class="PostLogoutRedirectUri" href="@Model.PostLogoutRedirectUri">here</a> to return to the
        <span>@Model.ClientName</span> application.
    </div>
}
@if (Model.SignOutIframeUrl != null)
{
    <iframe width="0" height="0" class="signout" src="@Model.SignOutIframeUrl"></iframe>
}

This is all well and good. 这一切都很好。 But my problem is that the BackChannelLogoutUri is a single url. 但是我的问题是BackChannelLogoutUri是单个URL。 When hosted it will need to be passed some how from each tennent 托管后,需要从每个租户传递一些方式

We cant really have a client for each tenant and app. 我们真的不能为每个租户和应用都有一个客户。 That would be a lot of clients. 那将有很多客户。 That and clients that are only users of tenant one would not need to be logged out of tenant two. 那和只作为第一租户用户的客户端将不需要从第二租户中注销。

I am not sure how to address this issue. 我不确定如何解决此问题。

I've implemented the backchannel logout without having to rely on iframes. 我已经实现了反向通道注销,而不必依赖iframe。 What it basically does is, collect the necessary urls and then send the notifications. 它的基本作用是,收集必要的URL,然后发送通知。

I don't have tenants, so this will work for me. 我没有房客,所以这对我有用。 But you can adapt the code and add the logic for tenants, as commented in the code: 但是您可以修改代码并为租户添加逻辑,如代码中所述:

// Injected services:

//private readonly IUserSession _userSession;
//private readonly IClientStore _clientStore;
//private readonly IBackChannelLogoutService _backChannelClient;

private async Task LogoutUserAsync(string logoutId)
{
    if (User?.Identity.IsAuthenticated == true)
    {
        // delete local authentication cookie
        await HttpContext.SignOutAsync();

        // Get all clients from the user's session
        var clientIds = await _userSession.GetClientListAsync();
        if (clientIds.Any())
        {
            var backChannelClients = new List<BackChannelLogoutModel>();
            var sessionId = await _userSession.GetSessionIdAsync();
            var sub = User.Identity.GetSubjectId();

            foreach (var clientId in clientIds)
            {
                var client = await _clientStore.FindEnabledClientByIdAsync(clientId);
                // This should be valid in any case:
                if (client == null && !string.IsNullOrEmpty(client.BackChannelLogoutUri))
                    continue;

                // Insert here the logic to retrieve the tenant url for this client
                // and replace the uri:
                var tenantLogoutUri = client.BackChannelLogoutUri;

                backChannelClients.Add(new BackChannelLogoutModel
                {
                    ClientId = client.ClientId,
                    LogoutUri = tenantLogoutUri,
                    SubjectId = sub,
                    SessionId = sessionId,
                    SessionIdRequired = true
                });
            }

            try
            {
                await _backChannelClient.SendLogoutNotificationsAsync(backChannelClients);
            }
            catch (Exception ex)
            {
                // Log message
            }
        }

        // raise the logout event
        await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM