예제 #1
0
        public void SignatureFinalRequestTest()
        {
            // Arrange
            var rtsSoapMessageSigned = XDocument.Load(@"Resources\Request25022015.xml");

            var cert = new X509Certificate2(Convert.FromBase64String("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"));

            // Act
            var verified = XmlSignatureUtils.VerifySignature(rtsSoapMessageSigned, cert);

            // Assert
            Assert.IsTrue(verified);
        }
예제 #2
0
        public void SignatureResponseTest()
        {
            // Arrange
            var rtsrSoapMessageSigned = XDocument.Load(@"Resources\Response25022015.xml");

            var cert = new X509Certificate2(Convert.FromBase64String("MIIGRTCCBS2gAwIBAgIEUw8DszANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQGEwJESzESMBAGA1UECgwJVFJVU1QyNDA4MSQwIgYDVQQDDBtUUlVTVDI0MDggU3lzdGVtdGVzdCBYSVggQ0EwHhcNMTQwNTA1MTMzNTU4WhcNMTcwNTA1MTMzNTEyWjCBljELMAkGA1UEBhMCREsxMTAvBgNVBAoMKERpZ2l0YWxpc2VyaW5nc3N0eXJlbHNlbiAvLyBDVlI6MzQwNTExNzgxVDAgBgNVBAUTGUNWUjozNDA1MTE3OC1VSUQ6ODMzODQ5NzAwMAYDVQQDDClEaWdpdGFsaXNlcmluZ3NzdHlyZWxzZW4gLSBOZW1Mb2ctaW4gVGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALnCmDRMztjDckSupQBLcEzrRRJnAFxzEFdB7Cj6ApMQ/YxqKzfL/TSIr3v2mdgQNnsJGz91YbAteDPRHR/K1W3kqoIX/qH2uXDzHK+qi4YD9D8s4MnHAt02x6t0TgKQGjn1XO6lgLQ563DjtgD2fdPm9USV2Lkxe5ofNRG7yvWowBWjXKia8D64k6zSzoHKdPz6GCy9S0NmwIyJE0sJavcfwxT3/ia0g63/xD77SteT4H/OR/DLis7FLnfkLp8yrd5xAk4nEGizmjrg2OVJmIMMPK6PQdw+/lqSdgaPDxMD6yoIwWshux5Rup1+piMLg852odHR6EhUzjEsi9DnWWcCAwEAAaOCAucwggLjMA4GA1UdDwEB/wQEAwIEsDCBlwYIKwYBBQUHAQEEgYowgYcwPAYIKwYBBQUHMAGGMGh0dHA6Ly9vY3NwLnN5c3RlbXRlc3QxOS50cnVzdDI0MDguY29tL3Jlc3BvbmRlcjBHBggrBgEFBQcwAoY7aHR0cDovL3YuYWlhLnN5c3RlbXRlc3QxOS50cnVzdDI0MDguY29tL3N5c3RlbXRlc3QxOS1jYS5jZXIwggEgBgNVHSAEggEXMIIBEzCCAQ8GDSsGAQQBgfRRAgQGAwQwgf0wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cudHJ1c3QyNDA4LmNvbS9yZXBvc2l0b3J5MIHJBggrBgEFBQcCAjCBvDAMFgVEYW5JRDADAgEBGoGrRGFuSUQgdGVzdCBjZXJ0aWZpa2F0ZXIgZnJhIGRlbm5lIENBIHVkc3RlZGVzIHVuZGVyIE9JRCAxLjMuNi4xLjQuMS4zMTMxMy4yLjQuNi4zLjQuIERhbklEIHRlc3QgY2VydGlmaWNhdGVzIGZyb20gdGhpcyBDQSBhcmUgaXNzdWVkIHVuZGVyIE9JRCAxLjMuNi4xLjQuMS4zMTMxMy4yLjQuNi4zLjQuMBwGA1UdEQQVMBOBEW5lbWxvZ2luQGRpZ3N0LmRrMIGpBgNVHR8EgaEwgZ4wPKA6oDiGNmh0dHA6Ly9jcmwuc3lzdGVtdGVzdDE5LnRydXN0MjQwOC5jb20vc3lzdGVtdGVzdDE5LmNybDBeoFygWqRYMFYxCzAJBgNVBAYTAkRLMRIwEAYDVQQKDAlUUlVTVDI0MDgxJDAiBgNVBAMMG1RSVVNUMjQwOCBTeXN0ZW10ZXN0IFhJWCBDQTENMAsGA1UEAwwEQ1JMMjAfBgNVHSMEGDAWgBTMAlUM5IF0ryBU1REUV5yRUjh/oDAdBgNVHQ4EFgQUwm9c3oUHE/zZ/43g4RUhswnMVAowCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEACLh3Ovvljv4b/Ywf/8WxoB2y50Oqt8rpwXZp+no4d5tLqIMTSAlQxL0lAf4Qm4e6tF5m/55+dLwxw5/Dqwa0bQXHt98vJjSBYLQH6rwfDzNmVGimO1n84k4MMYY449ykjqRNDfCS3+5+zV/An4CH9eUhvB0AHHWbD6eALw39sPGxc5kHADTOdJ5SboSm9DHYdLLt9k8HyxrHIkcJApLWPgyFmkE0+8jtuQQluN62F5+j5d53oTKinHEd7adM0ea537vNf5uBGu6h9OTXlhZwM9tlnrsTYQTTAIzdxGPlpD9Zvo5nmJHwILdRonm8rZf3vAm59/U6+Cht4+X2l5zxyg=="));

            // Act
            var verified = XmlSignatureUtils.VerifySignature(rtsrSoapMessageSigned, cert);

            // Assert
            Assert.IsTrue(verified);
        }
