- 我正在使用带有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 终结点而被忽略,但这似乎对登录过程没有影响。 所以一个"红鲱鱼"。