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?
.well-known/openid-configuration
per each tenant or just one? Also why do you need thetenantId
in theUserStore
, you can just create a customApplicationSignInManager
that overridesCanSignInAsync(ApplicationUser user)
and pass it in theAccountController
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