OpenIDConnect.Net框架中的多租户

OpenIDConnect.Net框架中的多租户,.net,azure,authentication,multi-tenant,openid-connect,.net,Azure,Authentication,Multi Tenant,Openid Connect,我试图实现多租户身份验证(我正在学习),到目前为止,我已经成功地在单租户中实现了我的应用程序身份验证 我对单租户使用的代码是 public void ConfigureAuth(IAppBuilder app) { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuth

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

我对单租户使用的代码是

 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
tenant和
Contoso
tenant中注册了我的应用程序,然后获得了2个客户端Id。但是我的问题是在
UseOpenIdConnectAuthentication
中无法提供2个客户端ID(请参阅下面我的更新代码)

这对我来说是新的。我可能错了,请纠正我,使事情朝正确的方向发展

更新1:

app.UseOpenIdConnectAuthentication(
新的OpenIdConnectAuthenticationOptions
{
//ClientId=AuthClientD1,//向第一个租户注册的应用程序ID
权威=”https://login.microsoftonline.com/common/",
重定向URI=”https://localhost:44376/",
TokenValidationParameters=新的TokenValidationParameters
{
validudiences=新列表{authClientID1,authClientID2},
validateisuer=true,
ValidIssuers=new[]{”https://sts.windows.net//", "https://sts.windows.net//" }
},
});
在评论了这个陈词滥调之后,我收到了这样的错误 AADSTS900144:请求正文必须包含以下参数: “客户id”


我不知道如何给出我的两个ClientID和租户ID,以便仅对来自我的两个租户的用户进行身份验证

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


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

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

您可以在这里找到很多信息:

还有一个完整的样本:


谢谢你的回答。我想我明白你的意思了。但是按照我的要求。我只想允许来自2个特定租户而不是其他租户的用户。在这种情况下,我们如何才能做到这一点?啊,你有我称之为N租户的情况。在这种情况下,不要禁用颁发者验证。保持共同权威,别无选择。然后为TokenValidationParameters指定ValidisUsers。颁发者字符串始终为
https://sts.windows.net/{tenantid}/
,所以添加其中两个,并用两个AAD的目录ID替换{tenantid}。@junnas我已根据您的评论更新了我的问题,不确定这是否正确,但面临一些问题。你能调查一下吗?@junnas是的,它正在工作。但正如已经告诉我的那样,它给了我类似“AADSTS700016:标识符为'xx-xxxx-xxxxx'(clientId)的应用程序在目录'xxx xxxx xx.(TenantID)中找不到”的错误。当我尝试使用在第二个目录中找到的用户登录时,但由于clientId是在租户1中注册的,它给出的这个错误非常奇怪。。您是否尝试过使用租户2(仅存在于租户2中)的管理员登录?
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
                     },

                 });
        }
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>/" }
                 },

             });
   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);
                    }
                }
            });

    }