简体   繁体   中英

How to switch Azure AD directory programatically via C# in a multi tenant app

I have ASP.NET MVC app which is configured with a Multi-tenant Azure AD app. So in my Web.config I had to put <add key="ida:Authority" value="https://login.microsoftonline.com/common/" /> so this will work for any one. But now some of my apps users are assigned to different Azure Directories (where Tenant IDs differ). I need to provided a "Switch Directory" functionality like in Azure Portal / Aure IoT Central.

I know if I replace common with the Tenant ID, the app will only work for the particular Tenant.

In the public void ConfigureAuth(IAppBuilder app) of Startup.Auth.cs I have something like below

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions { });
    app.UseCookieAuthentication(new CookieAuthenticationOptions ());

    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            ClientSecret = clientSecret,
            Authority = authority,
            PostLogoutRedirectUri = postLogoutRedirectUri,
            RedirectUri = redirectUri,

            TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
            {
                ValidateIssuer = false,
            },
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = (context) =>
                {
                    string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                    // The above tenantID is always coming from the default directory
                    string issuer = context.AuthenticationTicket.Identity.FindFirst("iss").Value;
                    // The above is also always from the default directory (tenant id)
                    string UPN = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;


                    return Task.FromResult(0);
                },
                AuthorizationCodeReceived = (context) =>
                {
                    var code = context.Code;
                    HttpContext.Current.Session["CODE"] = code;
                    return Task.FromResult(0);
                },
                AuthenticationFailed = context =>
                {
                    return Task.FromResult(0);
                }
            }
        });
}

So this gives a OWIN context to me which has the details only for the default directory ID. Can anyone help me to change this behavior? so that I can provide a feature to switch between directories.

A hack I made once (with OWIN) was to add a specific query parameter when requesting login that specified a tenant id.

I can't find the source code right now, but an OWIN middleware did the following:

  • Call next middleware
  • Is the response a GET, the response statuscode a 302, location header value has the Azure AD host, and the tenant id query parameter is present?
  • If yes, grab the Location header, switch the value to "https://login.microsoftonline.com/tenant-id/oauth2/authorize?" + locationHeader query string "https://login.microsoftonline.com/tenant-id/oauth2/authorize?" + locationHeader query string

It's a kind of hack, but works to help a user log in to the right tenant.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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