Identity Server 4 和 Sustainsys SAML2 拒绝将非 CORS 请求作为 CORS 请求
Identity Server 4 & Sustainsys SAML2 rejecting non-CORS request as a CORS request
- 我正在使用带有 AspNetIdentity 的 Identity Server 4。
- 我已经使用 Sustainsys 添加了一个 SAML 身份验证提供程序。
- 我可以使用本地帐户成功登录。
- 我想 link SAML 身份验证提供商到我的本地帐户。我遵循 link 外部和社交登录的过程(正如我在 Google、Microsoft 和 Facebook 上成功完成的那样)- link 是 https://identity.domain.com/Manage/ExternalLogins
- 我现在可以选择 link SAML2 服务
- 我可以 link 成功连接到外部 SSO 并进行身份验证;然后我被重定向回 https://identity.domain.com/Manage/LinkLoginCallback 但代码在 ManageController 中的以下几点失败:
正在为 GetExternalLoginInfoAsync 返回 Null。 user.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 错误有关,但是我没有成功解决这个错误,尽管我已经根据 http://docs.identityserver.io/en/release/topics/cors.html 上的文档在 startup.cs 中添加了以下几行.
var cors = new DefaultCorsPolicyService(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
{
AllowedOrigins = { "https://sso.acme.com" }
};
services.AddSingleton<ICorsPolicyService>(cors);
调试信息日志如下:
- LinkLogin redirectUrl: /Manage/LinkLoginCallback
- AuthenticationScheme:"Identity.Application" 已成功通过身份验证。
- 提取的 SAML 断言 _ea533182b0cb1781868a660af48ced3529d568
- AuthenticationScheme:"Identity.Application" 已成功通过身份验证。
- LinkLoginCallback User.Id: a0162430-eb22-4154-bf59-0ba49bfd473d
- 已成功处理 SAML 响应 _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786 并通过身份验证 test@acme.com
- System.ApplicationException:为 ID 为 'a0162430-eb22-4154-bf59-0ba49bfd473d' 的用户加载外部登录信息时发生意外错误。
- CORS 请求路径:“/Saml2/Acs”来自来源:“https://sso.acme.com”但被忽略,因为路径不是允许的 IdentityServer CORS端点
- LinkLoginCallback 开始
- SAML2 响应的验证条件 _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786
- Http POST 绑定提取消息
- Saml Response _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786 的签名验证已通过
- AuthenticationScheme:"Identity.Application" 已成功通过身份验证。
更新:
- 客户发回 Saml 请求说它不是 /Saml2/ACS 的 CORS 请求,因此不明白为什么我们会收到从 Identity Server / Sustainsy
收到的错误
最后这个问题的解决方法很简单。
- 我正在尝试使用处理来自 Google、Microsoft of Facebook
的响应的方法来处理 Saml 响应(在 ExternalLoginCallback
内)
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(user.Id);
- 显然,Saml 请求的 ExternalLoginCallback 过程略有不同 - 您需要以下代码:
AuthenticateResult samlResult = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
然后您可以使用 samlResult
中的属性构建一个 ExternalLoginInfo
对象
以下示例中提供了所有相关代码:
- 有趣的是,日志文件仍然打印出 针对路径的 CORS 请求:“/Saml2/Acs” 来自来源:“https://sso.acme.com” 但被忽略了因为路径不适用于允许的 IdentityServer CORS 端点 但这似乎对登录过程没有影响。所以 "red-herring".
- 我正在使用带有 AspNetIdentity 的 Identity Server 4。
- 我已经使用 Sustainsys 添加了一个 SAML 身份验证提供程序。
- 我可以使用本地帐户成功登录。
- 我想 link SAML 身份验证提供商到我的本地帐户。我遵循 link 外部和社交登录的过程(正如我在 Google、Microsoft 和 Facebook 上成功完成的那样)- link 是 https://identity.domain.com/Manage/ExternalLogins
- 我现在可以选择 link SAML2 服务
- 我可以 link 成功连接到外部 SSO 并进行身份验证;然后我被重定向回 https://identity.domain.com/Manage/LinkLoginCallback 但代码在 ManageController 中的以下几点失败:
正在为 GetExternalLoginInfoAsync 返回 Null。 user.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 错误有关,但是我没有成功解决这个错误,尽管我已经根据 http://docs.identityserver.io/en/release/topics/cors.html 上的文档在 startup.cs 中添加了以下几行.
var cors = new DefaultCorsPolicyService(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
{
AllowedOrigins = { "https://sso.acme.com" }
};
services.AddSingleton<ICorsPolicyService>(cors);
调试信息日志如下:
- LinkLogin redirectUrl: /Manage/LinkLoginCallback
- AuthenticationScheme:"Identity.Application" 已成功通过身份验证。
- 提取的 SAML 断言 _ea533182b0cb1781868a660af48ced3529d568
- AuthenticationScheme:"Identity.Application" 已成功通过身份验证。
- LinkLoginCallback User.Id: a0162430-eb22-4154-bf59-0ba49bfd473d
- 已成功处理 SAML 响应 _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786 并通过身份验证 test@acme.com
- System.ApplicationException:为 ID 为 'a0162430-eb22-4154-bf59-0ba49bfd473d' 的用户加载外部登录信息时发生意外错误。
- CORS 请求路径:“/Saml2/Acs”来自来源:“https://sso.acme.com”但被忽略,因为路径不是允许的 IdentityServer CORS端点
- LinkLoginCallback 开始
- SAML2 响应的验证条件 _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786
- Http POST 绑定提取消息
- Saml Response _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786 的签名验证已通过
- AuthenticationScheme:"Identity.Application" 已成功通过身份验证。
更新: - 客户发回 Saml 请求说它不是 /Saml2/ACS 的 CORS 请求,因此不明白为什么我们会收到从 Identity Server / Sustainsy
收到的错误最后这个问题的解决方法很简单。
- 我正在尝试使用处理来自 Google、Microsoft of Facebook 的响应的方法来处理 Saml 响应(在
ExternalLoginCallback
内)
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(user.Id);
- 显然,Saml 请求的 ExternalLoginCallback 过程略有不同 - 您需要以下代码:
AuthenticateResult samlResult = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
然后您可以使用
samlResult
中的属性构建一个 以下示例中提供了所有相关代码:
ExternalLoginInfo
对象
- 有趣的是,日志文件仍然打印出 针对路径的 CORS 请求:“/Saml2/Acs” 来自来源:“https://sso.acme.com” 但被忽略了因为路径不适用于允许的 IdentityServer CORS 端点 但这似乎对登录过程没有影响。所以 "red-herring".