コード例 #1
0
        public void PingTest_02()
        {
            string s =
                "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";
            Uri url = new Uri(s);

            HttpRedirectBindingParser parser = new HttpRedirectBindingParser(url);
            X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\SafewhereTest_SFS.pfx", "test1234");
            Assert.That(parser.CheckSignature(cert.PublicKey.Key));
        }
コード例 #2
0
        public override void ProcessRequest(HttpContext context)
        {
            if (context.Request.RequestType == "GET")
            {
                if (context.Request.Params["SAMLRequest"] == null)
                    return;

                HttpRedirectBindingParser parser = new HttpRedirectBindingParser(context.Request.Url);
                Signin(parser);
            }

            // Not playing SAML2-Redirect-binding? You're on your own....
        }
コード例 #3
0
        public void PingTest_01()
        {
            // Actual URL from Ping.
            string s =                
                "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";
            Uri url =
                new Uri(s);            

            HttpRedirectBindingParser parser = new HttpRedirectBindingParser(url);

            X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\pingcertificate.crt");
            Assert.That(parser.CheckSignature(cert.PublicKey.Key));
        }
コード例 #4
0
        /// <summary>
        /// Processes the request.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void ProcessRequest(HttpContext context)
        {
            if (context.Request.HttpMethod != "GET")
                return; // Only handle Redirect logouts.

            HttpRedirectBindingParser parser = new HttpRedirectBindingParser(context.Request.Url);
            if (context.Request.Params["SAMLRequest"] != null)
            {
                HandleLogoutRequest(parser);
            }

            if (context.Request.Params["SAMLResponse"] != null)
            {
                HandleLogoutResponse(parser);
            }
        }
コード例 #5
0
ファイル: BaseHandler.cs プロジェクト: fredrikhl/OIOSAML
 /// <summary>
 /// Checks the signature of a message received using the redirect binding using the keys found in the 
 /// metadata of the federation partner that sent the request.
 /// </summary>
 protected static bool CheckRedirectSignature(HttpRedirectBindingParser parser, Saml20MetadataDocument metadata)
 {
     List<KeyDescriptor> keys = metadata.GetKeys(KeyTypes.signing);
     // Go through the list of signing keys (usually only one) and use it to verify the REDIRECT request.
     foreach (KeyDescriptor key in keys)
     {
         KeyInfo keyinfo = (KeyInfo)key.KeyInfo;
         foreach (KeyInfoClause keyInfoClause in keyinfo)
         {
             AsymmetricAlgorithm signatureKey = XmlSignatureUtils.ExtractKey(keyInfoClause);
             if (signatureKey != null && parser.CheckSignature(signatureKey))
                 return true;                    
         }
     }
     return false;
 }
コード例 #6
0
        /// <summary>
        /// Verify the request and transfer the login-page.
        /// </summary>
        /// <param name="parser"></param>
        private static void Signin(HttpRedirectBindingParser parser)
        {
            AuthnRequest req = Serialization.DeserializeFromXmlString<AuthnRequest>(parser.Message);

            // Retrieve metadata of requestor.
            string SPID = req.Issuer.Value;
            Saml20MetadataDocument SPmetadata = GetMetadata(SPID);

            if (parser.IsSigned && !CheckRedirectSignature(parser, SPmetadata))
            {
                HandleUnableToVerifySignature(SPID);
                return;
            }

            HttpContext.Current.Application["authenticationrequest"] = req;
            HttpContext.Current.Server.Transfer("SignonForm.aspx");
        }
コード例 #7
0
ファイル: Logout.ashx.cs プロジェクト: fredrikhl/OIOSAML
        private static void HandleLogoutResponse(HttpRedirectBindingParser parser)
        {
            LogoutResponse res = Serialization.DeserializeFromXmlString<LogoutResponse>(parser.Message);

            // Retrieve metadata of requestor.
            string SPID = res.Issuer.Value;
            Saml20MetadataDocument SPmetadata = GetMetadata(SPID);

            if (parser.IsSigned && !CheckRedirectSignature(parser, SPmetadata))
            {
                HandleUnableToVerifySignature(SPID);
                return;
            }

            // Remove the Service Provider from the list of the user's active sessions.
            UserSessionsHandler.RemoveLoggedInSession(SPID);

            Logout();
        }
コード例 #8
0
        public void TestDSASigning()
        {
            HttpRedirectBindingBuilder binding = new HttpRedirectBindingBuilder();

            DSACryptoServiceProvider key = new DSACryptoServiceProvider();
            binding.signingKey = key;
            binding.Request = string.Empty.PadLeft(500, 'a');

            // Now, parse the query.
            Uri url = new Uri("http://localhost/?" + binding.ToQuery());
            HttpRedirectBindingParser parser = new HttpRedirectBindingParser(url);
            Assert.That(parser.IsSigned);
            Assert.That(parser.IsRequest);
            Assert.That(parser.CheckSignature(key));

            // Create a new key set, and check that it can not verify the signature.
            DSACryptoServiceProvider evilKey = new DSACryptoServiceProvider();
            Assert.IsFalse(parser.CheckSignature(evilKey));
        }
