public void ParserCanParsePingFederateSignedRequest()
            {
                // Arrange
                var url = new Uri("https://adler.safewhere.local:9031/idp/SSO.saml2?SAMLRequest=7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ%2fff%2fz9cZmQBbPbOStrJniGAqsgfP358Hz8iHv8e7xZlepnXTVEtP%2ftod7zz0e9x9Bsnj3%2fR7qPjdTtfvsp%2f0Tpv2vTs6WcfFbP7ew8fPnhw%2f97%2bZC%2fbvzebPty59%2bn92b37kwc755O9g92P0p80kPYIUnrWNOv8bNm02bKlj3Z2DrZ37m3v7L%2fZ3X90b%2ffRvU%2fHDz69v%2fPw3t5PfZQSHsvm0S%2fa%2feyjdb18VGVN0TxaZou8edROH70%2b%2fuL5IwL5aFVXbTWtyo8IyTR9zB3U8u7mF7OmyeuWUPvoCM2%2bnRVv14%2fvyvsC66Razgq0aN4THt6m94%2fXsyJfTvNXRK%2b6mOI7%2fcr70u%2fcfqYA7AddCI%2fvOtwwOXc7s3P0%2fwA%3d&SigAlg=http%3a%2f%2fwww.w3.org%2f2000%2f09%2fxmldsig%23rsa-sha1&Signature=UsZV%2bFga0YfCQaozLomKfV8jyNt85GMIYLFoBA9jrwFfabL%2bpAWVmlhwHyAMv50uxJWFc57v2ySj5Pc6e1t0NyyaguRL8VOKqB4P3svXV5U4iU0Gq4Rp1SJu0bj538%2f01X8IINmcAJMLdrx1cqCoRmofEcPPoQODWhQoq%2brjZdE%3d");
                var parser = new SAML2.Bindings.HttpRedirectBindingParser(url);
                var cert = new X509Certificate2(@"Certificates\SafewhereTest_SFS.pfx", "test1234");

                // Act
                var result = parser.CheckSignature(cert.PublicKey.Key);

                // Assert
                Assert.That(result);
            }
            public void ParserCanParsePingFederateSignedResponse()
            {
                // Arrange
                var url = new Uri("http://haiku.safewhere.local/Saml20TestWeb/SSOLogout.saml2.aspx?SAMLResponse=fZFRa8IwEMe%2FSsm7bZq2qMEWZN1DwSEY0eGLpGmqZTUpuYTpt19bGVMYPob7%2FX%2BXu1sAv7QdXemTdnYjodMKpJdLsI3ittEqRWdrOxoEZ958OR94Lb%2FP0ki%2F1YK3AevjBG97fi%2FLgLH13eQPWuJz6K7IK9SveKtT1FQ1qYSoSSRIVMVhPJ3hpMQRj6IwKUVcJn0CwMlCgeXKpohgPJvgaILjbUhoQmg49cl8dui5PEWH%2BoaB6P2arAtlq%2FqWF%2FNTXn8y3yBvJw2MQxAfI%2B96aRXQceIUOaOo5tAAVfwigVpB2fJjRXuSdkZbLXSLssVA0%2FE%2F5iH%2FOs4BpBmWh7JlvnrfHIcKwcciXwQPvru8o8xy6%2BD59aYr6e146%2BTrVjDSlDkhJAAKsnuHP2nw34GzHw%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=UoYGLeSCYOSvjIaBpTcgtq2O0Nbz%2BVk%2BaaLESje8%2FZKxGNmWrFXJjSPrA403J23NeQzbxxVgOwSP8idIM95BhlVwxpiG%2B7%2FhJyNNrjGPohmD3cQpBWoWqZ8IEudDc%2FwDCshPb6wTdr6%2FOdKXQ2uwSK5NA2LYI8AAN5sq9kPtVvk%3D");
                var parser = new HttpRedirectBindingParser(url);
                var cert = new X509Certificate2(@"Certificates\pingcertificate.crt");

                // Act
                var result = parser.CheckSignature(cert.PublicKey.Key);

                // Assert
                Assert.That(result);
            }
