protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync()
        {
            SAMLResponseDto samlResponse = null;

            if (Request.Method == "GET")
            {
                samlResponse = SAMLResponseDto.Build(Request.Query.ToDictionary(k => k.Key, k => k.Value.First()));
            }
            else
            {
                samlResponse = SAMLResponseDto.Build(Request.Form.ToDictionary(k => k.Key, k => k.Value.First()));
            }

            try
            {
                var properties = Options.StateDataFormat.Unprotect(samlResponse.RelayState);
                if (properties == null)
                {
                    return(HandleRequestResult.Fail("The state was missing or invalid."));
                }

                var assertion = await Validate(samlResponse, CancellationToken.None);

                var claimsIdentity  = new ClaimsIdentity(BuildClaims(assertion), Scheme.Name);
                var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
                var ticket          = new AuthenticationTicket(claimsPrincipal, properties, Options.SignInScheme);
                return(HandleRequestResult.Success(ticket));
            }
            catch (SamlException ex)
            {
                return(HandleRequestResult.Fail(ex));
            }
        }
        public async virtual Task <AssertionType> Validate(SAMLResponseDto samlResponse, CancellationToken cancellationToken)
        {
            var certificates = await CheckEntityDescriptor(cancellationToken);

            var response = CheckSamlResponse(samlResponse);

            CheckSignature(samlResponse, response, certificates);
            return(response.Content.Items.First(i => i is AssertionType) as AssertionType);
        }
        protected virtual SAMLValidatorResult <ResponseType> CheckSamlResponse(SAMLResponseDto samlResponse)
        {
            var response  = SAMLValidator.CheckSaml <ResponseType>(samlResponse.SAMLResponse, samlResponse.RelayState);
            var assertion = response.Content.Items.FirstOrDefault(i => i is AssertionType) as AssertionType;

            if (assertion == null)
            {
                throw new SamlException(System.Net.HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Responder, Global.MissingAssertion);
            }


            return(response);
        }
        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);
                }
            }
        }