多个身份验证提供程序 OWIN

3

我正在尝试根据组织的请求实现多重身份验证。在startup.auth.cs中,我有以下内容:

 foreach (OrganizationModel org in orgList)
    {
        if (org.AuthenticationType != "Azure")
        {
            var adfs = new WsFederationAuthenticationOptions
            {
                AuthenticationType = org.AuthenticationType,
                Caption = org.Caption,
                BackchannelCertificateValidator = null,
                MetadataAddress = org.MetadataUrl,
                Wtrealm = org.Realm,
                Notifications = new WsFederationAuthenticationNotifications
                {
                    AuthenticationFailed = context =>
                    {
                        context.HandleResponse();
                        context.Response.Redirect("Home/Error?message=" + context.Exception.Message);
                        return Task.FromResult(0);
                    }
                },
                TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },

            };
            app.UseWsFederationAuthentication(adfs);
        }
        else
        {
            var azure = new WsFederationAuthenticationOptions
            {
                AuthenticationType = org.AuthenticationType,
                Caption = org.Caption,
                BackchannelCertificateValidator = null,
                MetadataAddress = org.MetadataUrl,
                Wtrealm = org.Realm,
                Notifications = new WsFederationAuthenticationNotifications
                {
                    AuthenticationFailed = context =>
                    {
                        context.HandleResponse();
                        context.Response.Redirect("Home/Error?message=" + context.Exception.Message);
                        return Task.FromResult(0);
                    }
                },
                TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },

            };
            app.UseWsFederationAuthentication(azure);
        }
    }

我为登录填充各种身份验证提供程序。当我点击 ADFS 进行身份验证时,我能够成功认证、获得声明,一切正常。但是,当我尝试针对 Azure AD 进行身份验证时,我会收到“ID 4037”错误,“无法解析用于验证签名的密钥”。 注:如果我只尝试 Azure AD(注释掉 ADFS 部分),它就能正常工作。Orglist 从数据库中填充,并包含元数据 URL、域等信息。出于开发目的,我已将 https://localhost:44303 配置为两者的领域。

我的登录后回调方法是:

 [AllowAnonymous]
        public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
        {
            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

            if (loginInfo == null)
            {
                return RedirectToAction("Login");
            }

            // Sign in the user with this external login provider if the user already has a login
            var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
                case SignInStatus.Failure:
                default:
                    // If the user does not have an account, then prompt the user to create an account
                    ViewBag.ReturnUrl = returnUrl;
                    ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                    return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.DefaultUserName});
            }
        }

请指导我哪里做错了

1个回答

2
我找到了问题所在。当我们有多个认证提供者时,每个认证选项添加到OWIN中间件管道的认证类型应该是唯一的。 对于想要实施类似解决方案的人来说,下面是适用于我的代码。
 foreach (OrganizationModel org in orgList)
            {
                switch (org.AuthenticationName)
                {
                    case "ADFS":
                                var adfs = new WsFederationAuthenticationOptions
                                      {
                                          AuthenticationType = org.AuthenticationType,
                                          Caption = org.Caption,
                                          BackchannelCertificateValidator = null,
                                          MetadataAddress = org.MetadataUrl,
                                          Wtrealm = org.Realm,
                                          SignOutWreply = org.Realm,
                                          Notifications = new WsFederationAuthenticationNotifications
                                          {
                                              AuthenticationFailed = context =>
                                              {
                                                  context.HandleResponse();
                                                  context.Response.Redirect("Home/Error?message=" + context.Exception.Message);
                                                  return Task.FromResult(0);
                                              }
                                          },
                                          TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },
                                      };
                        app.UseWsFederationAuthentication(adfs);
                        break;
                    case "Azure":
                        OpenIdConnectAuthenticationOptions azure = null;
                        azure = new OpenIdConnectAuthenticationOptions
                        {
                            AuthenticationType = org.AuthenticationType,
                            Caption = org.Caption,
                            BackchannelCertificateValidator = null,
                            Authority = org.MetadataUrl,
                            ClientId = org.ClientId,
                            RedirectUri = org.Realm,
                      PostLogoutRedirectUri=org.Realm,
                            Notifications = new OpenIdConnectAuthenticationNotifications
                         {
                             AuthenticationFailed = context =>
                             {
                                 context.HandleResponse();
                                 context.Response.Redirect("Home/Error?message=" + context.Exception.Message);
                                 return Task.FromResult(0);
                             }
                         },
                        };
                        app.UseOpenIdConnectAuthentication(azure);
                        break;
                    case "Shibboleth":
                    break;
                    default:
                        break;
                }
            }

我认为你在这里所做的一切都是绕过了问题。据我所知,当你有多个提供程序时,其中2个或更多个使用WS-Federation时,问题就会发生。在你的解决方案中,你只是将Azure更改为使用OpenID Connect而已。虽然它能够工作,但并没有真正解决原始问题。 - RobSiklos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接