Beispiel #1
0
        /// <summary>
        /// Accepts SAML Response, serializes it to XML and signs using the supplied certificate
        /// </summary>
        /// <param name="Response">SAML 2.0 Response</param>
        /// <param name="SigningCert">X509 certificate</param>
        /// <returns>XML Document with computed signature</returns>
        private static XmlDocument SerializeAndSignSAMLResponse(ResponseType Response, X509Certificate2 SigningCert)
        {
            // Set serializer and writers for action
            XmlSerializer responseSerializer = new XmlSerializer(Response.GetType());
            StringWriter  stringWriter       = new StringWriter();
            XmlWriter     responseWriter     = XmlTextWriter.Create(stringWriter, new XmlWriterSettings()
            {
                OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8
            });

            responseSerializer.Serialize(responseWriter, Response);
            responseWriter.Close();
            XmlDocument xmlResponse = new XmlDocument();

            xmlResponse.LoadXml(stringWriter.ToString());

            // Set the namespace for prettier and more consistent XML
            XmlNamespaceManager ns = new XmlNamespaceManager(xmlResponse.NameTable);

            ns.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");

            CertificateUtility.AppendSignatureToXMLDocument(ref xmlResponse, "#" + ((AssertionType)Response.Items[0]).ID, SigningCert);

            return(xmlResponse);
        }
        /// <summary>
        /// Accepts SAML Response, serializes it to XML and signs using the supplied certificate
        /// </summary>
        /// <param name="Response">SAML 2.0 Response</param>
        /// <param name="partnerSP"></param>
        /// <returns>Serialized XML Document with computed signature as byte array.</returns>
        private static byte[] SerializeAndSignSAMLResponse(ResponseType Response, string partnerSP)
        {
            // saml.config contains relative paths not virtual
            var signatureCertificatePath     = HostingEnvironment.MapPath("~/" + SAMLConfiguration.Current.IdentityProviderConfiguration.CertificateFile);
            var signaruteCertificatePassword = SAMLConfiguration.Current.IdentityProviderConfiguration.CertificatePassword;
            var encryptionKeyPath            = HostingEnvironment.MapPath("~/" + SAMLConfiguration.Current.GetPartnerServiceProvider(partnerSP).CertificateFile);

            using (var stream = new MemoryStream())
            {
                var ns = new XmlSerializerNamespaces();
                // namespace prefixes so that output layout is like in their sample (SAML_Response_Unencoded_IWS_Working.xml)
                ns.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
                ns.Add("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");

                var responseSerializer = new XmlSerializer(Response.GetType());
                responseSerializer.Serialize(stream, Response, ns);

                stream.Seek(0, SeekOrigin.Begin);
                FXMLDocument.LoadFromStream(stream);
            }

            SBUtils.Unit.SetLicenseKey(File.ReadAllText(HostingEnvironment.MapPath("~/App_Data/eldos-key.txt")));

            // Assertion signature
            var assertionToSign = FXMLDocument.FindNode("saml2:Assertion", true);

            SignElement(signatureCertificatePath, signaruteCertificatePassword, assertionToSign);
            Trace.Write(DateTime.Now.ToShortTimeString() + ": SAML plain body:" + assertionToSign.OwnerDocument.OuterXML);
            // Assertion encryption
            EncryptAssertion(encryptionKeyPath, assertionToSign);
            // Response signature
            var responseToSign = FXMLDocument.FindNode("saml2p:Response", true);

            SignElement(signatureCertificatePath, signaruteCertificatePassword, responseToSign);

            using (var stream = new MemoryStream())
            {
                FXMLDocument.SaveToStream(stream, SBXMLDefs.Unit.xcmExclCanonComment, new SBXMLCharsets.TElXMLUTF8Codec {
                    WriteBOM = false
                });
                return(stream.ToArray());
            }
        }
