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