コード例 #9
0
ファイル: Logout.ashx.cs プロジェクト: fredrikhl/OIOSAML
        private static void HandleLogoutRequest(HttpRedirectBindingParser parser)
        {
            LogoutRequest req = Serialization.DeserializeFromXmlString<LogoutRequest>(parser.Message);

            // Retrieve metadata of requestor.
            string SPID = req.Issuer.Value;
            Saml20MetadataDocument SPmetadata = GetMetadata(SPID);

            if (parser.IsSigned && !CheckRedirectSignature(parser, SPmetadata))
            {
                HandleUnableToVerifySignature(SPID);
                return;
            }

            // Set the entity ID of the federation partner that initiated the logout.
            HttpContext.Current.Session[LOGOUTINITIATORKEY] = SPID;
            UserSessionsHandler.RemoveLoggedInSession(SPID);

            Logout();
        }
コード例 #10
0
        public void TestParsing_02()
        {
            HttpRedirectBindingBuilder bindingBuilder = new HttpRedirectBindingBuilder();
            string request = string.Empty.PadRight(140, 'l');
            string relaystate = "A relaystate test. @@@!!!&&&///";

            bindingBuilder.Request = request;
            bindingBuilder.RelayState = relaystate;

            string query = bindingBuilder.ToQuery();
            NameValueCollection coll = QueryToNameValueCollection(query);
            Assert.AreEqual(2, coll.Count);

            Uri url = new Uri("http://localhost/?" + query);
            HttpRedirectBindingParser bindingParser = new HttpRedirectBindingParser(url);
            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);
        }
コード例 #11
0
        public void TestParsing_01()
        {
            HttpRedirectBindingBuilder bindingBuilder = new HttpRedirectBindingBuilder();
            string request = string.Empty.PadLeft(350, 'A');
            bindingBuilder.Request = request;

            string query = bindingBuilder.ToQuery();
            NameValueCollection coll = QueryToNameValueCollection(query);
            Assert.That(coll.Count == 1);            

            Uri url = new Uri("http://localhost/?" + query);
            HttpRedirectBindingParser bindingParser = new HttpRedirectBindingParser(url);
            Assert.That(bindingParser.IsRequest);
            Assert.That(!bindingParser.IsResponse);
            Assert.That(!bindingParser.IsSigned);
            Assert.AreEqual(request, bindingParser.Message);

            try
            {
                bindingParser.CheckSignature(new RSACryptoServiceProvider());
                Assert.Fail("Trying to verify signature of an unsigned request should have thrown an exception.");
            } catch(InvalidOperationException) {}
        }
