protected virtual async Task <RelyingPartyAggregate> CheckRelyingParty(AuthnRequestType authnRequest, CancellationToken cancellationToken)
        {
            var relyingParty = await _relyingPartyRepository.Get(authnRequest.Issuer.Value, cancellationToken);

            if (relyingParty == null)
            {
                throw new SamlException(HttpStatusCode.NotFound, Saml.Constants.StatusCodes.Requester, string.Format(Global.UnknownIssuer, nameof(authnRequest.Issuer.Value)));
            }

            if (await relyingParty.GetAuthnRequestsSigned(_entityDescriptorStore, cancellationToken))
            {
                var certificates = await relyingParty.GetSigningCertificates(_entityDescriptorStore, cancellationToken);

                foreach (var certificate in certificates)
                {
                    if (SignatureHelper.CheckSignature(authnRequest.SerializeToXmlElement(), certificate))
                    {
                        return(relyingParty);
                    }
                }

                throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Requester, Global.BadAuthnRequestSignature);
            }

            if ((await relyingParty.GetAssertionLocation(_entityDescriptorStore, Saml.Constants.Bindings.HttpRedirect, cancellationToken)) == null)
            {
                throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.UnsupportedBinding, Global.BadSPAssertionLocation);
            }

            return(relyingParty);
        }
Exemplo n.º 2
0
        public void When_Build_And_Sign_AuthnRequest()
        {
            var payload     = File.ReadAllBytes(Path.Combine(Directory.GetCurrentDirectory(), "localhost.pfx"));
            var certificate = new X509Certificate2(payload, "password");
            // https://en.wikipedia.org/wiki/SAML_2.0
            // https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
            // https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf
            // https://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf
            // https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
            // http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml2-holder-of-key-cs-02.html
            // https://developers.onelogin.com/saml/examples/authnrequest : explains how to sign AuthnRequest
            // https://dtservices.bosa.be/sites/default/files/content/download/files/fas_saml_integration_guide_v0.51_1.pdf
            // ARRANGE
            var builder = AuthnRequestBuilder.New("SP")
                          .SetIssuer(Constants.NameIdentifierFormats.EntityIdentifier, "urn:sp");

            // ACT
            var authnRequest = builder.SignAndBuild(certificate, SignatureAlgorithms.RSASHA256, CanonicalizationMethods.C14);

            // ASSERT
            Assert.True(SignatureHelper.CheckSignature(authnRequest, certificate));
        }
        protected virtual void CheckSignature(SAMLResponseDto samlResponse, SAMLValidatorResult <ResponseType> response, IEnumerable <X509Certificate2> certificates)
        {
            if (string.IsNullOrWhiteSpace(samlResponse.SAMLResponse))
            {
                throw new SamlException(System.Net.HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Responder, string.Format(Global.MissingParameter, "SAMLResponse"));
            }

            if (Options.WantsResponseSigned)
            {
                if (!certificates.Any(certificate => SignatureHelper.CheckSignature(response.Document.DocumentElement, certificate)))
                {
                    throw new SamlException(System.Net.HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Responder, Global.BadSamlResponseSignature);
                }
            }

            if (Options.WantAssertionSigned)
            {
                var assertion = response.Document.GetElementsByTagName("Assertion", "urn:oasis:names:tc:SAML:2.0:assertion");
                if (!certificates.Any(certificate => SignatureHelper.CheckSignature(assertion[0] as XmlElement, certificate)))
                {
                    throw new SamlException(System.Net.HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Responder, Global.BadAssertionSignature);
                }
            }

            if (!string.IsNullOrWhiteSpace(samlResponse.SigAlg))
            {
                var query  = samlResponse.ToQuery(false);
                var sig    = Constants.MappingStrToSignature[samlResponse.SigAlg];
                var hashed = Hash.Compute(query, sig);
                if (!certificates.Any(certificate =>
                {
                    var rsa = certificate.GetRSAPublicKey();
                    return(rsa.VerifyHash(hashed, Convert.FromBase64String(samlResponse.Signature), Constants.MappingSignatureAlgToHash[sig], RSASignaturePadding.Pkcs1));
                }))
                {
                    throw new SamlException(System.Net.HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Responder, Global.BadSignature);
                }
            }
        }