在Identityserver4 .NET Core中启用多个AzureAd [英] Enable multiple AzureAd in Identityserver4 .NET Core

查看:179
本文介绍了在Identityserver4 .NET Core中启用多个AzureAd的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在一台身份服务器中为多个AzureAD启用登录功能.

I'm trying to enable login-functionality to multiple AzureAD's in one identity server.

之所以这样做是因为,多个租户需要能够通过1个身份服务器登录到自己的AzureAD.设置这些将动态进行.

The reason this is necessary, is that multiple tenants need to be able to login to their own AzureAD through 1 identityserver. Setting these up will happen dynamically.

在此示例中,我对AuthenticationBuilder进行了扩展,该扩展允许传递多个AzureAd,并将它们添加到AuthenticationBuilder.

For this example, I have made an extension to AuthenticationBuilder which allows passing multiple AzureAd's and adds them to the AuthenticationBuilder.

//startup.cs
        Dictionary<string, string> azure1 = new Dictionary<string, string>();
        azure1.Add("name", "azure1");
        azure1.Add("clientid", <azure1id>);
        azure1.Add("tenantid", <azure1tenant>);
        Dictionary<string, string> azure2 = new Dictionary<string, string>();
        azure2.Add("name", "azure2");
        azure2.Add("clientid", <azure2id>);
        azure2.Add("tenantid", <azure2tenant>);
        Dictionary<string, string>[] ids = { azure1, azure2 };

        services.AddAuthentication()
        .AddCookie()
        .AddAzureAdAuthentications(ids)


//AuthenticationBuilderExtension
    public static AuthenticationBuilder AddAzureAdAuthentications(this AuthenticationBuilder builder, Dictionary<string, string>[] azureAds)
    {
        string name = "";
        string clientid = "";
        string tenantid = "";
        foreach (Dictionary<string, string> azuread in azureAds)
        {
            name = azuread.GetValueOrDefault("name");
            clientid = azuread.GetValueOrDefault("clientid");
            tenantid = azuread.GetValueOrDefault("tenantid");
            builder.AddOpenIdConnect(name, name, options =>
            {
                options.Authority = $"https://login.microsoftonline.com/{tenantid}";
                options.ClientId = clientid;
                options.ResponseType = OpenIdConnectResponseType.IdToken;
            });
        }
        return builder;
    }

我希望上面的代码添加2个azureAd作为登录选项,这可以正常工作.我认为认证流程将保持不变.

I would expect the above code to add 2 azureAd's as a login options, this works fine. I would think the authentication-flow would stay intact.

而是出现了2个问题.

Instead, 2 problems appear.

  1. 这两个loginoptions都导致最后一个配置(azure2),azure1才消失.这意味着最后一个配置将覆盖第一个配置.
  2. 使用有效帐户登录到azure2时,登录到Identityserver失败,并发生以下错误:

异常:相关性失败. Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler + d__12.MoveNext()

Exception: Correlation failed. Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler+d__12.MoveNext()

从字典中删除2个AzureAD中的1个,一切正常.

Removing 1 of the 2 AzureAD's from the dictionary results in everything working fine.

实施最低特权答案(谢谢)会导致以下结果: 它几乎"起作用. AzureAD被正确识别,从而导致正确的流程并仅接受相应的帐户.但是现在,在回调到身份服务器之后,客户端无法成功登录.

Implementing leastprivileges answer (thanks) results in the following: It "almost" works. The AzureAD's are recognized correctly, leading to the correct flows and accepting only the corresponding accounts. But now the client is not succesfully logged in after the callback to the identityserver.

我觉得这只是有关signinscheme的一小部分编辑,但由于涉及的文献很少,我无法真正弄清楚.

I feel it's just a small edit regarding the signinscheme, but i can't really figure it out as the documention on this is quite minimal.

foreach (Dictionary<string, string> azuread in ids)
        {
            string name = azuread.GetValueOrDefault("name");
            string clientid = azuread.GetValueOrDefault("clientid");
            string tenantid = azuread.GetValueOrDefault("tenantid");
            services.AddAuthentication(name).AddCookie($"Cookie{name}").AddOpenIdConnect(name, name, options =>
            {
                options.SignInScheme = $"Cookie{name}";
                options.SignOutScheme = $"Cookie1{name}";
                options.CallbackPath = $"/signin-{name}";
                options.Authority = $"https://login.microsoftonline.com/{tenantid}";
                options.ClientId = clientid;
                options.ResponseType = OpenIdConnectResponseType.IdToken;
            });
        }

解决方案

可能没有那么困难,但是可以共享解决方案来帮助他人:

Solution

Might not be that difficult, but sharing the solution to help others:

            services.AddAuthentication().AddCookie($"Cookie{name}")
            .AddOpenIdConnect(name, name, options =>
            {
                options.CallbackPath = $"/signin-{name}";
                options.Authority = $"https://login.microsoftonline.com/{tenantid}";
                options.ClientId = clientid;
                options.ResponseType = OpenIdConnectResponseType.IdToken;
            });

推荐答案

每个处理程序至少需要一个唯一的CallbackPath-还有其他用于注销和后重定向的回调-如果您正在使用这些功能,则也必须进行设置

Each handler needs at least a unique CallbackPath - there are other callbacks for signout and post redirect - they must be set as well if you are using those features.

此外,身份验证方案必须是唯一的.

Also the authentication scheme must be unique.

这篇关于在Identityserver4 .NET Core中启用多个AzureAd的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