예제 #3
0
            public void ParserCanParsePingFederateSignedRequest()
            {
                // Arrange
                var url    = new Uri("https://adler.safewhere.local:9031/idp/SSO.saml2?SAMLRequest=7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ%2fff%2fz9cZmQBbPbOStrJniGAqsgfP358Hz8iHv8e7xZlepnXTVEtP%2ftod7zz0e9x9Bsnj3%2fR7qPjdTtfvsp%2f0Tpv2vTs6WcfFbP7ew8fPnhw%2f97%2bZC%2fbvzebPty59%2bn92b37kwc755O9g92P0p80kPYIUnrWNOv8bNm02bKlj3Z2DrZ37m3v7L%2fZ3X90b%2ffRvU%2fHDz69v%2fPw3t5PfZQSHsvm0S%2fa%2feyjdb18VGVN0TxaZou8edROH70%2b%2fuL5IwL5aFVXbTWtyo8IyTR9zB3U8u7mF7OmyeuWUPvoCM2%2bnRVv14%2fvyvsC66Razgq0aN4THt6m94%2fXsyJfTvNXRK%2b6mOI7%2fcr70u%2fcfqYA7AddCI%2fvOtwwOXc7s3P0%2fwA%3d&SigAlg=http%3a%2f%2fwww.w3.org%2f2000%2f09%2fxmldsig%23rsa-sha1&Signature=UsZV%2bFga0YfCQaozLomKfV8jyNt85GMIYLFoBA9jrwFfabL%2bpAWVmlhwHyAMv50uxJWFc57v2ySj5Pc6e1t0NyyaguRL8VOKqB4P3svXV5U4iU0Gq4Rp1SJu0bj538%2f01X8IINmcAJMLdrx1cqCoRmofEcPPoQODWhQoq%2brjZdE%3d");
                var parser = new SAML2.Bindings.HttpRedirectBindingParser(url);
                var cert   = new X509Certificate2(@"Certificates\SafewhereTest_SFS.pfx", "test1234");

                // Act
                var result = parser.CheckSignature(cert.PublicKey.Key);

                // Assert
                Assert.That(result);
            }
예제 #4
0
파일: Logout.cs 프로젝트: jbparker/SAML2
        private void ValidateLogoutViaGet(Uri requestUrl, out string message, out LogoutResponse response)
        {
            var parser = new HttpRedirectBindingParser(requestUrl);
            response = Serialization.DeserializeFromXmlString<LogoutResponse>(parser.Message);

            logger.DebugFormat(TraceMessages.LogoutResponseRedirectBindingParse, parser.Message, parser.SignatureAlgorithm, parser.Signature);

            var idp = IdpSelectionUtil.RetrieveIDPConfiguration(response.Issuer.Value, config);
            if (idp.Metadata == null) {
                logger.ErrorFormat(ErrorMessages.UnknownIdentityProvider, idp.Id);
                throw new Saml20Exception(string.Format(ErrorMessages.UnknownIdentityProvider, idp.Id));
            }

            if (!parser.VerifySignature(idp.Metadata.Keys)) {
                logger.Error(ErrorMessages.ResponseSignatureInvalid);
                throw new Saml20Exception(ErrorMessages.ResponseSignatureInvalid);
            }

            message = parser.Message;
        }