Beispiel #3
0
        public static string SerializeAndSignSAMLResponse(ResponseType Response)
        {
            // Set serializer and writers for action
            XmlSerializer responseSerializer = new XmlSerializer(Response.GetType());
            StringWriter  stringWriter       = new StringWriter();
            XmlWriter     responseWriter     = XmlTextWriter.Create(stringWriter, new XmlWriterSettings()
            {
                OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8
            });

            responseSerializer.Serialize(responseWriter, Response);
            responseWriter.Close();
            XmlDocument xmlResponse = new XmlDocument();

            xmlResponse.LoadXml(stringWriter.ToString());
            XmlElement elementToEncrypt = xmlResponse.GetElementsByTagName("saml:Assertion")[0] as XmlElement;

            /////////////////////////////////////////////////////
            // Create a new instance of the EncryptedXml class //
            // and use it to encrypt the XmlElement with the   //
            // X.509 Certificate.                              //
            /////////////////////////////////////////////////////

            EncryptedXml eXml = new EncryptedXml();

            // Encrypt the element.
            X509Certificate2 certificate = new X509Certificate2(@"C:\Program Files\OpenSSL-Win64\bin\certificate.crt");//SAMLConfiguration.Current.CertificateManager.GetPartnerCertificate(partnerSP);
            //X509Certificate2 certificate2 = new X509Certificate2(@"C:\Program Files\OpenSSL-Win64\bin\certificate1.pfx", "VSIP@ssw0rd");
            //certificate.Import(@"C:\Program Files\OpenSSL-Win64\bin\certificate.crt");
            EncryptedData edElement = eXml.Encrypt(elementToEncrypt, certificate);

            XmlElement encryptedAssertion = xmlResponse.CreateElement("saml", "EncryptedAssertion", "urn:oasis:names:tc:SAML:2.0:assertion");

            EncryptedXml.ReplaceElement(encryptedAssertion, edElement, true);

            ///////////////////////////////////////////////////////
            // Replace the element from the original XmlDocument //
            // object with the EncryptedData element.            //
            ///////////////////////////////////////////////////////
            xmlResponse.GetElementsByTagName("Response")[0].ReplaceChild(encryptedAssertion, elementToEncrypt);

            return(xmlResponse.OuterXml);
        }
Beispiel #4
0
        /// <summary>
        /// GetPostSamlResponse - Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="domain">Domain</param>
        /// <param name="subject">Subject</param>
        /// <param name="storeLocation">Certificate Store Location</param>
        /// <param name="storeName">Certificate Store Name</param>
        /// <param name="findType">Certificate Find Type</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="findValue">Certificate Find Value</param>
        /// <param name="certFile">Certificate File (used instead of the above Certificate Parameters)</param>
        /// <param name="certPassword">Certificate Password (used instead of the above Certificate Parameters)</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <param name="signatureType">Whether to sign Response or Assertion</param>
        /// <returns>A base64Encoded string with a SAML response.</returns>
        public static string GetPostSamlResponse(string recipient, string issuer, string domain, string subject,
                                                 StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                 Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString();
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;
            settings.Encoding           = Encoding.UTF8;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            string samlString = string.Empty;



            AssertionType assertionType = SamlHelper.CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\"",
                                                          DateTime.UtcNow.AddMinutes(5), recipient));

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                cert = new X509Certificate2(certFile, certPassword);
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue, true);
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature =
                SigningHelper.SignDoc(doc, cert, "ID",
                                      (signatureType == SigningHelper.SignatureType.Response || signatureType == SigningHelper.SignatureType.TestVU475445) ? response.ID : assertionType.ID);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[1]);

            if (SamlHelper.Logger.IsDebugEnabled)
            {
                SamlHelper.Logger.DebugFormat(
                    "Saml Assertion before encoding = {0}",
                    doc.OuterXml.ToString());
            }

            string responseStr = doc.OuterXml;

            // 2018Ma06 Special Post-signature Maniuplation postsignature to inject comment into subject.
            if (signatureType == SigningHelper.SignatureType.TestVU475445)
            {
                string sub        = subject.Trim();
                int    half       = sub.Length / 2;
                string firstHalf  = sub.Substring(0, half);
                string secondHalf = sub.Substring(half);
                responseStr = responseStr.Replace(sub, firstHalf + "<!--VU475445-->" + secondHalf);
                int breaker = 1;
            }


            byte[] base64EncodedBytes =
                Encoding.UTF8.GetBytes(responseStr);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }
