Мультитенант в OpenIDConnect .Net Framework - PullRequest
0 голосов
/ 18 января 2019

Я пытался реализовать Multitenant Authentication (которую я изучаю), и до сих пор мне удалось реализовать аутентификацию моего приложения в режиме Single tenant.

Код, который я использовал для одного арендатора:

 public void ConfigureAuth(IAppBuilder app)
        {

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
                 new OpenIdConnectAuthenticationOptions
                 {
                     ClientId = ConfigurationManager.AppSettings["AuthclientId"],
                     Authority = "https://login.microsoftonline.com/abc.onmicrosoft.com/",



                 });
        }

Здесь; сначала я регистрирую свое приложение в ABC AAD и получаю идентификатор клиента, затем помещаю его в мою конфигурацию. Все отлично работает.

Но теперь я должен реализовать это с мультитенантным типом. Несмотря на то, что это мультитенант, я должен разрешить только 2 арендатора. Допустим, abc.onmicrosoft.com и contoso.onmicrosoft.com

До сих пор я делал все возможное, чтобы зарегистрировать свое приложение в ABC tenant и Contoso tenant, а затем получил 2 идентификатора клиента. Но моя проблема заключается в том, что невозможно указать 2 идентификатора клиента в UseOpenIdConnectAuthentication (см. Мой обновленный код ниже)

public void ConfigureAuth(IAppBuilder app)
        {

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
                 new OpenIdConnectAuthenticationOptions
                 {

                     ClientId = ??,
                     Authority = "https://login.microsoftonline.com/common/",
                     TokenValidationParameters = new TokenValidationParameters
                     {
                         ValidateIssuer = false
                     },

                 });
        }

P.S. Это ново для меня. Я могу ошибаться, пожалуйста, поправьте меня, чтобы все было на правильном пути

Обновление 1:

app.UseOpenIdConnectAuthentication(
             new OpenIdConnectAuthenticationOptions
             {

                 //ClientId = authClientID1,//App ID registered with 1st Tenant
                 Authority = "https://login.microsoftonline.com/common/",
                 RedirectUri= "https://localhost:44376/",
                 TokenValidationParameters = new TokenValidationParameters
                 {
                     ValidAudiences = new List<string>{ authClientID1, authClientID2 },
                     ValidateIssuer =true,
                     ValidIssuers= new[] { "https://sts.windows.net/<tenantID1>/", "https://sts.windows.net/<tenantID2>/" }
                 },

             });

После комментирования ClientID я получаю сообщение об ошибке вроде AADSTS900144: Тело запроса должно содержать следующий параметр: 'Client_id'

Я не уверен, как дать два идентификатора клиента и идентификатор клиента, чтобы аутентифицировать пользователей только из двух моих клиентов!

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Для доставки мультитенантного приложения в AAD необходимо создать только одно приложение. Поэтому у вас также есть только один client_id . Убедитесь, что в вашем приложении включена функция «Multi-Tenanted».

Вы найдете много информации здесь: https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant

Существует также полный образец: https://github.com/Azure-Samples/active-directory-dotnet-webapp-multitenant-openidconnect

   public void ConfigureAuth(IAppBuilder app)
    {         
        string ClientId = ConfigurationManager.AppSettings["ida:ClientID"];
        //fixed address for multitenant apps in the public cloud
        string Authority = "https://login.microsoftonline.com/common/";

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions { });

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = ClientId,
                Authority = Authority,
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    // instead of using the default validation (validating against a single issuer value, as we do in line of business apps), 
                    // we inject our own multitenant validation logic
                    ValidateIssuer = false,
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;                         
                        context.ProtocolMessage.RedirectUri = appBaseUrl;
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        return Task.FromResult(0);
                    },
                    // we use this notification for injecting our custom logic
                    SecurityTokenValidated = (context) =>
                    {
                        // retriever caller data from the incoming principal
                        string issuer = context.AuthenticationTicket.Identity.FindFirst("iss").Value;
                        string UPN = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
                        string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

                        if (
                            // the caller comes from an admin-consented, recorded issuer
                            (db.Tenants.FirstOrDefault(a => ((a.IssValue == issuer) && (a.AdminConsented))) == null)
                            // the caller is recorded in the db of users who went through the individual onboardoing
                            && (db.Users.FirstOrDefault(b =>((b.UPN == UPN) && (b.TenantID == tenantID))) == null)
                            )
                            // the caller was neither from a trusted issuer or a registered user - throw to block the authentication flow
                            throw new SecurityTokenValidationException();                            
                        return Task.FromResult(0);
                    },
                    AuthenticationFailed = (context) =>
                    {
                        context.OwinContext.Response.Redirect("/Home/Error?message=" + context.Exception.Message);
                        context.HandleResponse(); // Suppress the exception
                        return Task.FromResult(0);
                    }
                }
            });

    }
0 голосов
/ 18 января 2019

Ваш идентификатор клиента должен быть идентификатором клиента вашего приложения. Вы не создаете другое приложение в другом арендаторе. Установление авторитета для общего достаточно. Проверка эмитента может быть отключена, если вы хотите разрешить любого арендатора.

Затем, когда кто-то из другого арендатора входит в ваше приложение, ему будет предложено дать согласие на необходимые вам разрешения. После этого в их клиенте автоматически создается субъект службы, представляющий ваше приложение. У него такой же идентификатор клиента.

...