public static AuthenticationResponse Parse()

in wwauth/Google.Solutions.WWAuth/Data/Saml2/AuthenticationResponse.cs [63:169]


        public static AuthenticationResponse Parse(string encodedResponse)
        {
            try
            {
                var xml = Encoding.UTF8.GetString(
                    Convert.FromBase64String(encodedResponse));

                var deserializer = new XmlSerializer(typeof(Saml2Schema.Response));
                var response = (Saml2Schema.Response)deserializer.Deserialize(
                    new StringReader(xml));

                if (response.Version != "2.0")
                {
                    throw new InvalidSamlResponseException(
                        "Unsupported SAML version");
                }
                else if (string.IsNullOrEmpty(response.ID))
                {
                    throw new InvalidSamlResponseException(
                        "Malformed SAML response: Missing required attribute: ID");
                }
                else if (string.IsNullOrEmpty(response.Issuer))
                {
                    throw new InvalidSamlResponseException(
                        "Malformed SAML response: Missing required attribute: Issuer");
                }
                else if (response.IssueInstant == DateTime.MinValue)
                {
                    throw new InvalidSamlResponseException(
                        "Malformed SAML response: Missing required attribute: IssueInstant");
                }
                else if (string.IsNullOrEmpty(response.Destination))
                {
                    throw new InvalidSamlResponseException(
                        "Malformed SAML response: Missing required attribute: Destination");
                }
                else if (response.Status?.StatusCode?.Value == "urn:oasis:names:tc:SAML:2.0:status:Responder" &&
                    string.IsNullOrEmpty(response.Status?.StatusMessage) &&
                    string.IsNullOrEmpty(response.Status.StatusCode?.StatusCode?.Value))
                {
                    throw new InvalidSamlResponseException(
                        $"Server rejected request, possible because of mismatched signing settings");
                }
                else if (response.Status?.StatusCode?.Value !=
                    "urn:oasis:names:tc:SAML:2.0:status:Success")
                {
                    throw new InvalidSamlResponseException(
                        $"Request failed with status code {response.Status?.StatusCode?.Value}\n\n" +
                        $"Details: {response.Status?.StatusMessage ?? "-"}\n" +
                        $"Detail status code {response.Status.StatusCode?.StatusCode?.Value ?? "-"}");
                }

                //
                // There should be either an <Assertion/> or <EncryptedAssertion/> element,
                // but we don't know which.
                //

                var assertionElement = response.Assertion
                    .EnsureNotNull()
                    .FirstOrDefault(n => n.NamespaceURI == "urn:oasis:names:tc:SAML:2.0:assertion");

                switch (assertionElement.Name)
                {
                    case "Assertion":
                        //
                        // Response contains non-encrypted assertion. We can parse
                        // this to extract attributes, etc.
                        //

                        using (var assertionReader = new XmlNodeReader(assertionElement))
                        {
                            var tokenHandler = new Saml2SecurityTokenHandler()
                            {
                                Configuration = new SecurityTokenHandlerConfiguration()
                            };

                            tokenHandler.Configuration.CertificateValidationMode =
                                System.ServiceModel.Security.X509CertificateValidationMode.None;

                            var assertion = new Assertion(
                                (Saml2SecurityToken)tokenHandler.ReadToken(assertionReader),
                                null);

                            return new Saml2ResponseWithPlaintextAssertion(
                                encodedResponse,
                                assertion);
                        }

                    case "EncryptedAssertion":
                        //
                        // Response contains an encrypted assertion. We can't do
                        // much with that.
                        //
                        return new Saml2ResponseWithEncryptedAssertion(
                            response.Issuer,
                            encodedResponse);

                    default:
                        throw new InvalidSamlResponseException(
                            $"SAML Response does not contain an assertion: {assertionElement}");
                }
            }
            catch (InvalidOperationException e)
            {
                throw new InvalidSamlResponseException("Failed to parse SAML respose", e);
            }
        }