【问题标题】:Multi-tenant in OpenIDConnect .Net FrameworkOpenIDConnect .Net 框架中的多租户
【发布时间】:2019-06-12 08:11:36
【问题描述】:

我正在尝试实现多租户身份验证(我正在学习),到目前为止,我已经成功地在单租户中实现了我的应用程序的身份验证。

我用于单租户的代码是

 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 中注册我的应用程序并获取客户端 ID,然后将其放入我的配置中。一切正常。

但现在我必须使用多租户类型来实现它。即使它是多租户的,我也只允许 2 个租户用户。假设abc.onmicrosoft.com 和contoso.onmicrosoft.com

到目前为止,我已经完成了在ABC 租户和Contoso 租户中注册我的应用程序,然后获得 2 个客户端 ID。但我的问题是无法在UseOpenIdConnectAuthentication 中提供 2 个客户端 ID(请参阅下面的更新代码)

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'

我不确定如何提供我的两个 ClientID 和租户 ID,以便仅对来自我的两个租户的用户进行身份验证!

【问题讨论】:

    标签: .net azure authentication multi-tenant openid-connect


    【解决方案1】:

    要交付多租户应用程序,您只需在 AAD 中创建一个应用程序。因此,您也只有 一个 client_id。确保您的应用已启用“多租户”。

    您可以在这里找到很多信息: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);
                        }
                    }
                });
    
        }
    

    【讨论】:

      【解决方案2】:

      您的客户端 ID 应该是您的应用客户端 ID。您不会在另一个租户中创建另一个应用程序。将权限设置为 common 就足够了。如果您想允许任何租户,可以禁用颁发者验证。

      然后,当其他租户的某人登录到您的应用时,系统会要求他们同意您所需的权限。一旦他们这样做,代表您的应用程序的服务主体会自动在他们的租户中创建。它具有相同的客户端 ID。

      【讨论】:

      • 感谢您的回答。我想我明白你的意思了。但是按照我的要求。我只想允许来自 2 个特定租户而不是其他租户的用户。在这种情况下,我们怎样才能做到这一点。?
      • 啊,你遇到了我所说的 N 租户情况。在这种情况下,不要禁用颁发者验证。保持共同的权威,别无选择。然后为 TokenValidationParameters 指定 ValidIssuers。颁发者字符串始终为 https://sts.windows.net/{tenantid}/,因此添加其中两个并将 {tenantId} 替换为两个 AAD 的目录 ID。
      • @junnas 我已经根据您的评论更新了我的问题,不确定这是否正确,但面临一些问题。你能调查一下吗?
      • @junnas 是的,它现在正在工作。但正如已经告诉我的那样,当我尝试使用“AADSTS700016:在目录'xxx-xxxx-xx.(TenantID) 中找不到标识符为'xx-xxxx-xxxxx'(clientId) 的应用程序”时,它给了我这样的错误。在第二个目录中找到的用户,但由于 clientId 已在租户 1 中注册,因此出现此错误
      • 这很奇怪..您是否尝试过使用租户 2 的管理员登录(仅存在于租户 2 中)?
      猜你喜欢
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 2014-10-14
      • 2012-03-24
      • 1970-01-01
      • 2015-01-05
      • 1970-01-01
      • 2020-11-04
      相关资源
      最近更新 更多