예제 #3
0
        public void SignatureTest()
        {
            // Arrange
            var rtsSoapMessageNotSigned = XDocument.Load(@"Resources\RST_Not_Signed.xml");
            var ids  = new[] { "action", "msgid", "to", "sec-ts", "sec-binsectoken", "body" };
            var cert = CertificateUtil.GetCertificate("0E6DBCC6EFAAFF72E3F3D824E536381B26DEECF5");

            // Act
            var rtsSoapMessageSigned = XmlSignatureUtils.SignDocument(rtsSoapMessageNotSigned, ids, cert);

            // Assert
            Assert.IsTrue(XmlSignatureUtils.VerifySignature(rtsSoapMessageSigned, cert));
        }
        public void ModifyMessageAccordingToWsTrust(ref Message response, X509Certificate2 stsCertificate)
        {
            // Convert Message into a XML document that can be manipulated
            var xDocument = ConvertMessageToXml(response);

            // Log RSTR before being manipulated
            Logger.Instance.Trace("RSTR recieved from STS before being manipulated:\n" + xDocument);

            // SOAP 1.1 faults from NemLog-in STS contains two Envelope elements. This hack removes the first element whereafter the .Net framework will see it as a fault.
            RemoveOuterEnvelopeElementIfMessageIsASoapFault(ref xDocument, ref response);

            // Fault response is not SOAP 1.1 compliant. We therefore need to change it so that other channels (e.g. WSTrust channel) are able to read it properly.
            if (response.IsFault)
            {
                // Remove default namespace in order for fault message to be soap 1.1 compliant.
                var namespaceManager = new XmlNamespaceManager(new NameTable());
                namespaceManager.AddNamespace("s", S11Namespace);
                namespaceManager.AddNamespace("wst", Wst13Namespace);
                var envelopeElement = xDocument.XPathSelectElement("/s:Envelope", namespaceManager);
                var xmlnsAttribute  = envelopeElement.Attribute(XName.Get("xmlns"));
                xmlnsAttribute.Remove();

                // faultcode must contain a qualified name. However, NemLog-in has forgotten to specify the wst namespace in order to make the SOAP fault SOAP 1.1 compliant.
                var xmlnsWstAttribute = envelopeElement.Attribute(XNamespace.Xmlns + Wst13Prefix);
                if (xmlnsWstAttribute == null)
                {
                    envelopeElement.Add(new XAttribute(XNamespace.Xmlns + Wst13Prefix, Wst13Namespace));
                }

                // faultcode and faultstring must be in the empty namespace.
                var faultElement     = xDocument.XPathSelectElement("/s:Envelope/s:Body/s:Fault", namespaceManager);
                var faultcodeElement = xDocument.XPathSelectElement("/s:Envelope/s:Body/s:Fault/wst:faultcode",
                                                                    namespaceManager);
                faultcodeElement.Remove();
                var faultstringElement = xDocument.XPathSelectElement("/s:Envelope/s:Body/s:Fault/wst:faultstring",
                                                                      namespaceManager);
                faultstringElement.Remove();
                var newFaultCodeElement = new XElement("faultcode")
                {
                    Value = faultcodeElement.Value
                };
                var newFaultStringElement = new XElement("faultstring")
                {
                    Value = faultstringElement.Value
                };
                faultElement.Add(newFaultCodeElement);
                faultElement.Add(newFaultStringElement);
            }
            // Normal RSTR
            else
            {
                var namespaceManager = new XmlNamespaceManager(new NameTable());
                namespaceManager.AddNamespace("s", S11Namespace);
                namespaceManager.AddNamespace("wsse", Wsse10Namespace);
                namespaceManager.AddNamespace("wsu", WsuNamespace);
                namespaceManager.AddNamespace("wst", Wst13Namespace);
                namespaceManager.AddNamespace("d", XmlDigSigNamespace);
                namespaceManager.AddNamespace("wsa", WsaNamespace);

                // Verify signature before making any modifications
                if (!XmlSignatureUtils.VerifySignature(xDocument, stsCertificate))
                {
                    throw new InvalidOperationException("SOAP signature recieved from STS does not validate!");
                }

                // Expiry time is currently not on the format specified by the spec. The spec says yyyy-MM-ddTHH:mm:ssZ but yyyy-MM-ddTHH:mm:ss.fffZ is currently retrieved.
                // Verify life time of SOAP message
                var messageExpireTimeElement = xDocument.XPathSelectElement("/s:Envelope/s:Header/wsse:Security/wsu:Timestamp/wsu:Expires", namespaceManager);
                var messageExpireZuluTime    = GetPatchedDateTime(messageExpireTimeElement.Value);
                var currentZuluTime          = DateTime.UtcNow;
                if (currentZuluTime >= messageExpireZuluTime)
                {
                    throw new InvalidOperationException("SOAP message has expired. Current Zulu time was: " + currentZuluTime + ", message Zulu expiry time was: " + messageExpireZuluTime);
                }

                // Verify life time of RSTS
                var rstsExpireTimeElement = xDocument.XPathSelectElement("/s:Envelope/s:Body/wst:RequestSecurityTokenResponseCollection/wst:RequestSecurityTokenResponse/wst:Lifetime/wsu:Expires", namespaceManager);

                var rstsExpireZuluTime = GetPatchedDateTime(rstsExpireTimeElement.Value);

                if (currentZuluTime >= rstsExpireZuluTime)
                {
                    throw new InvalidOperationException("RSTS has expired. Current Zulu time was: " + currentZuluTime + ", RSTS Zulu expiry time was: " + rstsExpireZuluTime);
                }

                // Verify replay attack
                var signatureValueElement = xDocument.XPathSelectElement("/s:Envelope/s:Header/wsse:Security/d:Signature/d:SignatureValue", namespaceManager);
                if (ReplyAttackCache.DoesKeyExist(signatureValueElement.Value))
                {
                    var messageIdElement = xDocument.XPathSelectElement("/s:Envelope/s:Header/wsa:MessageID",
                                                                        namespaceManager);
                    throw new InvalidOperationException("Replay attack detected. Response message id: " + messageIdElement.Value);
                }
                else
                {
                    ReplyAttackCache.Set(signatureValueElement.Value, messageExpireZuluTime);
                }

                // response is validated ok
                ManipulateRstrBody(xDocument);
            }

            // Log RSTR before being manipulated
            Logger.Instance.Trace("RSTR recieved from STS after being manipulated:\n" + xDocument);

            // Convert XML back to a Message
            response = ConvertXmlToMessage(response, xDocument);

            // The Security element is only present in succesfull responses.
            if (!response.IsFault)
            {
                // Security header element is marked with the MustUnderstand attribute. Hence, we need to inform the WCF framework that this header element has been taken care of.
                response.Headers.UnderstoodHeaders.Add(
                    response.Headers.Single(x => "Security" == x.Name && Wsse10Namespace == x.Namespace));
            }
        }
