简体   繁体   English

具有多个 B2C 环境的基于 .NET Core 路由的身份验证

[英].NET Core route based authentication with multiple B2C environments

Situation情况

We have clients that should be able to login into our application.我们有客户应该能够登录到我们的应用程序。 Our clients do also have clients, who also may login.我们的客户也有客户,他们也可以登录。 Therefore we have an Azure AD B2C environment per client.因此,我们每个客户端都有一个 Azure AD B2C 环境。

So, we want to have one single application that can be used to authenticate against multiple Azure B2C environments.因此,我们希望拥有一个可用于针对多个 Azure B2C 环境进行身份验证的应用程序。 We want to have this route-based.我们希望有这个基于路由的。 So:所以:

/client1 goes to B2C environment Client1B2C, with user flow B2C_1_Client1 /client1 转到 B2C 环境 Client1B2C,用户流为 B2C_1_Client1

/client2 goes to B2C environment Client2B2C, with user flow B2C_1_Client2 /client2 转到 B2C 环境 Client2B2C,用户流为 B2C_1_Client2

Challenge挑战

So, we need to define multiple instances of AddOpenIdConnect.因此,我们需要定义多个 AddOpenIdConnect 实例。 I do this inside a specific builder, so my Startup.cs keeps clean:我在特定的构建器中执行此操作,因此我的 Startup.cs 保持干净:

Startup.cs启动文件

            ...
            var AzureAdB2CSettings = new List<AzureAdB2COptions>();
            Configuration.GetSection("Authentication:AzureAdB2C").Bind(AzureAdB2CSettings, c => c.BindNonPublicProperties = true);

            services.AddAuthentication(sharedOptions =>
            {
                ...
            })
            .AddAzureAdB2C(options => Configuration.Bind("Authentication:AzureAdB2C", options), AzureAdB2CSettings)
            ...

And there is the builder:还有建造者:

AzureAdB2CAuthenticationBuilderExtensions.cs AzureAdB2CAuthenticationBuilderExtensions.cs

        ...
        public static string policyToUse;
        
        public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder, Action<AzureAdB2COptions> configureOptions, List<AzureAdB2COptions> openIdOptions)
        {
            ...
            foreach(var b2c in openIdOptions)
            {
                builder.AddOpenIdConnect(b2c.SignUpSignInPolicyId, b2c.SignUpSignInPolicyId, options =>
                {
                    options.Authority = b2c.Authority;
                    options.ClientId = b2c.ClientId;
                    options.CallbackPath = b2c.CallbackPath;
                    options.SignedOutCallbackPath = b2c.SignedOutCallbackPath;
                    options.ClientSecret = b2c.ClientSecret;
                });
            }

            return builder;
        }
        ...

        public Task OnRedirectToIdentityProvider(RedirectContext context)
        {
            ...
            string policyToUse = "B2C_1_" + context.Request.Query["area"];
            ...

            var b2cSettings = AzureAdB2CSettings.Find(x => x.SignUpSignInPolicyId.ToLower().Equals(policyToUse.ToLower()));

            AzureAdB2CAuthenticationBuilderExtensions.policyToUse = b2cSettings.DefaultPolicy;
            ...

Yippee ya yeeey! Yippee ya yeeey! We can have a dynamic amount of add AddOpenIdConnect, based on a configuration file.我们可以根据配置文件动态添加 AddOpenIdConnect。 The chosen authentication scheme has been set to the static string "AzureAdB2CAuthenticationBuilderExtension.policyToUse".所选的身份验证方案已设置为静态字符串“AzureAdB2CAuthenticationBuilderExtension.policyToUse”。

But now it comes... how to define the Authorization header?但是现在来了...如何定义Authorization标头?

BackofficeController.cs后台控制器.cs

        ...
        [Authorize(AuthenticationSchemes = AzureAdB2CAuthenticationBuilderExtensions.policyToUse)]
        public async Task<IActionResult> ChooseBackoffice()
        {
            ...
        }
        ...

AUTCH!!奥奇!! You can't use dynamic attributes... Have tried to set the chosen scheme as a default, but it seems we can only define a default at startup, not during runtime...您不能使用动态属性...尝试将所选方案设置为默认值,但似乎我们只能在启动时定义默认值,而不能在运行时定义...

Any suggestions how to solve this challenge?有什么建议可以解决这个挑战吗?

One suggestion is to set all possible values of AzureAdB2CAuthenticationBuilderExtensions.policyToUse in config and read from there.一个建议是在配置​​中设置AzureAdB2CAuthenticationBuilderExtensions.policyToUse所有可能值并从那里读取。

For each action method/controller (as per your use case), define the attribute value from these configs.对于每个操作方法/控制器(根据您的用例),从这些配置中定义属性值。

It seems indeed impossible at the moment to have multiple B2C environments connected to one Azure App Service.目前看来确实不可能将多个 B2C 环境连接到一个 Azure 应用服务。

Therefore there is a choice:因此有一个选择:

  1. Don't do it.不要这样做。 Just create one giant B2C environment.只需创建一个巨大的 B2C 环境。
  2. Make a multi-instance application instead of a multi-tenant application.制作多实例应用程序而不是多租户应用程序。

Our partner came with another solution.我们的合作伙伴提出了另一种解决方案。 We haven't explored this route.我们还没有探索过这条路线。 Who knows does this help somebody:谁知道这对某人有帮助:

  1. Orchard core.果园核心。 Seems like a multi-tenant .NET Core solution.看起来像是一个多租户的 .NET Core 解决方案。 Looks like a complete application, where this multi-tenant question will be handled.看起来像一个完整的应用程序,将在其中处理这个多租户问题。

We did choose option 2. This makes sure we have a good separation of data.我们确实选择了选项 2。这确保我们有良好的数据分离。 There are more hosting costs, although with a multi-tenant application all the traffic does to one application.尽管使用多租户应用程序,所有流量都流向一个应用程序,但托管成本更高。 This does require better hardware, so is also more expensive.这确实需要更好的硬件,因此也更昂贵。 I do not know which option is more expensive.我不知道哪个选项更贵。

Now comes the question how to deploy this efficiently, but that's another question...现在是如何有效部署的问题,但这是另一个问题......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM