public void TestAuthnRequest() { AuthnRequestType authnRequest = new AuthnRequestType(); authnRequest.ID = "test-id"; authnRequest.AssertionConsumerServiceURL = "http://test.assertion.consumer"; authnRequest.Destination = "http://destination"; authnRequest.ForceAuthn = true; authnRequest.ProtocolBinding = "urn:test:protocol:binding"; authnRequest.Version = "2.0"; authnRequest.IssueInstant = DateTime.Now.ToUniversalTime(); NameIDType issuer = new NameIDType(); issuer.Value = "test-issuer"; authnRequest.Issuer = issuer; NameIDPolicyType nameIdPolicy = new NameIDPolicyType(); nameIdPolicy.AllowCreate = true; nameIdPolicy.AllowCreateSpecified = true; authnRequest.NameIDPolicy = nameIdPolicy; XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("samlp", "urn:oasis:names:tc:SAML:2.0:protocol"); ns.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion"); //ns.Add("ds", "http://www.w3.org/2000/09/xmldsig#"); XmlRootAttribute xRoot = new XmlRootAttribute(); xRoot.ElementName = "AuthnRequest"; xRoot.Namespace = "urn:oasis:names:tc:SAML:2.0:protocol"; XmlSerializer serializer = new XmlSerializer(typeof(AuthnRequestType), xRoot); MemoryStream memoryStream = new MemoryStream(); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); serializer.Serialize(xmlTextWriter, authnRequest, ns); memoryStream = (MemoryStream)xmlTextWriter.BaseStream; string result = new UTF8Encoding().GetString(memoryStream.ToArray()); Console.WriteLine("result: " + result); XmlDocument document = new XmlDocument(); memoryStream.Seek(0, SeekOrigin.Begin); document.Load(memoryStream); String xmlString = document.OuterXml; Console.WriteLine("DOM result: " + xmlString); RSACryptoServiceProvider Key = new RSACryptoServiceProvider(); SignedXml signedXml = new SignedXml(document); signedXml.SigningKey = Key; Signature signature = signedXml.Signature; signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference("#" + authnRequest.ID); XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigExcC14NTransform excC14NTransform = new XmlDsigExcC14NTransform("ds saml samlp"); reference.AddTransform(excC14NTransform); signature.SignedInfo.AddReference(reference); signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); document.DocumentElement.AppendChild(document.ImportNode(xmlDigitalSignature, true)); result = document.OuterXml; Console.WriteLine("result: " + result); XmlTextWriter xmltw = new XmlTextWriter(TestConstants.workDir + "\\test.xml", new UTF8Encoding(false)); document.WriteTo(xmltw); xmltw.Close(); }
/// <summary> /// Generates a SAML v2.0 Authentication Request with HTTP Browser Post Binding. /// The return string containing the request is NOT Base64 encoded. /// </summary> /// <param name="linkIDContext">the linkID authentication/payment configuration</param> /// <returns>SAML request</returns> public static AuthnRequestType generateAuthnRequest(LinkIDAuthenticationContext linkIDContext) { AuthnRequestType authnRequest = new AuthnRequestType(); authnRequest.ForceAuthn = true; authnRequest.ID = Guid.NewGuid().ToString(); authnRequest.Version = "2.0"; authnRequest.IssueInstant = DateTime.UtcNow; NameIDType issuer = new NameIDType(); issuer.Value = linkIDContext.applicationName; authnRequest.Issuer = issuer; NameIDPolicyType nameIdPolicy = new NameIDPolicyType(); nameIdPolicy.AllowCreate = true; nameIdPolicy.AllowCreateSpecified = true; authnRequest.NameIDPolicy = nameIdPolicy; Dictionary <string, string> deviceContextMap = linkIDContext.getDeviceContextMap(); DeviceContextType deviceContext = null; if (null != deviceContextMap && deviceContextMap.Count > 0) { deviceContext = new DeviceContextType(); List <AttributeType> attributes = new List <AttributeType>(); foreach (string deviceContextKey in deviceContextMap.Keys) { string deviceContextValue = deviceContextMap[deviceContextKey]; AttributeType attribute = new AttributeType(); attribute.Name = deviceContextKey; attribute.AttributeValue = new object[] { deviceContextValue }; attributes.Add(attribute); deviceContext.Items = attributes.ToArray(); } } SubjectAttributesType subjectAttributes = null; if (null != linkIDContext.attributeSuggestions && linkIDContext.attributeSuggestions.Count > 0) { subjectAttributes = new SubjectAttributesType(); List <AttributeType> attributes = new List <AttributeType>(); foreach (string attributeName in linkIDContext.attributeSuggestions.Keys) { List <object> values = linkIDContext.attributeSuggestions[attributeName]; AttributeType attribute = new AttributeType(); attribute.Name = attributeName; attribute.AttributeValue = values.ToArray(); attributes.Add(attribute); subjectAttributes.Items = attributes.ToArray(); } } PaymentContextType paymentContextType = null; if (null != linkIDContext.paymentContext) { Dictionary <String, String> paymentContextDict = linkIDContext.paymentContext.toDictionary(); paymentContextType = new PaymentContextType(); List <AttributeType> attributes = new List <AttributeType>(); foreach (string paymentContextKey in paymentContextDict.Keys) { string value = paymentContextDict[paymentContextKey]; AttributeType attribute = new AttributeType(); attribute.Name = paymentContextKey; attribute.AttributeValue = new object[] { value }; attributes.Add(attribute); paymentContextType.Items = attributes.ToArray(); } } CallbackType callbackType = null; if (null != linkIDContext.callback) { Dictionary <String, String> callbackDict = linkIDContext.callback.toDictionary(); callbackType = new CallbackType(); List <AttributeType> attributes = new List <AttributeType>(); foreach (string callbackKey in callbackDict.Keys) { string value = callbackDict[callbackKey]; AttributeType attribute = new AttributeType(); attribute.Name = callbackKey; attribute.AttributeValue = new object[] { value }; attributes.Add(attribute); callbackType.Items = attributes.ToArray(); } } if (null != deviceContext || null != subjectAttributes || null != paymentContextType || null != callbackType) { ExtensionsType extensions = new ExtensionsType(); List <XmlElement> extensionsList = new List <XmlElement>(); if (null != subjectAttributes) { extensionsList.Add(toXmlElement(subjectAttributes)); } if (null != deviceContext) { extensionsList.Add(toXmlElement(deviceContext)); } if (null != paymentContextType) { extensionsList.Add(toXmlElement(paymentContextType)); } if (null != callbackType) { extensionsList.Add(toXmlElement(callbackType)); } extensions.Any = extensionsList.ToArray(); authnRequest.Extensions = extensions; } return(authnRequest); }
/// <summary> /// /// </summary> /// <param name="UUID"></param> /// <param name="Destination"></param> /// <param name="ConsumerServiceURL"></param> /// <param name="certFile"></param> /// <param name="certPassword"></param> /// <param name="storeLocation"></param> /// <param name="storeName"></param> /// <param name="findType"></param> /// <param name="findValue"></param> /// <param name="signatureType"></param> /// <returns></returns> public static string BuildPostSamlRequest(string UUID, string Destination, string ConsumerServiceURL, int SecurityLevel, string certFile, string certPassword, StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue, SigningHelper.SignatureType signatureType, string IdentityProvider, int Enviroment) { AuthnRequestType MyRequest = new AuthnRequestType { ID = UUID, Version = "2.0" }; DateTime now = DateTime.UtcNow; DateTime after = now.AddMinutes(10); string nowString = String.Empty; string afterString = String.Empty; if (IdentityProvider.Contains("sielte")) { // SIELTE nowString = now.AddMinutes(-2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); afterString = after.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); } else { // POSTE - TIM - INFOCERT nowString = now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); afterString = after.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); } MyRequest.IssueInstant = nowString; if (SecurityLevel > 1) { MyRequest.ForceAuthn = true; MyRequest.ForceAuthnSpecified = true; } MyRequest.Destination = Destination; MyRequest.AssertionConsumerServiceIndex = (ushort)Enviroment; MyRequest.AssertionConsumerServiceIndexSpecified = true; MyRequest.AttributeConsumingServiceIndex = 1; MyRequest.AttributeConsumingServiceIndexSpecified = true; NameIDType IssuerForRequest = new NameIDType { Value = ConsumerServiceURL.Trim(), Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity", NameQualifier = ConsumerServiceURL }; MyRequest.Issuer = IssuerForRequest; NameIDPolicyType NameIdPolicyForRequest = new NameIDPolicyType { Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", AllowCreate = true, AllowCreateSpecified = true }; MyRequest.NameIDPolicy = NameIdPolicyForRequest; ConditionsType Conditional = new ConditionsType(); if (IdentityProvider.Contains("sielte")) { // SIELTE Conditional.NotBefore = nowString; } else { // POSTE - TIM - INFOCERT Conditional.NotBefore = now.AddMinutes(-2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); } Conditional.NotBeforeSpecified = true; Conditional.NotOnOrAfter = afterString; Conditional.NotOnOrAfterSpecified = true; MyRequest.Conditions = Conditional; RequestedAuthnContextType RequestedAuthn = new RequestedAuthnContextType { Comparison = AuthnContextComparisonType.minimum, ComparisonSpecified = true, ItemsElementName = new ItemsChoiceType7[] { ItemsChoiceType7.AuthnContextClassRef }, Items = new string[] { "https://www.spid.gov.it/SpidL" + SecurityLevel.ToString() } }; MyRequest.RequestedAuthnContext = RequestedAuthn; 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(MyRequest.GetType()); StringWriter stringWriter = new StringWriter(); XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8 }; XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings); responseSerializer.Serialize(responseWriter, MyRequest, ns); responseWriter.Close(); string samlString = string.Empty; samlString = stringWriter.ToString(); 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; X509Certificate2Collection coll = store.Certificates.Find(findType, findValue.ToString(), false); if (coll.Count < 1) { throw new ArgumentException("Unable to locate certificate"); } cert = coll[0]; store.Close(); } XmlElement signature = SigningHelper.SignDoc(doc, cert, UUID); 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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + responseStr); }