- I am using Identity Server 4 with AspNetIdentity.
- I have added a SAML Authentication provider using Sustainsys.
- I can successfully login using a local account.
- I want to link the SAML Authentication provider to my local account. I follow the process to link an external and social login (as I have successfully done with Google, Microsoft & Facebook) - link is https://identity.domain.com/Manage/ExternalLogins
- I now have an option to link a SAML2 service
- I can successfully link out to the external SSO and authenticate; I am then redirected back to https://identity.domain.com/Manage/LinkLoginCallback but the code is failing in the ManageController at the following point:
Null is being returned for GetExternalLoginInfoAsync. The user.Id is correct and exists in the database.
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}'.");
}
From what I can see there should be a collection of properties that have been returned by the external SAML provider to:
public async Task<IActionResult> LinkLogin(string provider)
I suspect that the issue may be something related to the CORS error however I have not successfully addressed this error even though I've added the following lines in startup.cs as per documentation at 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);
Here is the log of debugging information:
- LinkLogin redirectUrl: /Manage/LinkLoginCallback
- AuthenticationScheme: "Identity.Application" was successfully authenticated.
- Extracted SAML assertion _ea533182b0cb1781868a660af48ced3529d568
- AuthenticationScheme: "Identity.Application" was successfully authenticated.
- LinkLoginCallback User.Id: a0162430-eb22-4154-bf59-0ba49bfd473d
- Successfully processed SAML response _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786 and authenticated test@acme.com
- System.ApplicationException: Unexpected error occurred loading external login info for user with ID 'a0162430-eb22-4154-bf59-0ba49bfd473d'.
- CORS request made for path: "/Saml2/Acs" from origin: "https://sso.acme.com" but was ignored because path was not for an allowed IdentityServer CORS endpoint
- LinkLoginCallback starting
- Validated conditions for SAML2 Response _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786
- Http POST binding extracted message
- Signature validation passed for Saml Response _402e6060e55e8e5d3b05f52ff5e5d2d7d4d786
- AuthenticationScheme: "Identity.Application" was successfully authenticated.
UPDATE:
- Customer sending back Saml request says it is not a CORS request to /Saml2/ACS and therefore doesn't understand why we would be getting the error we are getting from Identity Server / Sustainsy
The solution to this problem was simple in the end.
- I was trying to process a Saml response (within
ExternalLoginCallback
) using the approach to process a response from Google, Microsoft of Facebook
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(user.Id);
- It's apparent that the process for ExternalLoginCallback for a Saml request is slightly different - you need the following code:
AuthenticateResult samlResult = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
https://github.com/Sustainsys/Saml2/blob/netstandard/Samples/SampleIdentityServer4/Quickstart/Account/AccountController.cs
- Interestingly, the log files still print out a CORS request made for path: "/Saml2/Acs" from origin: "https://sso.acme.com" but was ignored because path was not for an allowed IdentityServer CORS endpoint however this appears to have had no impact on the sign-in process. So a "red-herring".