Example #1
0
        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}");
        }
Example #2
0
        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}");
        }
Example #3
0
        /// <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}");
        }
Example #4
0
        /// <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}");
        }