예제 #5
0
        /// <summary>
        /// Handles the response.
        /// </summary>
        /// <param name="context">The context.</param>
        private void HandleResponse(HttpContext context)
        {
            Logger.DebugFormat(TraceMessages.LogoutResponseReceived);

            var message = string.Empty;
            LogoutResponse response = null;
            if (context.Request.RequestType == "GET")
            {
                var parser = new HttpRedirectBindingParser(context.Request.Url);
                response = Serialization.DeserializeFromXmlString<LogoutResponse>(parser.Message);

                Logger.DebugFormat(TraceMessages.LogoutResponseRedirectBindingParse, parser.Message, parser.SignatureAlgorithm, parser.Signature);

                var idp = RetrieveIDPConfiguration(response.Issuer.Value);
                if (idp.Metadata == null)
                {
                    Logger.ErrorFormat(ErrorMessages.UnknownIdentityProvider, idp.Id);
                    throw new Saml20Exception(string.Format(ErrorMessages.UnknownIdentityProvider, idp.Id));
                }

                if (!parser.VerifySignature(idp.Metadata.Keys))
                {
                    Logger.Error(ErrorMessages.ResponseSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.ResponseSignatureInvalid);
                }

                message = parser.Message;
            }
            else if (context.Request.RequestType == "POST")
            {
                var parser = new HttpPostBindingParser(context);
                Logger.DebugFormat(TraceMessages.LogoutResponsePostBindingParse, parser.Message);

                response = Serialization.DeserializeFromXmlString<LogoutResponse>(parser.Message);

                var idp = RetrieveIDPConfiguration(response.Issuer.Value);
                if (idp.Metadata == null)
                {
                    Logger.ErrorFormat(ErrorMessages.UnknownIdentityProvider, idp.Id);
                    throw new Saml20Exception(string.Format(ErrorMessages.UnknownIdentityProvider, idp.Id));
                }

                if (!parser.IsSigned)
                {
                    Logger.Error(ErrorMessages.ResponseSignatureMissing);
                    throw new Saml20Exception(ErrorMessages.ResponseSignatureMissing);
                }

                // signature on final message in logout
                if (!parser.CheckSignature(idp.Metadata.Keys))
                {
                    Logger.Error(ErrorMessages.ResponseSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.ResponseSignatureInvalid);
                }

                message = parser.Message;
            }

            if (response == null)
            {
                Logger.ErrorFormat(ErrorMessages.UnsupportedRequestType, context.Request.RequestType);
                throw new Saml20Exception(string.Format(ErrorMessages.UnsupportedRequestType, context.Request.RequestType));
            }

            Logger.DebugFormat(TraceMessages.LogoutResponseParsed, message);

            if (response.Status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
            {
                Logger.ErrorFormat(ErrorMessages.ResponseStatusNotSuccessful, response.Status.StatusCode.Value);
                throw new Saml20Exception(string.Format(ErrorMessages.ResponseStatusNotSuccessful, response.Status.StatusCode.Value));
            }

            // Log the user out locally
            DoLogout(context);
        }
예제 #6
0
        /// <summary>
        /// Handles the request.
        /// </summary>
        /// <param name="context">The context.</param>
        private void HandleRequest(HttpContext context)
        {
            Logger.DebugFormat(TraceMessages.LogoutRequestReceived);

            // Fetch the endpoint configuration
            var idp = RetrieveIDPConfiguration(StateService.Get<string>(IdpLoginSessionKey));
            var destination = DetermineEndpointConfiguration(BindingType.Redirect, idp.Endpoints.LogoutEndpoint, idp.Metadata.IDPSLOEndpoints);

            // Fetch config object
            var config = Saml2Config.GetConfig();

            // Build the response object
            var response = new Saml20LogoutResponse
                               {
                                   Issuer = config.ServiceProvider.Id,
                                   Destination = destination.Url,
                                   StatusCode = Saml20Constants.StatusCodes.Success
                               };

            string message;
            if (context.Request.RequestType == "GET")
            {
                // HTTP Redirect binding
                var parser = new HttpRedirectBindingParser(context.Request.Url);
                Logger.DebugFormat(TraceMessages.LogoutRequestRedirectBindingParse, parser.Message, parser.SignatureAlgorithm, parser.Signature);

                var endpoint = config.IdentityProviders.FirstOrDefault(x => x.Id == idp.Id);
                if (endpoint == null || endpoint.Metadata == null)
                {
                    Logger.ErrorFormat(ErrorMessages.UnknownIdentityProvider, idp.Id);
                    throw new Saml20Exception(string.Format(ErrorMessages.UnknownIdentityProvider, idp.Id));
                }

                var metadata = endpoint.Metadata;
                if (!parser.VerifySignature(metadata.GetKeys(KeyTypes.Signing)))
                {
                    Logger.Error(ErrorMessages.RequestSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.RequestSignatureInvalid);
                }

                message = parser.Message;
            }
            else if (context.Request.RequestType == "POST")
            {
                // HTTP Post binding
                var parser = new HttpPostBindingParser(context);
                Logger.DebugFormat(TraceMessages.LogoutRequestPostBindingParse, parser.Message);

                if (!parser.IsSigned)
                {
                    Logger.Error(ErrorMessages.RequestSignatureMissing);
                    throw new Saml20Exception(ErrorMessages.RequestSignatureMissing);
                }

                var endpoint = config.IdentityProviders.FirstOrDefault(x => x.Id == idp.Id);
                if (endpoint == null || endpoint.Metadata == null)
                {
                    Logger.ErrorFormat(ErrorMessages.UnknownIdentityProvider, idp.Id);
                    throw new Saml20Exception(string.Format(ErrorMessages.UnknownIdentityProvider, idp.Id));
                }

                var metadata = endpoint.Metadata;

                // Check signature
                if (!parser.CheckSignature(metadata.GetKeys(KeyTypes.Signing)))
                {
                    Logger.Error(ErrorMessages.RequestSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.RequestSignatureInvalid);
                }

                message = parser.Message;
            }
            else
            {
                // Error: We don't support HEAD, PUT, CONNECT, TRACE, DELETE and OPTIONS
                Logger.ErrorFormat(ErrorMessages.UnsupportedRequestType, context.Request.RequestType);
                throw new Saml20Exception(string.Format(ErrorMessages.UnsupportedRequestType, context.Request.RequestType));
            }

            Logger.DebugFormat(TraceMessages.LogoutRequestParsed, message);

            // Log the user out locally
            DoLogout(context, true);

            var req = Serialization.DeserializeFromXmlString<LogoutRequest>(message);
            response.InResponseTo = req.Id;

            // Respond using redirect binding
            if (destination.Binding == BindingType.Redirect)
            {
                var builder = new HttpRedirectBindingBuilder
                                  {
                                      RelayState = context.Request.Params["RelayState"],
                                      Response = response.GetXml().OuterXml,
                                      SigningKey = Saml2Config.GetConfig().ServiceProvider.SigningCertificate.GetCertificate().PrivateKey
                                  };

                Logger.DebugFormat(TraceMessages.LogoutResponseSent, builder.Response);

                context.Response.Redirect(destination.Url + "?" + builder.ToQuery(), true);
                return;
            }

            // Respond using post binding
            if (destination.Binding == BindingType.Post)
            {
                var builder = new HttpPostBindingBuilder(destination)
                                  {
                                      Action = SamlActionType.SAMLResponse
                                  };

                var responseDocument = response.GetXml();

                Logger.DebugFormat(TraceMessages.LogoutResponseSent, responseDocument.OuterXml);

                XmlSignatureUtils.SignDocument(responseDocument, response.Id);
                builder.Response = responseDocument.OuterXml;
                builder.RelayState = context.Request.Params["RelayState"];
                builder.GetPage().ProcessRequest(context);
            }
        }
            public void ParserThrowsExceptionWhenTryingToVerifySignatureOfUnsignedRequest()
            {
                // Arrange
                var request = string.Empty.PadLeft(350, 'A') + "ֶ״ֵזרו";
                var bindingBuilder = new SAML2.Bindings.HttpRedirectBindingBuilder { Request = request };

                var query = bindingBuilder.ToQuery();
                var url = new Uri("http://localhost/?" + query);
                var bindingParser = new HttpRedirectBindingParser(url);

                // Act
                bindingParser.CheckSignature(new RSACryptoServiceProvider());

                // Assert
                Assert.Fail("Trying to verify signature of an unsigned request should have thrown an exception.");
            }
            public void ParserCanSignAuthnRequestWithRsaKey()
            {
                // Arrange
                var key = new RSACryptoServiceProvider();
                var evilKey = new RSACryptoServiceProvider();

                var binding = new SAML2.Bindings.HttpRedirectBindingBuilder
                {
                    Request = string.Empty.PadLeft(500, 'a'),
                    SigningKey = key
                };

                var url = new Uri("http://localhost/?" + binding.ToQuery());

                // Act
                var parser = new HttpRedirectBindingParser(url);

                // Assert
                Assert.That(parser.IsSigned);
                Assert.That(parser.IsRequest);
                Assert.That(!parser.IsResponse);
                Assert.That(parser.CheckSignature(key));
                Assert.IsFalse(parser.CheckSignature(evilKey));
            }
            public void ParserCanEncodeAndDecodeRequestWithRelayState()
            {
                // Arrange
                var request = string.Empty.PadRight(140, 'l');
                var relaystate = "A relaystate test. @@@!!!&&&///";

                var bindingBuilder = new SAML2.Bindings.HttpRedirectBindingBuilder
                                         {
                                             Request = request,
                                             RelayState = relaystate
                                         };

                var query = bindingBuilder.ToQuery();
                var coll = QueryToNameValueCollection(query);
                var url = new Uri("http://localhost/?" + query);

                // Act
                var bindingParser = new HttpRedirectBindingParser(url);

                // Assert
                Assert.AreEqual(2, coll.Count);
                Assert.IsTrue(bindingParser.IsRequest);
                Assert.IsFalse(bindingParser.IsResponse);
                Assert.IsFalse(bindingParser.IsSigned);
                Assert.IsNotNull(bindingParser.RelayState);
                Assert.AreEqual(relaystate, bindingParser.RelayStateDecoded);
                Assert.AreEqual(request, bindingParser.Message);
            }
            public void ParserCanEncodeAndDecodeRequest()
            {
                // Arrange
                var request = string.Empty.PadLeft(350, 'A') + "ֶ״ֵזרו";
                var bindingBuilder = new SAML2.Bindings.HttpRedirectBindingBuilder { Request = request };

                var query = bindingBuilder.ToQuery();
                var coll = QueryToNameValueCollection(query);
                var url = new Uri("http://localhost/?" + query);

                // Act
                var bindingParser = new HttpRedirectBindingParser(url);

                // Assert
                Assert.That(coll.Count == 1);
                Assert.That(bindingParser.IsRequest);
                Assert.That(!bindingParser.IsResponse);
                Assert.That(!bindingParser.IsSigned);
                Assert.AreEqual(request, bindingParser.Message);
            }