コード例 #12
0
        private void HandleRequest(HttpContext context)
        {
            Trace.TraceMethodCalled(GetType(), "HandleRequest()");

            //Fetch the endpoint configuration
            IDPEndPoint idpEndpoint = RetrieveIDPConfiguration(context.Session[IDPLoginSessionKey].ToString());

            IDPEndPointElement destination =
                DetermineEndpointConfiguration(SAMLBinding.REDIRECT, idpEndpoint.SLOEndpoint, idpEndpoint.metadata.SLOEndpoints());

            //Fetch config object
            SAML20FederationConfig config = ConfigurationReader.GetConfig<SAML20FederationConfig>();
                        
            //Build the response object
            Saml20LogoutResponse response = new Saml20LogoutResponse();
            response.Issuer = config.ServiceProvider.ID;
            response.Destination = destination.Url;
            response.StatusCode = Saml20Constants.StatusCodes.Success;

            string message = string.Empty;

            if(context.Request.RequestType == "GET") // HTTP Redirect binding
            {
                HttpRedirectBindingParser parser = new HttpRedirectBindingParser(context.Request.Url);
                IDPEndPoint endpoint = config.FindEndPoint(idpEndpoint.Id);

                if (endpoint.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Cannot find metadata for IdP");
                    HandleError(context, "Cannot find metadata for IdP " + idpEndpoint.Id);
                    return;
                }

                Saml20MetadataDocument metadata = endpoint.metadata;

                if (!parser.VerifySignature(metadata.GetKeys(KeyTypes.signing)))
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Invalid signature redirect-binding, msg: " + parser.Message);
                    HandleError(context, Resources.SignatureInvalid);
                    return;
                }

                message = parser.Message;
            }
            else if (context.Request.RequestType == "POST") // HTTP Post binding
            {
                HttpPostBindingParser parser = new HttpPostBindingParser(context);

                if (!parser.IsSigned())
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Signature not present, msg: " + parser.Message);
                    HandleError(context, Resources.SignatureNotPresent);
                }

                IDPEndPoint endpoint = config.FindEndPoint(idpEndpoint.Id);
                if (endpoint.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Cannot find metadata for IdP");
                    HandleError(context, "Cannot find metadata for IdP " + idpEndpoint.Id);
                    return;
                }

                Saml20MetadataDocument metadata = endpoint.metadata;

                // handle a logout-request
                if (!parser.CheckSignature(metadata.GetKeys(KeyTypes.signing)))
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Invalid signature post-binding, msg: " + parser.Message);
                    HandleError(context, Resources.SignatureInvalid);
                }

                message = parser.Message;
            }else
            {
                //Error: We don't support HEAD, PUT, CONNECT, TRACE, DELETE and OPTIONS
                HandleError(context, Resources.UnsupportedRequestTypeFormat(context.Request.RequestType));
            }

            AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, message);

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

            LogoutRequest req = Serialization.DeserializeFromXmlString<LogoutRequest>(message);

            response.InResponseTo = req.ID;

            //Respond using redirect binding
            if(destination.Binding == SAMLBinding.REDIRECT)
            {
                HttpRedirectBindingBuilder builder = new HttpRedirectBindingBuilder();
                builder.RelayState = context.Request.Params["RelayState"];
                builder.Response = response.GetXml().OuterXml;
                builder.signingKey = FederationConfig.GetConfig().SigningCertificate.GetCertificate().PrivateKey;
                string s = destination.Url + "?" + builder.ToQuery();
                context.Response.Redirect(s, true);
                return;
            }

            //Respond using post binding
            if (destination.Binding == SAMLBinding.POST)
            {
                HttpPostBindingBuilder builder = new HttpPostBindingBuilder(destination);
                builder.Action = SAMLAction.SAMLResponse;                                
                XmlDocument responseDocument = response.GetXml();
                XmlSignatureUtils.SignDocument(responseDocument, response.ID);
                builder.Response = responseDocument.OuterXml;
                builder.RelayState = context.Request.Params["RelayState"];
                builder.GetPage().ProcessRequest(context);
                return;
            }
        }
コード例 #13
0
        private void HandleResponse(HttpContext context)
        {
            Trace.TraceMethodCalled(GetType(), "HandleResponse()");


            string message = string.Empty;

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

                IDPEndPoint idp = RetrieveIDPConfiguration(response.Issuer.Value);
                
                AuditLogging.IdpId = idp.Id;
                AuditLogging.AssertionId = response.ID;
                
                if (idp.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("No IDP metadata, unknown IDP, response: {0}", parser.Message));
                    HandleError(context, Resources.UnknownIDP);
                    return;
                }

                if (!parser.VerifySignature(idp.metadata.Keys))
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("Invalid signature in redirect-binding, response: {0}", parser.Message));
                    HandleError(context, Resources.SignatureInvalid);
                    return;
                }

                message = parser.Message;
            }else if(context.Request.RequestType == "POST")
            {
                HttpPostBindingParser parser = new HttpPostBindingParser(context);
                LogoutResponse response = Serialization.DeserializeFromXmlString<LogoutResponse>(parser.Message);

                IDPEndPoint idp = RetrieveIDPConfiguration(response.Issuer.Value);

                if (idp.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("No IDP metadata, unknown IDP, response: {0}", parser.Message));
                    HandleError(context, Resources.UnknownIDP);
                    return;
                }

                if (!parser.IsSigned())
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("Signature not present, response: {0}", parser.Message));
                    HandleError(context, Resources.SignatureNotPresent);
                }

                // signature on final message in logout
                if (!parser.CheckSignature(idp.metadata.Keys))
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("Invalid signature in post-binding, response: {0}", parser.Message));
                    HandleError(context, Resources.SignatureInvalid);
                }

                message = parser.Message;
            }else
            {
                AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("Unsupported request type format, type: {0}", context.Request.RequestType));
                HandleError(context, Resources.UnsupportedRequestTypeFormat(context.Request.RequestType));
            }

            AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE, message);

            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = true;
            doc.LoadXml(message);

            XmlElement statElem =
                (XmlElement)doc.GetElementsByTagName(Status.ELEMENT_NAME, Saml20Constants.PROTOCOL)[0];

            Status status = Serialization.DeserializeFromXmlString<Status>(statElem.OuterXml);

            if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
            {
                AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                                      string.Format("Unexpected status code: {0}, msg: {1}", status.StatusCode.Value, message));
                HandleError(context, status);
                return;
            }

            AuditLogging.logEntry(Direction.IN, Operation.LOGOUTRESPONSE,
                     "Assertion validated succesfully");

            //Log the user out locally
            DoLogout(context);
        }