Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initiate SingleSignOn by Saml2PostBinding

I am having an issue when using ITfoxtec for ASP.NET Core 3.0.
As context I am trying to establish a connection between a webapplication and a third-party login service. To encapsulate some of the possibilities beforehand, the third-party has access to our metadata-url and configured their services for our webapplication.

Desired user workflow:

  • User enters the webapplication;
  • User clicks a button which redirects the user to the login service;
  • User logs in on the service and redirects back to the given returnURL;
  • Afterwards the webapplication determines permission based on the provided sso-cookie.

Steps taken so far:

  • Added Saml2 section in appsettings.json containing our metadata.xml and issuer. The issuer name equals the given EntityID provided within the metadata.xml. It is made anonymous in the given context, like so:
"Saml2": {
    "IdPMetadata": "wwwroot/SAML/Metadata.xml",
    "Issuer": "myIssuerName",
    "SignatureAlgorithm": "http://www.w3.org/2000/09/xmldsig#rsa-sha1",
    "CertificateValidationMode": "ChainTrust",
    "RevocationMode": "NoCheck",
    "SigningCertificateFile": "\\licenses\\certificate.pfx",
    "SigningCertificatePassword": "password1"
}, 
  • Added Saml2Configuration in startup.cs;
    services
        .Configure<Saml2Configuration>(Configuration.GetSection("Saml2"))
        .Configure<Saml2Configuration>(configuration =>
        {
            configuration.SigningCertificate = CertificateUtil.Load(
                 $"{Environment.WebRootPath}{Configuration["Saml2:SigningCertificateFile"]}",
                 Configuration["Saml2:SigningCertificatePassword"]);
            configuration.AllowedAudienceUris.Add(configuration.Issuer);

            var entityDescriptor = new EntityDescriptor();
                entityDescriptor.ReadIdPSsoDescriptorFromFile(Configuration["Saml2:IdpMetadata"]);

            if (entityDescriptor.IdPSsoDescriptor == null) throw new Exception("Failed to read the metadata.");

            configuration.SignAuthnRequest = true;
            configuration.SingleSignOnDestination = entityDescriptor.IdPSsoDescriptor.SingleSignOnServices
               .Where(ed => ed.Binding.ToString() == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")
               .First().Location;
            configuration.SignatureValidationCertificates.AddRange(entityDescriptor.IdPSsoDescriptor.SigningCertificates);
        }); 
  • Here comes the tricky part; By default the sso initiation does a request with a RedirectBinding which does therefore send a GET request towards the sso service. However, the service I am trying to approach expects a SAMLRequest as a POST request. So I have changed the code by initiating with PostBinding request and afterwards directly submit the form, like so:
    public IActionResult Initiate([FromQuery(Name = "returnUrl")] string returnUrl = "")
    {
        var binding = new Saml2PostBinding();
            binding.SetRelayStateQuery(new Dictionary<string, string> { { "ReturnUrl", returnUrl } });
            binding.Bind(new Saml2AuthnRequest(_saml2configuration)
            {
                ForceAuthn = false,
                IsPassive = false,
                NameIdPolicy = new NameIdPolicy() { AllowCreate = true },
                AssertionConsumerServiceUrl = new Uri("https://localhost:44366/api/Authentication/Process"),
            });

        return binding.ToActionResult();
    } 

Issue:
However, after sending the base64 encoded AuthnRequest as SAML Request, I am receiving a 403 Forbidden from the third-party login. At this stage I am not certain whether is the identity provider not being configured properly or my request lacking something. What am I doing wrong?

Below is the (anonymously made) request headers.
Assume that the SAMLRequest is provided in formdata as base64 encoded.

    :authority: myEntityDescriptorName
    :method: POST
    :path: mySsoURL
    :scheme: https
    accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    accept-encoding: gzip, deflate, br
    accept-language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
    cache-control: no-cache
    content-length: 3582
    content-type: application/x-www-form-urlencoded
    cookie: JSESSIONID=3D5FE88D55674C2F1E3646E6D8A0FFBE
    origin: https://localhost:44366
    pragma: no-cache
    referer: https://localhost:44366/
    sec-fetch-mode: navigate
    sec-fetch-site: cross-site
    sec-fetch-user: ?1
    upgrade-insecure-requests: 1
    user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
like image 895
Lucas van Liere Avatar asked Nov 07 '22 12:11

Lucas van Liere


1 Answers

It is correct to change the Authn Request to a Post binding if that is required.

Your application is a Service Provider (also called Relying Party) which needs to be configured at the Identity Provider with a unique Issuer name.

I think the problem is that the Issuer name you have configured ("Issuer": "myIssuerName") is incorrect. The issuer name should be your Service Providers issuer name, not the Identity Provider Issuer name from the metadata.xml.

like image 89
Anders Revsgaard Avatar answered Dec 16 '22 10:12

Anders Revsgaard