Beispiel #5
0
        /// <summary>
        /// Accepts SAML Response, serializes it to XML and signs using the supplied certificate
        /// </summary>
        /// <param name="Response">SAML 2.0 Response</param>
        /// <param name="SigningCert">X509 certificate</param>
        /// <returns>XML Document with computed signature</returns>
        private static XmlDocument SerializeAndSignSAMLResponse(ResponseType Response, string partnerSP)
        {
            // Set serializer and writers for action
            XmlSerializer responseSerializer = new XmlSerializer(Response.GetType());
            StringWriter  stringWriter       = new StringWriter();
            XmlWriter     responseWriter     = XmlTextWriter.Create(stringWriter, new XmlWriterSettings()
            {
                OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8
            });

            responseSerializer.Serialize(responseWriter, Response);
            responseWriter.Close();
            XmlDocument xmlResponse = new XmlDocument();

            xmlResponse.LoadXml(stringWriter.ToString());
            XmlElement elementToEncrypt = xmlResponse.GetElementsByTagName("saml:Assertion")[0] as XmlElement;

            //////////////////////////////////////////////////
            // Create a new instance of the EncryptedXml class
            // and use it to encrypt the XmlElement with the
            // X.509 Certificate.
            //////////////////////////////////////////////////

            EncryptedXml eXml = new EncryptedXml();

            // Encrypt the element.
            var           certificate = SAMLConfiguration.Current.CertificateManager.GetPartnerCertificate(partnerSP);
            EncryptedData edElement   = eXml.Encrypt(elementToEncrypt, certificate);

            XmlElement encryptedAssertion = xmlResponse.CreateElement("saml2", "EncryptedAssertion", "urn:oasis:names:tc:SAML:2.0:assertion");

            EncryptedXml.ReplaceElement(encryptedAssertion, edElement, true);


            ////////////////////////////////////////////////////
            // Replace the element from the original XmlDocument
            // object with the EncryptedData element.
            ////////////////////////////////////////////////////
            xmlResponse.GetElementsByTagName("Response")[0].ReplaceChild(encryptedAssertion, elementToEncrypt);

            //Get the X509 info
            XmlElement issuerSerialElement = xmlResponse.CreateElement("ds", "X509IssuerSerial", SignedXml.XmlDsigNamespaceUrl);
            XmlElement issuerNameElement   = xmlResponse.CreateElement("ds", "X509IssuerName", SignedXml.XmlDsigNamespaceUrl);

            issuerNameElement.AppendChild(xmlResponse.CreateTextNode(certificate.IssuerName.Name));
            issuerSerialElement.AppendChild(issuerNameElement);
            XmlElement serialNumberElement = xmlResponse.CreateElement("ds", "X509SerialNumber", SignedXml.XmlDsigNamespaceUrl);

            serialNumberElement.AppendChild(xmlResponse.CreateTextNode(certificate.SerialNumber));
            issuerSerialElement.AppendChild(serialNumberElement);

            // Set requested namespaces
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["EncryptedData"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["EncryptionMethod"].Prefix           = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["KeyInfo"].Prefix                    = "ds";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["EncryptedKey"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["EncryptionMethod"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["CipherData"].Prefix       = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["xenc:CipherData"]["CipherValue"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["KeyInfo"].Prefix = "ds";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["X509Data"].Prefix = "ds";
            // We don't need this for MagnaCare
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["ds:X509Data"].RemoveChild(xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["ds:X509Data"]["X509Certificate"]);
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["CipherData"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["xenc:CipherData"]["CipherValue"].Prefix = "xenc";

            //Add X509 Issuer Info
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["ds:X509Data"].AppendChild(issuerSerialElement);

            // Set the namespace for prettire and more consistent XML
            var ns = new XmlNamespaceManager(xmlResponse.NameTable);

            ns.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
            ns.AddNamespace("xenc", "http://www.w3.org/2001/04/xmlenc#");

            CertificateUtility.AppendSignatureToXMLDocument(ref xmlResponse, "#" + ((AssertionType)Response.Items[0]).ID);

            return(xmlResponse);
        }
Beispiel #6
0
        public static XmlElement GetSignature(string recipient, string issuer, string domain, string subject,
                                              StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                              Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString();
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;
            settings.Encoding           = Encoding.UTF8;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            string samlString = string.Empty;

            AssertionType assertionType = CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\"",
                                                          DateTime.UtcNow.AddMinutes(5), recipient));

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            cert = new X509Certificate2(certFile, certPassword);

            XmlElement signature =
                SigningHelper.SignDoc(doc, cert, "ID",
                                      signatureType == SigningHelper.SignatureType.Response ? response.ID : assertionType.ID);

            return(signature);
        }
Beispiel #7
0
        /// <summary>
        /// GetPostSamlResponse - Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="domain">Domain</param>
        /// <param name="subject">Subject</param>
        /// <param name="storeLocation">Certificate Store Location</param>
        /// <param name="storeName">Certificate Store Name</param>
        /// <param name="findType">Certificate Find Type</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="findValue">Certificate Find Value</param>
        /// <param name="certFile">Certificate File (used instead of the above Certificate Parameters)</param>
        /// <param name="certPassword">Certificate Password (used instead of the above Certificate Parameters)</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <param name="signatureType">Whether to sign Response or Assertion</param>
        /// <returns>A base64Encoded string with a SAML response.</returns>
        public static string BuildPostSamlResponse(string recipient, string issuer, string domain, string subject,
                                                   StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                   Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType
            {
                // Response Main Area
                ID           = "_" + Guid.NewGuid().ToString(),
                Destination  = recipient,
                Version      = "2.0",
                IssueInstant = DateTime.UtcNow
            };

            NameIDType issuerForResponse = new NameIDType
            {
                Value = issuer.Trim()
            };

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType
            {
                StatusCode = new StatusCodeType()
            };

            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
            ns.Add("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");

            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                Indent             = true,
                Encoding           = Encoding.UTF8
            };

            XmlWriter responseWriter = XmlWriter.Create(stringWriter, settings);

            string samlString = string.Empty;

            AssertionType assertionType = Saml2Helper.CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response, ns);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\"",
                                                          DateTime.UtcNow.AddMinutes(5), recipient));

            samlString = samlString.Replace("<saml2:Assertion ", "<saml2:Assertion xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" ");

            samlString = samlString.Replace("<saml2:AuthnContextClassRef>AuthnContextClassRef</saml2:AuthnContextClassRef>", "<saml2:AuthnContextClassRef>" + issuer + "</saml2:AuthnContextClassRef>");

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                cert = new X509Certificate2(certFile, certPassword);
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                X509Certificate2Collection CertCol = store.Certificates;

                //foreach (X509Certificate2 c in CertCol)
                //{
                //    if (c.Subject.Contains(findValue.ToString()))
                //    {
                //        cert = c;
                //        break;
                //    }
                //}

                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue.ToString(), false);

                //if (cert == null)
                //{
                //    throw new ArgumentException("Unable to locate certificate");
                //}
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature = SigningHelper.SignDoc(doc, cert, response.ID);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[1]);

            string responseStr = doc.OuterXml;

            byte[] base64EncodedBytes =
                Encoding.UTF8.GetBytes(responseStr);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }
        /// <summary>
        /// GetPostSamlResponse - Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="domain">Domain</param>
        /// <param name="subject">Subject</param>
        /// <param name="storeLocation">Certificate Store Location</param>
        /// <param name="storeName">Certificate Store Name</param>
        /// <param name="findType">Certificate Find Type</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="findValue">Certificate Find Value</param>
        /// <param name="certFile">Certificate File (used instead of the above Certificate Parameters)</param>
        /// <param name="certPassword">Certificate Password (used instead of the above Certificate Parameters)</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <param name="signatureType">Whether to sign Response or Assertion</param>
        /// <returns>A base64Encoded string with a SAML response.</returns>
        public static string GetPostSamlResponse(string recipient, string issuer, string subject, string audience, string requestid, string nameIdPolicyFormat,
                                                 StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                 Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType, Models.IdPOptionsModel options)
        {
            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString("N");
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;
            response.InResponseTo = requestid;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            if (options.UseNamespaces)
            {
                ns.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
                ns.Add("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");
                ns.Add("ds", "http://www.w3.org/2000/09/xmldsig#");
            }
            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.Encoding           = Encoding.UTF8;
            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            string samlString = string.Empty;

            AssertionType assertionType = SamlHelper.CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), subject.Trim(), audience.Trim(), nameIdPolicyFormat, attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response, ns);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\" InResponseTo=\"{2:D}\" ",
                                                          DateTime.UtcNow.AddMinutes(5), recipient, requestid));

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            //doc.LoadXml(samlString);
            byte[] samlBytes = Encoding.UTF8.GetBytes(samlString);
            var    ms        = new MemoryStream(samlBytes);

            doc.Load(ms);

            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                try
                {
                    cert = new X509Certificate2(certFile, certPassword);
                }
                catch (Exception ex)
                {
                    ;
                }
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue, false);
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature =
                SigningHelper.SignDoc(doc, cert, "ID",
                                      signatureType == SigningHelper.SignatureType.Response ? response.ID : assertionType.ID,
                                      options);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[1]);

            if (SamlHelper.Logger.IsDebugEnabled)
            {
                SamlHelper.Logger.DebugFormat(
                    "Saml Assertion before encoding = {0}",
                    doc.OuterXml.ToString());
            }
            //string responseStr = doc.OuterXml;

            //byte[] base64EncodedBytes =
            //    Encoding.UTF8.GetBytes(responseStr);

            if (options.IncludeXmlDeclaration)
            {
                //Create an XML declaration.
                XmlDeclaration xmldecl;
                xmldecl = doc.CreateXmlDeclaration("1.0", "UTF-8", "no");
                //Add the new node to the document.
                XmlElement root = doc.DocumentElement;
                doc.InsertBefore(xmldecl, root);
            }

            byte[] base64EncodedBytes = Encoding.UTF8.GetBytes(doc.OuterXml);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }
