/// <summary> /// Build a signed SAML authentication request. /// </summary> /// <param name="uuid"></param> /// <param name="destination"></param> /// <param name="consumerServiceURL"></param> /// <param name="securityLevel"></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="identityProvider"></param> /// <param name="enviroment"></param> /// <returns>Returns a Base64 Encoded String of the SAML request</returns> public static string BuildAuthnPostRequest(string uuid, string destination, string consumerServiceURL, int securityLevel, X509Certificate2 certificate, IdentityProvider identityProvider, int enviroment) { if (string.IsNullOrWhiteSpace(uuid)) { throw new ArgumentNullException("The uuid parameter can't be null or empty."); } if (string.IsNullOrWhiteSpace(destination)) { throw new ArgumentNullException("The destination parameter can't be null or empty."); } if (string.IsNullOrWhiteSpace(consumerServiceURL)) { throw new ArgumentNullException("The consumerServiceURL parameter can't be null or empty."); } if (certificate == null) { throw new ArgumentNullException("The certificate parameter can't be null."); } if (identityProvider == null) { throw new ArgumentNullException("The identityProvider parameter can't be null."); } if (enviroment < 0) { throw new ArgumentNullException("The enviroment parameter can't be less than zero."); } DateTime now = DateTime.UtcNow; AuthnRequestType authnRequest = new AuthnRequestType { ID = "_" + uuid, Version = "2.0", IssueInstant = identityProvider.Now(now), Destination = destination, AssertionConsumerServiceIndex = (ushort)enviroment, AssertionConsumerServiceIndexSpecified = true, AttributeConsumingServiceIndex = 1, AttributeConsumingServiceIndexSpecified = true, ForceAuthn = (securityLevel > 1), ForceAuthnSpecified = (securityLevel > 1), Issuer = new NameIDType { Value = consumerServiceURL.Trim(), Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity", NameQualifier = consumerServiceURL }, NameIDPolicy = new NameIDPolicyType { Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" }, Conditions = new ConditionsType { NotBefore = identityProvider.NotBefore(now), NotBeforeSpecified = true, NotOnOrAfter = identityProvider.After(now.AddMinutes(10)), NotOnOrAfterSpecified = true }, RequestedAuthnContext = new RequestedAuthnContextType { Comparison = AuthnContextComparisonType.minimum, ComparisonSpecified = true, ItemsElementName = new ItemsChoiceType7[] { ItemsChoiceType7.AuthnContextClassRef }, Items = new string[] { "https://www.spid.gov.it/SpidL" + securityLevel.ToString() } } }; 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"); StringWriter stringWriter = new StringWriter(); XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8 }; XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings); XmlSerializer responseSerializer = new XmlSerializer(authnRequest.GetType()); responseSerializer.Serialize(responseWriter, authnRequest, ns); responseWriter.Close(); string samlString = stringWriter.ToString(); stringWriter.Close(); XmlDocument doc = new XmlDocument(); doc.LoadXml(samlString); XmlElement signature = XmlSigningHelper.SignXMLDoc(doc, certificate, "_" + uuid); doc.DocumentElement.InsertBefore(signature, doc.DocumentElement.ChildNodes[1]); return(Convert.ToBase64String(Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + doc.OuterXml))); }
/// <summary> /// Build a signed SAML logout request. /// </summary> /// <param name="uuid"></param> /// <param name="destination"></param> /// <param name="consumerServiceURL"></param> /// <param name="certificate"></param> /// <param name="identityProvider"></param> /// <param name="subjectNameId"></param> /// <param name="authnStatementSessionIndex"></param> /// <returns></returns> public static string BuildLogoutPostRequest(string uuid, string consumerServiceURL, X509Certificate2 certificate, IdentityProvider identityProvider, string subjectNameId, string authnStatementSessionIndex) { if (string.IsNullOrWhiteSpace(uuid)) { throw new ArgumentNullException("The uuid parameter can't be null or empty."); } if (string.IsNullOrWhiteSpace(consumerServiceURL)) { throw new ArgumentNullException("The consumerServiceURL parameter can't be null or empty."); } if (certificate == null) { throw new ArgumentNullException("The certificate parameter can't be null."); } if (identityProvider == null) { throw new ArgumentNullException("The identityProvider parameter can't be null."); } if (string.IsNullOrWhiteSpace(subjectNameId)) { throw new ArgumentNullException("The subjectNameId parameter can't be null or empty."); } if (string.IsNullOrWhiteSpace(identityProvider.SingleLogoutServiceUrl)) { throw new ArgumentNullException("The LogoutServiceUrl of the identity provider is null or empty."); } DateTime now = DateTime.UtcNow; LogoutRequestType logoutRequest = new LogoutRequestType { ID = "_" + uuid, Version = "2.0", IssueInstant = identityProvider.Now(now), Destination = identityProvider.EntityID, Issuer = new NameIDType { Value = consumerServiceURL.Trim(), Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity", NameQualifier = consumerServiceURL }, Item = new NameIDType { NameQualifier = consumerServiceURL, Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", Value = identityProvider.SubjectNameIdFormatter(subjectNameId) }, NotOnOrAfterSpecified = true, NotOnOrAfter = now.AddMinutes(10), Reason = "urn:oasis:names:tc:SAML:2.0:logout:user", SessionIndex = new string[] { authnStatementSessionIndex } }; try { 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"); StringWriter stringWriter = new StringWriter(); XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8 }; XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings); XmlSerializer responseSerializer = new XmlSerializer(logoutRequest.GetType()); responseSerializer.Serialize(responseWriter, logoutRequest, ns); responseWriter.Close(); string samlString = stringWriter.ToString(); stringWriter.Close(); XmlDocument doc = new XmlDocument(); doc.LoadXml(samlString); XmlElement signature = XmlSigningHelper.SignXMLDoc(doc, certificate, "_" + uuid); doc.DocumentElement.InsertBefore(signature, doc.DocumentElement.ChildNodes[1]); return(Convert.ToBase64String(Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + doc.OuterXml))); } catch (Exception ex) { throw ex; } }