与多个 B2C 租户共享单个 WebApp 和 API 部署
Sharing single WebApp and API deployment with multiple B2C Tenants
当前情景:
Web 应用程序和 Web API 使用 AAD B2C 进行身份验证并且工作正常。每个客户都有一个独特的租户。 OpenIdConnectAuthenticationOptions
(网络应用程序)和 OAuthBearerAuthenticationOptions
(api)在应用程序 Startup
中设置。
如此处所述:Token based authentication for both Web App and Web API using Azure AD B2C
不幸的是,Web 应用程序和 API 都必须为每个客户部署,以将它们分开。
要求:
为多个客户使用相同的 Web 应用程序和 API,而不是为每个客户部署它们。每个客户的 Web 应用程序都会有不同的 URL。
问题 1(Web 应用程序):如何根据请求将用户重定向(用于身份验证)到正确的租户 URL?
即基于 Request.Url
而不是在应用程序 Startup
.
上从数据库(或内存)动态设置 OpenIdConnectAuthenticationOptions
(租户、applicationId、signInPolicy 等)
问题 2 (API):如何使用正确的租户验证收到的令牌?
即根据收到的令牌 clientId 即时设置 OAuthBearerAuthenticationOptions
配置,而不是在应用程序 Startup
根据我认为的假设,其中有几件事是行不通的。
首先,B2C没有倍数的概念"tenants"。 B2C本质上是
您的租户中的目录,不能进一步分离。你
在你的租户中可以有多个 B2C 目录,比如每个
客户,但您不能在一个
单个 B2C 目录。
其次,如果您的应用程序确实连接到多个 B2C
目录,您需要管理连接器、应用程序 ID、密钥
等每一个。然后由您的应用程序确定哪个
一个根据一些数据使用(URL 访问等)。
关于您如何吸引用户,我还想问几个问题?他们可以自己注册吗?他们有自己的用户商店吗?
如果您真的想将每个组织的用户帐户分开(并且他们还没有 SAML/OIDC 身份提供者),那么我会执行以下操作:
- 为每个客户创建一个 B2C 实例
- 为您的应用程序/网站创建 B2C 实例 API
- 使用自定义策略将您的应用程序 B2C 实例与您的客户 B2C 实例连接(确保在 XML 中为声明提供者使用
<Domain>
元素)
- 在您的应用程序中使用域提示来强制应用程序选择正确的 B2C 实例(参见:http://www.cloudidentity.com/blog/2014/11/17/skipping-the-home-realm-discovery-page-in-azure-ad/)
通过这种方式,您的应用程序只需要信任和维护单个 B2C 目录,如果您有拥有自己的 OIDC 或 SAML 端点的客户,他们将成为目录中的声明提供者,而不是单独的 B2C 实例.
根据@ManishJoisar 的要求,这是我很久以前解决问题的方法。这是一个旧的 .net 框架 4.8 代码示例。
请注意,如今,B2C v2 策略通过自定义策略提供了更好的联合实施。
public void ConfigureAuth(IAppBuilder app)
{
int index = 2000;
foreach (var record in SystemConfig.ApiToWebUrl)
{
app.MapWhen(
context => System.Web.HttpContext.Current.Request.Url.BaseURL() == record.Key,
config =>
{
var customer = SystemConfig.GetWebSettings(true)[record.Value];
config.UseOAuthBearerAuthentication(CreateBearerOptionsFromPolicy(index, customer.B2CSignInPolicyId,
customer.B2CAadInstance, customer.B2CTenant, customer.B2CApplicationId));
}
);
index++;
}
}
public OAuthBearerAuthenticationOptions CreateBearerOptionsFromPolicy(int index, string b2cPlicyName,
string b2cInstance, string b2cTenant, string b2cClientId)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
// This is where you specify that your API only accepts tokens from its own clients
ValidAudience = b2cClientId,
AuthenticationType = string.Format("{0}_{1}", b2cPlicyName, index)
};
var aadInstance = string.Format("https://{0}{1}", b2cTenant.Split('.')[0], ".b2clogin.com/{0}/{1}/v2.0/.well-known/openid-configuration");
var config = String.Format(aadInstance, b2cTenant, b2cPlicyName);
return new OAuthBearerAuthenticationOptions
{
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(config)),
Provider = new CustomOAuthBearerProvider()
};
}
当前情景:
Web 应用程序和 Web API 使用 AAD B2C 进行身份验证并且工作正常。每个客户都有一个独特的租户。 OpenIdConnectAuthenticationOptions
(网络应用程序)和 OAuthBearerAuthenticationOptions
(api)在应用程序 Startup
中设置。
如此处所述:Token based authentication for both Web App and Web API using Azure AD B2C
不幸的是,Web 应用程序和 API 都必须为每个客户部署,以将它们分开。
要求: 为多个客户使用相同的 Web 应用程序和 API,而不是为每个客户部署它们。每个客户的 Web 应用程序都会有不同的 URL。
问题 1(Web 应用程序):如何根据请求将用户重定向(用于身份验证)到正确的租户 URL?
即基于 Request.Url
而不是在应用程序 Startup
.
OpenIdConnectAuthenticationOptions
(租户、applicationId、signInPolicy 等)
问题 2 (API):如何使用正确的租户验证收到的令牌?
即根据收到的令牌 clientId 即时设置 OAuthBearerAuthenticationOptions
配置,而不是在应用程序 Startup
根据我认为的假设,其中有几件事是行不通的。
首先,B2C没有倍数的概念"tenants"。 B2C本质上是 您的租户中的目录,不能进一步分离。你 在你的租户中可以有多个 B2C 目录,比如每个 客户,但您不能在一个 单个 B2C 目录。
其次,如果您的应用程序确实连接到多个 B2C 目录,您需要管理连接器、应用程序 ID、密钥 等每一个。然后由您的应用程序确定哪个 一个根据一些数据使用(URL 访问等)。
关于您如何吸引用户,我还想问几个问题?他们可以自己注册吗?他们有自己的用户商店吗?
如果您真的想将每个组织的用户帐户分开(并且他们还没有 SAML/OIDC 身份提供者),那么我会执行以下操作:
- 为每个客户创建一个 B2C 实例
- 为您的应用程序/网站创建 B2C 实例 API
- 使用自定义策略将您的应用程序 B2C 实例与您的客户 B2C 实例连接(确保在 XML 中为声明提供者使用
<Domain>
元素) - 在您的应用程序中使用域提示来强制应用程序选择正确的 B2C 实例(参见:http://www.cloudidentity.com/blog/2014/11/17/skipping-the-home-realm-discovery-page-in-azure-ad/)
通过这种方式,您的应用程序只需要信任和维护单个 B2C 目录,如果您有拥有自己的 OIDC 或 SAML 端点的客户,他们将成为目录中的声明提供者,而不是单独的 B2C 实例.
根据@ManishJoisar 的要求,这是我很久以前解决问题的方法。这是一个旧的 .net 框架 4.8 代码示例。
请注意,如今,B2C v2 策略通过自定义策略提供了更好的联合实施。
public void ConfigureAuth(IAppBuilder app)
{
int index = 2000;
foreach (var record in SystemConfig.ApiToWebUrl)
{
app.MapWhen(
context => System.Web.HttpContext.Current.Request.Url.BaseURL() == record.Key,
config =>
{
var customer = SystemConfig.GetWebSettings(true)[record.Value];
config.UseOAuthBearerAuthentication(CreateBearerOptionsFromPolicy(index, customer.B2CSignInPolicyId,
customer.B2CAadInstance, customer.B2CTenant, customer.B2CApplicationId));
}
);
index++;
}
}
public OAuthBearerAuthenticationOptions CreateBearerOptionsFromPolicy(int index, string b2cPlicyName,
string b2cInstance, string b2cTenant, string b2cClientId)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
// This is where you specify that your API only accepts tokens from its own clients
ValidAudience = b2cClientId,
AuthenticationType = string.Format("{0}_{1}", b2cPlicyName, index)
};
var aadInstance = string.Format("https://{0}{1}", b2cTenant.Split('.')[0], ".b2clogin.com/{0}/{1}/v2.0/.well-known/openid-configuration");
var config = String.Format(aadInstance, b2cTenant, b2cPlicyName);
return new OAuthBearerAuthenticationOptions
{
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(config)),
Provider = new CustomOAuthBearerProvider()
};
}