Beispiel #9
0
        /// <summary>
        /// Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="subject">Subject</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="certPassword">Certificate Password</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <returns></returns>
        public static string GetPostSamlResponse(string recipient, string issuer, string domain, string subject,
                                                 StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                 Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType();

            // Create Response
            response.ResponseID = "_" + Guid.NewGuid().ToString();

            response.MajorVersion = "1";
            response.MinorVersion = "1";
            response.IssueInstant = System.DateTime.UtcNow;
            response.Recipient    = recipient;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = new XmlQualifiedName("Success", "urn:oasis:names:tc:SAML:1.0:protocol");

            response.Status = status;

            // Create Assertion
            AssertionType assertionType = SamlHelper.CreateSaml11Assertion(
                issuer.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Assertion = new AssertionType[] { assertionType };

            //Serialize
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("samlp", "urn:oasis:names:tc:SAML:1.0:protocol");
            ns.Add("saml", "urn:oasis:names:tc:SAML:1.0:assertion");
            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());
            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;
            settings.Encoding           = Encoding.UTF8;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            responseSerializer.Serialize(responseWriter, response, ns);
            responseWriter.Close();

            string samlString = stringWriter.ToString();

            stringWriter.Close();
            // Sign the document
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                cert = new X509Certificate2(certFile, certPassword);
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue, true);
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }
            XmlElement signature = SigningHelper.SignDoc(
                doc, cert, "ResponseID", response.ResponseID);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[0]);

            if (SamlHelper.Logger.IsDebugEnabled)
            {
                SamlHelper.Logger.DebugFormat(
                    "Saml Assertion before encoding = {0}",
                    doc.OuterXml.ToString());
            }
            // Base64Encode and URL Encode
            byte[] base64EncodedBytes =
                Encoding.UTF8.GetBytes(doc.OuterXml);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }