Identity Server 4 和 Sustainsys SAML2 拒绝非 CORS 请求作为 CORS 请求


  • 我正在使用带有AspNetIdentity的Identity Server 4。
  • 我使用 Sustainsys 添加了一个 SAML 身份验证提供程序。
  • 我可以使用本地帐户成功登录。
  • 我想将 SAML 身份验证提供程序链接到我的本地帐户。我按照流程链接外部和社交登录(就像我在Google,Microsoft和Facebook上成功所做的那样) - 链接是 https://identity.domain.com/Manage/ExternalLogins
  • 我现在可以选择链接 SAML2 服务
  • 我可以成功链接到外部 SSO 并进行身份验证;然后我被重定向回 https://identity.domain.com/Manage/LinkLoginCallback 但代码在以下一点在管理控制器中失败:

为 GetExternalLoginInfoAsync 返回 Null。 用户。Id 是正确的,并且存在于数据库中。

ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync(user.Id);
if (info == null)
{
throw new ApplicationException($"Unexpected error occurred loading external login info for user with ID '{user.Id}'.");
}

据我所知,应该有一个属性集合,这些属性已由外部 SAML 提供程序返回给:

public async Task<IActionResult> LinkLogin(string provider)

我怀疑该问题可能与 CORS 错误有关,但是即使我在启动中添加了以下行.cs根据 http://docs.identityserver.io/en/release/topics/cors.html 上的文档,我也没有成功解决此错误。

var cors = new DefaultCorsPolicyService(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
{
AllowedOrigins = { "https://sso.acme.com" }
};
services.AddSingleton<ICorsPolicyService>(cors);

以下是调试信息的日志:

LinkLogin
  • redirectUrl:/Manage/LinkLoginCallback
  • 身份验证方案:"Identity.Application"已成功通过身份验证。
  • 提取的 SAML 断言_ea533182b0cb1781868a660af48ced3529d568
  • 身份验证方案:"Identity.Application"已成功通过身份验证。
  • 链接登录回调 User.Id: a0162430-eb22-4154-bf59-0ba49bfd473d
  • 已成功处理 SAML 响应_402e6060e55e8e5d3b05f52ff5e5d2d7d4d786和经过身份验证的 test@acme.com
  • 系统应用程序异常:加载 ID 为"a0162430-eb22-4154-bf59-0ba49bfd473d"的用户的外部登录信息时发生意外错误。
  • 来自源的路径"/Saml2/Acs"发出 CORS 请求:"https://sso.acme.com",但被忽略,因为路径不适用于允许的身份服务器 CORS 端点
  • 链接登录回调启动
  • SAML2 响应_402e6060e55e8e5d3b05f52ff5e5d2d7d4d786的验证条件
  • HTTP POST 绑定提取的消息
  • SAML 响应_402e6060e55e8e5d3b05f52ff5e5d2d7d4d786的签名验证已通过
  • 身份验证方案:"Identity.Application"已成功通过身份验证。

更新: - 发回 Saml 请求的客户说这不是对/Saml2/ACS 的 CORS 请求,因此不明白为什么我们会收到来自身份服务器/Sustainsy 的错误

这个问题的解决方案最终很简单。

  • 我试图处理一个Saml响应(在ExternalLoginCallback内),使用这种方法来处理来自谷歌,Facebook Microsoft的响应。

ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(user.Id);

  • 很明显,Saml 请求的 ExternalLoginCallback 过程略有不同 - 您需要以下代码:

AuthenticateResult samlResult = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);

  • 然后,可以使用 中的属性生成ExternalLoginInfo对象samlResult

  • 以下示例中提供了用于此目的的所有代码:

https://github.com/Sustainsys/Saml2/blob/netstandard/Samples/SampleIdentityServer4/Quickstart/Account/AccountController.cs

  • 有趣的是,日志文件仍然打印出来自源"https://sso.acme.com"的路径"/Saml2/Acs"的 CORS 请求,但由于路径不适用于允许的 IdentityServer CORS 终结点而被忽略,但这似乎对登录过程没有影响。 所以一个"红鲱鱼"。

最新更新