Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
940 stars 606 forks source link

KeyNotFoundException: No Idp with entity id "" found. #1441

Closed talessio-mmehl closed 3 months ago

talessio-mmehl commented 4 months ago

Hello,

we're currently working on an ASP.NET Core web app (.NET 8.0) and Sustainsys.Saml2 version 2.9.2 and Sustainsys.Saml2.AspNetCore2 2.9.2 nuget packages.

In Program.cs we have added:

builder.Services.AddAuthentication(opt =>
{
    opt.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    opt.DefaultChallengeScheme = Saml2Defaults.Scheme;
})
.AddCookie()
.AddSaml2(opt =>
{
    opt.SPOptions.EntityId = new EntityId("https://localhost:7031/Saml2");
    opt.SPOptions.ServiceCertificates.Add(new X509Certificate2("Certificates\\saml.pfx"));
    opt.IdentityProviders.Add(new IdentityProvider(
        new EntityId("https://sso.test.com"),
        opt.SPOptions)
    {
        MetadataLocation = "https://sso.test.com/metadata.asp"
    });
});

Authentication requests are sent correctly, traces look good, however, after receiving back the SAML response, we receive this error:

KeyNotFoundException: The given key 'Sustainsys.Saml2.Metadata.EntityId' was not present in the dictionary.
System.Collections.Generic.Dictionary<TKey, TValue>.get_Item(TKey key)
Sustainsys.Saml2.Configuration.IdentityProviderDictionary.get_Item(EntityId entityId)

KeyNotFoundException: No Idp with entity id "" found.
Sustainsys.Saml2.Configuration.IdentityProviderDictionary.get_Item(EntityId entityId)
Sustainsys.Saml2.Configuration.Saml2Notifications+<>c.<.ctor>b__84_18(EntityId ei, IDictionary<string, string> rd, IOptions opt)
Sustainsys.Saml2.WebSso.AcsCommand.GetIdpContext(XmlElement xml, HttpRequestData request, IOptions options)
Sustainsys.Saml2.WebSso.AcsCommand.Run(HttpRequestData request, IOptions options)
Sustainsys.Saml2.AspNetCore2.Saml2Handler.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

How can we adjust this to get the correct mapping?

Cheers and thanks, Michael

AndersAbel commented 4 months ago

Could it be that there is no Issuer in the Saml Response? It is valid to not have an issuer if the signature is no the assertion level. However, this library (version 1-2) expects an issuer to be present.

To workaround you can override the GetIdentityProvider notification. The EntityId is in the dictionary so you can use that to get the right entry from the IdentityProviders collection.

talessio-mmehl commented 4 months ago

Hi,

thanks for the response. I identified the root cause a bit more. Obviously, the issuer is mentioned in the assertion, but not directly in the response. Is there a more general approach to fix that issue?

image

Cheers, Michael

AndersAbel commented 4 months ago

The issuer element is optional on the Saml response level, but the v1+v2 versions of this library requires it to be present. V3 (work in progress) only requires an issuer on the assertion. If the response is signed, the standard still requires an issuer on the response.