在Identityserver4 .NET Core中启用多个AzureAd

时间:2017-12-07 09:59:40

标签: asp.net-core azure-active-directory identityserver4

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

这是必要的原因,是多个租户需要能够通过1个身份服务器登录自己的AzureAD。设置这些将动态发生。

对于此示例,我对AuthenticationBuilder进行了扩展,允许传递多个AzureAd并将其添加到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作为登录选项,这很好用。我认为身份验证流程将保持不变。

相反,出现了2个问题。

  1. 两次登录都会导致最后一次配置(azure2),azure1就会消失。这意味着最后一个配置将覆盖第一个配置。
  2. 使用有效帐户登录azure2时,登录身份服务器失败,并出现以下错误:
  3.   

    例外:关联失败。   Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler + d__12.MoveNext()

    从字典中删除2个AzureAD中的1个会导致一切正常。

    更新

    实施最少特权答案(谢谢)会产生以下结果: 它“几乎”有效。 AzureAD被正确识别,导致正确的流量并仅接受相应的帐户。但是现在客户端在回调到身份服务器之后没有成功登录。

    我觉得这只是关于signinscheme的一个小编辑,但我无法弄明白,因为这方面的文件很少。

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

    解决方案

    可能不那么困难,但是分享解决方案以帮助他人:

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

1 个答案:

答案 0 :(得分:2)

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

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