예제 #5
0
        public new void ProcessRequest(HttpContext context)
        {
            try
            {
                // ***** RESPONSE *****
                if (!String.IsNullOrEmpty(context.Request[HttpBindingConstants.SAMLResponse]))
                {
                    // Recupera Response
                    string      samlresponse = context.Request[HttpBindingConstants.SAMLResponse];
                    XmlDocument doc          = new XmlDocument();
                    doc.PreserveWhitespace = true;
                    doc.LoadXml(samlresponse);

                    // Verifica Signature do Response
                    if (XmlSignatureUtils.VerifySignature(doc))
                    {
                        SAMLResponse = SAMLUtility.DeserializeFromXmlString <ResponseType>(doc.InnerXml);
                        if (SAMLResponse.Items.Length > 0)
                        {
                            for (int i = 0; i < SAMLResponse.Items.Length; i++)
                            {
                                if (SAMLResponse.Items[i] is AssertionType)
                                {
                                    NameIDType    nameID    = null;
                                    AssertionType assertion = (AssertionType)SAMLResponse.Items[i];
                                    for (int j = 0; j < assertion.Subject.Items.Length; j++)
                                    {
                                        if (assertion.Subject.Items[j] is NameIDType)
                                        {
                                            nameID = (NameIDType)assertion.Subject.Items[j];
                                        }
                                    }
                                    if (nameID != null)
                                    {
                                        SignHelper.AutenticarUsuarioDaRespostaDoSaml(nameID.Value);
                                    }
                                }

                                // Armazena dados do sistema emissor do Request
                                // em Cookie de sistemas autenticados
                                AddSAMLCookie(context);
                            }
                        }
                        context.Response.Redirect(HttpUtility.UrlDecode(context.Request[HttpBindingConstants.RelayState]), false);
                    }
                    else
                    {
                        throw new ValidationException("Não foi possível encontrar assinatura.");
                    }
                }
                // ***** REQUEST *****
                else if (!String.IsNullOrEmpty(context.Request[HttpBindingConstants.SAMLRequest]))
                {
                    throw new NotImplementedException();
                }
                else
                {
                    // Carrega as configurações do ServiceProvider
                    ServiceProvider         config = ServiceProvider.GetConfig();
                    ServiceProviderEndpoint spend  = SAMLUtility.GetServiceProviderEndpoint(config.ServiceEndpoint, SAMLTypeSSO.signon);

                    // Verifica configuração do ServiceProvider para signon
                    if (spend == null)
                    {
                        throw new ValidationException("Não foi possível encontrar as configurações do ServiceProvider para signon.");
                    }

                    // Verifica se usuário está autenticado, caso não envia um Resquest solicitando autenticação
                    if (!UsuarioWebIsValid())
                    {
                        SAMLRequest        = new SAMLAuthnRequest();
                        SAMLRequest.Issuer = config.id;
                        SAMLRequest.AssertionConsumerServiceURL = context.Request.Url.AbsoluteUri;

                        HttpRedirectBinding binding = new HttpRedirectBinding(SAMLRequest, spend.localpath);
                        binding.SendRequest(context, spend.redirectUrl);
                    }
                    else
                    {
                        HttpContext.Current.Response.Redirect(spend.localpath, false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                    }
                }
            }
            catch (ValidationException ex)
            {
                ErrorMessage(ex.Message);
            }
            catch (Exception ex)
            {
                ApplicationWEB._GravaErro(ex);

                ErrorMessage("Não foi possível atender a solicitação.");
            }
        }