private string BuildRequestUrl(string providerName, string relayState, string message, string destination) { var result = new StringBuilder(); result.AddMessageParameter(message, null); result.AddRelayState(message, relayState); AddSignature(providerName, result); return($"{destination}?{result}"); }
private string BuildRequestUrl(AsymmetricAlgorithm signingKey, string hashingAlgorithm, string relayState, string request, string destination) { var shaHashingAlgorithm = _signatureProviderFactory.ValidateShaHashingAlgorithm(hashingAlgorithm); // Check if the key is of a supported type. [SAMLBind] sect. 3.4.4.1 specifies this. if (!(signingKey is RSA || signingKey is DSA || signingKey == null)) { throw new ArgumentException("Signing key must be an instance of either RSA or DSA."); } var result = new StringBuilder(); result.AddMessageParameter(request, null); result.AddRelayState(request, relayState); AddSignature(result, signingKey, shaHashingAlgorithm); return($"{destination}?{result}"); }
/// <summary> /// Creates the authn request. /// </summary> /// <param name="options">The options.</param> /// <param name="authnRequestId">The authn request identifier.</param> /// <param name="relayState">State of the relay.</param> /// <param name="assertionConsumerServiceUrl">The assertion consumer service URL.</param> /// <returns></returns> /// <exception cref="ArgumentException">Signing key must be an instance of either RSA or DSA.</exception> public string CreateAuthnRequest(Saml2Options options, string authnRequestId, string relayState, string assertionConsumerServiceUrl) { NameIDType entityID = new NameIDType() { Value = options.ServiceProvider.EntityId }; var singleSignOnService = options.Configuration.SingleSignOnServices.FirstOrDefault(x => x.Binding == options.AssertionConsumerServiceProtocolBinding); X509Certificate2 spCertificate = GetServiceProviderCertficate(options); AuthnRequest authnRequest = new AuthnRequest() { ID = authnRequestId, Issuer = entityID, Version = Saml2Constants.Version, ForceAuthn = options.ForceAuthn, ForceAuthnSpecified = true, IsPassive = options.IsPassive, IsPassiveSpecified = true, NameIDPolicy = new NameIDPolicyType() { Format = options.NameIDType.Format, SPNameQualifier = options.NameIDType.SPNameQualifier, AllowCreate = true, AllowCreateSpecified = true }, Destination = singleSignOnService.Location.ToString(), ProtocolBinding = singleSignOnService.Binding.ToString(), IssueInstant = DateTime.UtcNow, AssertionConsumerServiceURL = assertionConsumerServiceUrl }; string singleSignOnUrl = options.Configuration.SingleSignOnServices.FirstOrDefault().Location; //serialize AuthnRequest to xml string string xmlTemplate = string.Empty; XmlSerializer xmlSerializer = new XmlSerializer(typeof(AuthnRequest)); using (MemoryStream memStm = new MemoryStream()) { xmlSerializer.Serialize(memStm, authnRequest); memStm.Position = 0; xmlTemplate = new StreamReader(memStm).ReadToEnd(); } //create xml document from string XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlTemplate); xmlDoc.PreserveWhitespace = false; string request = xmlDoc.OuterXml; var result = new StringBuilder(); result.AddMessageParameter(request, null); result.AddRelayState(request, relayState); if (options.ServiceProvider.X509Certificate2 != null) { AsymmetricAlgorithm spPrivateKey = spCertificate.PrivateKey; string hashingAlgorithm = options.Configuration.Signature.SignedInfo.SignatureMethod; // Check if the key is of a supported type. [SAMLBind] sect. 3.4.4.1 specifies this. if (!(spPrivateKey is RSA || spPrivateKey is DSA || spPrivateKey == null)) { throw new ArgumentException("Signing key must be an instance of either RSA or DSA."); } AddSignature(result, spPrivateKey, hashingAlgorithm, options.ServiceProvider.HashAlgorithm); } return($"{singleSignOnUrl}?{result}"); }
/// <summary> /// Creates the logout request. /// The "LogoutRequest" message MUST be signed if the HTTP POST or Redirect binding is used. /// Logout request MUST be signed according to http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf Sect 4.4.3.1 /// </summary> /// <param name="options">The options.</param> /// <param name="logoutRequestId">The logout request identifier.</param> /// <param name="sessionIndex">Index of the session.</param> /// <param name="nameId">The name identifier.</param> /// <param name="relayState">State of the relay.</param> /// <param name="sendSignoutTo">The send signout to.</param> /// <returns></returns> /// <exception cref="ArgumentException">Signing key must be an instance of either RSA or DSA.</exception> public string CreateLogoutRequest(Saml2Options options, string logoutRequestId, string sessionIndex, string nameId, string relayState, string sendSignoutTo) { NameIDType entityID = new NameIDType() { Value = options.ServiceProvider.EntityId }; var singleLogoutService = options.Configuration.SingleLogoutServices.FirstOrDefault(x => x.Binding == options.SingleLogoutServiceProtocolBinding); LogoutRequest logoutRequest = new LogoutRequest() { ID = logoutRequestId, Issuer = entityID, Version = Saml2Constants.Version, Reason = Saml2Constants.Reasons.User, SessionIndex = new string[] { sessionIndex }, Destination = singleLogoutService.Location.ToString(), IssueInstant = DateTime.UtcNow, Item = new NameIDType() { Format = options.NameIDType.Format, NameQualifier = options.NameIDType.NameQualifier, SPProvidedID = options.NameIDType.SPProvidedID, SPNameQualifier = options.NameIDType.SPNameQualifier, Value = options.NameIDType.Value } }; string singleLogoutUrl = options.Configuration.SingleLogoutServices.FirstOrDefault().Location; //serialize AuthnRequest to xml string string xmlTemplate = string.Empty; XmlSerializer xmlSerializer = new XmlSerializer(typeof(LogoutRequest)); using (MemoryStream memStm = new MemoryStream()) { xmlSerializer.Serialize(memStm, logoutRequest); memStm.Position = 0; xmlTemplate = new StreamReader(memStm).ReadToEnd(); } //create xml document from string XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlTemplate); xmlDoc.PreserveWhitespace = false; string request = xmlDoc.OuterXml; var result = new StringBuilder(); result.AddMessageParameter(request, null); result.AddRelayState(request, relayState); if (options.hasCertificate) { X509Certificate2 spCertificate = GetServiceProviderCertficate(options); string hashingAlgorithm = options.Configuration.Signature.SignedInfo.SignatureMethod; AsymmetricAlgorithm spPrivateKey = spCertificate.PrivateKey; // Check if the key is of a supported type. [SAMLBind] sect. 3.4.4.1 specifies this. if (!(spPrivateKey is RSA || spPrivateKey is DSA || spPrivateKey == null)) { throw new ArgumentException("Signing key must be an instance of either RSA or DSA."); } AddSignature(result, spPrivateKey, hashingAlgorithm, options.ServiceProvider.HashAlgorithm); } return($"{singleLogoutUrl}?{result}"); }