【问题标题】:IdentityServer4 multiple WSFederation-providers cause an exceptionIdentityServer4 多个 WSFederation-providers 导致异常
【发布时间】:2018-05-27 04:11:35
【问题描述】:

有人告诉我,我将在这里描述的 issue 不是 IdentityServer 中的错误,所以我可能做错了什么:

此代码有效,在QuickStart-project using EFCore 中使用单个 WSFederation-instance 作为身份提供者。

注册提供者:

services.AddAuthentication()
            .AddWsFederation("WsFederation", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.Wtrealm = realm;
                options.MetadataAddress = metadata;
                options.Events.OnTicketReceived += OnTicketReceived;
            })

OnTicketReceived-Eventhandler:

/// <summary>
/// Transform the UPN-claim to the sub-claim to be compatible with IdentityServer4
/// </summary>
private async Task OnTicketReceived(TicketReceivedContext ticketReceivedContext)
{
     var identity = ticketReceivedContext.Principal.Identities.First();
     identity.AddClaim(new Claim("sub", ticketReceivedContext.Principal.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")));

}

一旦我添加了第二个提供者,我会在尝试使用第二个提供者时遇到异常,因为添加的第一个提供者会接受请求并在收到请求后立即抛出异常:

services.AddAuthentication()
.AddWsFederation("WsFederation_LocalHost", "WsFederation_LocalHost", options =>
                {
                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    options.Wtrealm = "urn:aspnetcorerp";
                    options.MetadataAddress = "http://localhost:5000/wsfederation";
                    options.Events.OnTicketReceived += OnTicketReceived;
                    options.RequireHttpsMetadata = false;
                })
                .AddWsFederation("WsFederation_SVN", "WsFederation_SVN", options =>
                {
                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    options.Wtrealm = realm;
                    options.MetadataAddress = metadata;
                    options.Events.OnTicketReceived += OnTicketReceived;
                    options.Events.OnSecurityTokenReceived += OnSecurityTokenReceived;
                })

我得到的例外是 - 如果我通过允许未经请求的登录来修复它,则会发生其他异常,因为它仍然尝试使用错误的提供程序:

System.Exception:不允许未经请求的登录。 在 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.d__12.MoveNext()

我找到了它的提出点in IdentityServer4

public async Task<bool> HandleRequestAsync()
    {
var result = await _inner.HandleRequestAsync();

如果我更改上面的代码来捕获异常,我可以解决这个问题,因为它之后会传递正确的提供程序并且登录成功:

var result = false;
try
{
   result = await _inner.HandleRequestAsync();
}
catch (Exception) {}

我不满意必须分叉 IdentityServer4 来解决这个问题,所以我要求在不更改 IdentityServer 代码的情况下提供解决方案。我可以介入并进行更改的地方是我的 WSFederation-endpoint 的配置,即 AccountController 中的 before starting the ExternalLoginat the callback

AccountController 中的回调:

    [HttpGet]
    public async Task<IActionResult> ExternalLoginCallback()
    {
        // read external identity from the temporary cookie - I don't know how I could change which AuthenticationMiddleware gets called
        var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);

非常感谢我应该从哪里开始的任何提示。

【问题讨论】:

    标签: c# asp.net-core .net-core identityserver4 ws-federation


    【解决方案1】:

    知道了 - 解决方案是为不同的提供者设置不同的 CallbackPaths:

    services.AddAuthentication()
                    .AddWsFederation("WsFederation_LocalHost", "WsFederation_LocalHost", options =>
                    {
                        options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                        options.Wtrealm = "urn:aspnetcorerp";
                        options.MetadataAddress = "http://localhost:5000/wsfederation";
                        options.Events.OnTicketReceived += OnWsFedTicketReceived;
                        options.RequireHttpsMetadata = false;
                        options.CallbackPath = "/signin-wsfed-localhost";
                    })
                    .AddWsFederation("WsFederation_SVN", "WsFederation_SVN", options =>
                    {
                        options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                        options.Wtrealm = realm;
                        options.MetadataAddress = metadata;
                        options.Events.OnTicketReceived += OnWsFedTicketReceived;
                        options.CallbackPath = "/signin-wsfed-svn";
                    })
    

    【讨论】:

    • 嘿,回调路径可以是任何随机名称吗?喜欢 /signin-wsfed-svn-random?只需要独一无二?
    • 是的,您可以使用自己选择的路径。
    • 非常感谢。这个答案对我帮助很大。很久以来一直在寻找解决方案。我尝试将 AllowUnsolicitedLogins 设置为 true,但它似乎产生了问题,您认为 AllowUnsolicitedLogins 设置为 true 可以替代吗?
    • 我不知道这是否有帮助,但除了你遇到的问题之外,这也会降低安全性,所以我不建议使用它。我也总是会使用现有的功能,而不是尝试实施变通办法,因为这样可能会产生更多的安全问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 2018-06-08
    相关资源
    最近更新 更多