Multitenant Identity Server 4
Asked Answered
W

1

16

I'm trying to implement an IdentityServer that handles an SSO for a multitenant application. Our system will have only one IdentityServer4 instance to handle the authentication of a multitentant client.

On the client side, I'm using the acr_value to pass the tenant Id. A piece of code from the Startup.cs file is as follows:

public void ConfigureServices(IServiceCollection services)
{
        services.AddMvc();
        services.AddAuthorization();

        services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";
                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;
                options.ClientId = "Client1";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;                    
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("offline_access");
                options.Events.OnRedirectToIdentityProvider = n =>
                {
                    if (n.ProtocolMessage.RequestType == 
                          OpenIdConnectRequestType.Authentication)
                    {
                        n.ProtocolMessage.AcrValues = "tenant:clientId1";
                    }
                    return Task.FromResult(0);
                };
            });
}

For the identity server the IdentityServer4 with ASP.NET Core Identity is used. To handle multitenant client authentication I followed the instructions given by Scott Brady for ASP.NET Identity in this post: https://www.scottbrady91.com/ASPNET-Identity/Quick-and-Easy-ASPNET-Identity-Multitenancy

I modified the UserStore to receive the tenant Id but the moment of the UserStore instance is injected for the AccountController I can't retrieve the passed acr_value.

Has any one faced this problem before?

Wintertime answered 22/1, 2018 at 15:0 Comment(7)
Perhaps this article can help you: leastprivilege.com/2017/11/15/…Wallraff
Thanks for the advice. This article is to pass the claim acr from the endpoint to a client. I'm doing the inverse, passing the acr to the Server endpoint and verifying that user exists for this acr tenant valueWintertime
Just wandering if you've made any progress on this. Are you trying to have different .well-known/openid-configuration per each tenant or just one? Also why do you need the tenantId in the UserStore, you can just create a custom ApplicationSignInManager that overrides CanSignInAsync(ApplicationUser user) and pass it in the AccountController Login like this: var context = await _interaction.GetAuthorizationContextAsync(returnUrl); _signInManager.ClientId = context?.Tenant; However, how do you manage with this approach to sign out of one tenant and not the others?Sizing
@Sizing exactly I'm guessing the issue will occur even when the user logs into other tenant and try to login to restricted tenant, because idsrv sso looks at the cookie and bypass the authentication. So the signout will also have an impact. I believe with this approach we need to create a tenant based cookie so that they are isolated at tenant level.Fermat
cool @Jay! Any sample on how you’d create the tenant based cookie in aspnetcore 2?Sizing
@Ovi, thats just a theory I have at the moment, in the process to implement.. how did you go with your approach? any results to share?Fermat
@Jay, yes see my PR on Saaskit: github.com/saaskit/saaskit/pull/96Sizing
F
13

if you haven't figure out yet, here is the solution

private readonly IIdentityServerInteractionService _interaction;


 var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
            var tenant = context.Tenant;
Fermat answered 5/4, 2018 at 6:40 Comment(4)
I've got no idea where to put that code. It is just code without any context.Elodiaelodie
@Elodiaelodie thats because you have not looked at the basic code needed to make an IS4 server. IIdentityServerInteractionService is typically used in a controller... github.com/IdentityServer/IdentityServer4/blob/main/src/…Kirman
@Elodiaelodie the code can be used in any of the services, where you want to know the incoming request tenant Id. You can also use the HttpContext service to extract the request URLFermat
...well, on login page context.tenant is null... (using IdentityServer 6.1.5) To use the Identity Server in real multitenancy we need to know the tenant in every request, for example to brand the login page itself...Tarrance

© 2022 - 2024 — McMap. All rights reserved.