コード例 #1
0
            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);
            }
コード例 #2
0
            public void DoesNotAllowRequestAndResponseToBothBeSet()
            {
                // Arrange
                var binding = new HttpRedirectBindingBuilder
                                  {
                                      Request = "Request"
                                  };

                // Act
                binding.Response = "Response";

                // Assert
                Assert.Fail("HttpRedirectBinding did not throw an exception when both Request and Response were set.");
            }
コード例 #3
0
            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
                Assert.Throws <InvalidOperationException>(() => bindingParser.CheckSignature(new RSACryptoServiceProvider()));
            }
コード例 #4
0
            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.");
            }
コード例 #5
0
            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);
            }
コード例 #6
0
            public void ParserCanSignAuthnRequestWithDsaKey()
            {
                // Arrange
                var key     = new DSACryptoServiceProvider();
                var evilKey = new DSACryptoServiceProvider();

                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.CheckSignature(key));
                Assert.IsFalse(parser.CheckSignature(evilKey));
            }
コード例 #7
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);
            }
        }
コード例 #8
0
        /// <summary>
        /// Transfers the client.
        /// </summary>
        /// <param name="identityProvider">The identity provider.</param>
        /// <param name="request">The request.</param>
        /// <param name="context">The context.</param>
        private void TransferClient(IdentityProviderElement identityProvider, Saml20AuthnRequest request, HttpContext context)
        {
            // Set the last IDP we attempted to login at.
            StateService.Set(IdpTempSessionKey, identityProvider.Id);

            // Determine which endpoint to use from the configuration file or the endpoint metadata.
            var destination = DetermineEndpointConfiguration(BindingType.Redirect, identityProvider.Endpoints.SignOnEndpoint, identityProvider.Metadata.SSOEndpoints);
            request.Destination = destination.Url;

            if (identityProvider.ForceAuth)
            {
                request.ForceAuthn = true;
            }

            // Check isPassive status
            var isPassiveFlag = StateService.Get<bool?>(IdpIsPassive);

            if (isPassiveFlag != null && (bool)isPassiveFlag)
            {
                request.IsPassive = true;
                StateService.Set(IdpIsPassive, null);
            }

            if (identityProvider.IsPassive)
            {
                request.IsPassive = true;
            }

            // Check if request should forceAuthn
            var forceAuthnFlag = StateService.Get<bool?>(IdpForceAuthn);
            if (forceAuthnFlag != null && (bool)forceAuthnFlag)
            {
                request.ForceAuthn = true;
                StateService.Set(IdpForceAuthn, null);
            }

            // Check if protocol binding should be forced
            if (identityProvider.Endpoints.SignOnEndpoint != null)
            {
                if (!string.IsNullOrEmpty(identityProvider.Endpoints.SignOnEndpoint.ForceProtocolBinding))
                {
                    request.ProtocolBinding = identityProvider.Endpoints.SignOnEndpoint.ForceProtocolBinding;
                }
            }

            // Save request message id to session
            StateService.Set(ExpectedInResponseToSessionKey, request.Id);

            switch (destination.Binding)
            {
                case BindingType.Redirect:
                    Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpRedirect);

                    var redirectBuilder = new HttpRedirectBindingBuilder
                                      {
                                          SigningKey = _certificate.PrivateKey,
                                          Request = request.GetXml().OuterXml
                                      };

                    Logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);

                    var redirectLocation = request.Destination + "?" + redirectBuilder.ToQuery();
                    context.Response.Redirect(redirectLocation, true);
                    break;
                case BindingType.Post:
                    Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpPost);

                    var postBuilder = new HttpPostBindingBuilder(destination);

                    // Honor the ForceProtocolBinding and only set this if it's not already set
                    if (string.IsNullOrEmpty(request.ProtocolBinding))
                    {
                        request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpPost;
                    }

                    var requestXml = request.GetXml();
                    XmlSignatureUtils.SignDocument(requestXml, request.Id);
                    postBuilder.Request = requestXml.OuterXml;

                    Logger.DebugFormat(TraceMessages.AuthnRequestSent, postBuilder.Request);

                    postBuilder.GetPage().ProcessRequest(context);
                    break;
                case BindingType.Artifact:
                    Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpArtifact);

                    var artifactBuilder = new HttpArtifactBindingBuilder(context);

                    // Honor the ForceProtocolBinding and only set this if it's not already set
                    if (string.IsNullOrEmpty(request.ProtocolBinding))
                    {
                        request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpArtifact;
                    }

                    Logger.DebugFormat(TraceMessages.AuthnRequestSent, request.GetXml().OuterXml);

                    artifactBuilder.RedirectFromLogin(destination, request);
                    break;
                default:
                    Logger.Error(ErrorMessages.EndpointBindingInvalid);
                    throw new Saml20Exception(ErrorMessages.EndpointBindingInvalid);
            }
        }
コード例 #9
0
            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.");
            }
コード例 #10
0
            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));
            }
コード例 #11
0
            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);
            }
コード例 #12
0
            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);
            }
コード例 #13
0
            public void EncodesRelayStateForRequests()
            {
                // Arrange
                var relaystate = string.Empty.PadRight(10, 'A');
                var bindingBuilder = new HttpRedirectBindingBuilder
                                         {
                                             Request = "A random request... !!!! .... ",
                                             RelayState = relaystate
                                         };

                // Act
                var query = bindingBuilder.ToQuery();

                // Assert
                Assert.That(!query.Contains(relaystate));
            }
コード例 #14
0
ファイル: Saml20LogoutHandler.cs プロジェクト: jbparker/SAML2
        /// <summary>
        /// Transfers the client.
        /// </summary>
        /// <param name="idp">The identity provider.</param>
        /// <param name="context">The context.</param>
        private void TransferClient(IdentityProvider idp, HttpContext context, Saml2Configuration config)
        {
            var request = Saml20LogoutRequest.GetDefault(config);

            // Determine which endpoint to use from the configuration file or the endpoint metadata.
            var destination = IdpSelectionUtil.DetermineEndpointConfiguration(BindingType.Redirect, idp.Endpoints.DefaultLogoutEndpoint, idp.Metadata.IDPSLOEndpoints);
            request.Destination = destination.Url;

            var nameIdFormat = (string)context.Session[IdpNameIdFormat];
            request.SubjectToLogOut.Format = nameIdFormat;

            // Handle POST binding
            if (destination.Binding == BindingType.Post)
            {
                var builder = new HttpPostBindingBuilder(destination);
                request.Destination = destination.Url;
                request.Reason = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = (string)context.Session[IdpNameId];
                request.SessionIndex = (string)context.Session[IdpSessionIdKey];

                var requestDocument = request.GetXml();
                XmlSignatureUtils.SignDocument(requestDocument, request.Id, config.ServiceProvider.SigningCertificate);
                builder.Request = requestDocument.OuterXml;

                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "POST", builder.Request);

                context.Response.Write(builder.GetPage());
                context.Response.End();
                return;
            }

            // Handle Redirect binding
            if (destination.Binding == BindingType.Redirect)
            {
                request.Destination = destination.Url;
                request.Reason = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = (string)context.Session[IdpNameId];
                request.SessionIndex = (string)context.Session[IdpSessionIdKey];

                var builder = new HttpRedirectBindingBuilder
                                  {
                                      Request = request.GetXml().OuterXml,
                                      SigningKey = config.ServiceProvider.SigningCertificate.PrivateKey
                                  };

                var redirectUrl = destination.Url + (destination.Url.Contains("?") ? "&" : "?") + builder.ToQuery();
                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "REDIRECT", redirectUrl);

                context.Response.Redirect(redirectUrl, true);
                return;
            }

            // Handle Artifact binding
            if (destination.Binding == BindingType.Artifact)
            {
                request.Destination = destination.Url;
                request.Reason = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = (string)context.Session[IdpNameId];
                request.SessionIndex = (string)context.Session[IdpSessionIdKey];

                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "ARTIFACT", request.GetXml().OuterXml);

                var builder = GetBuilder(context);
                builder.RedirectFromLogout(destination, request, Guid.NewGuid().ToString("N"), (s, o) => context.Cache.Insert(s, o, null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration));
            }

            Logger.Error(ErrorMessages.EndpointBindingInvalid);
            throw new Saml20Exception(ErrorMessages.EndpointBindingInvalid);
        }
コード例 #15
0
        /// <summary>
        /// Transfers the client.
        /// </summary>
        /// <param name="idp">The identity provider.</param>
        /// <param name="context">The context.</param>
        private void TransferClient(IdentityProviderElement idp, HttpContext context)
        {
            var request = Saml20LogoutRequest.GetDefault();

            // Determine which endpoint to use from the configuration file or the endpoint metadata.
            var destination = DetermineEndpointConfiguration(BindingType.Redirect, idp.Endpoints.LogoutEndpoint, idp.Metadata.IDPSLOEndpoints);
            request.Destination = destination.Url;

            var nameIdFormat = StateService.Get<string>(IdpNameIdFormat);
            request.SubjectToLogOut.Format = nameIdFormat;

            // Handle POST binding
            if (destination.Binding == BindingType.Post)
            {
                var builder = new HttpPostBindingBuilder(destination);
                request.Destination = destination.Url;
                request.Reason = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = StateService.Get<string>(IdpNameId);
                request.SessionIndex = StateService.Get<string>(IdpSessionIdKey);

                var requestDocument = request.GetXml();
                XmlSignatureUtils.SignDocument(requestDocument, request.Id);
                builder.Request = requestDocument.OuterXml;

                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "POST", builder.Request);

                builder.GetPage().ProcessRequest(context);
                context.Response.End();
                return;
            }

            // Handle Redirect binding
            if (destination.Binding == BindingType.Redirect)
            {
                request.Destination = destination.Url;
                request.Reason = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = StateService.Get<string>(IdpNameId);
                request.SessionIndex = StateService.Get<string>(IdpSessionIdKey);

                var builder = new HttpRedirectBindingBuilder
                                  {
                                      Request = request.GetXml().OuterXml,
                                      SigningKey = Saml2Config.GetConfig().ServiceProvider.SigningCertificate.GetCertificate().PrivateKey
                                  };

                var redirectUrl = destination.Url + "?" + builder.ToQuery();
                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "REDIRECT", redirectUrl);

                context.Response.Redirect(redirectUrl, true);
                return;
            }

            // Handle Artifact binding
            if (destination.Binding == BindingType.Artifact)
            {
                request.Destination = destination.Url;
                request.Reason = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = StateService.Get<string>(IdpNameId);
                request.SessionIndex = StateService.Get<string>(IdpSessionIdKey);

                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "ARTIFACT", request.GetXml().OuterXml);

                var builder = new HttpArtifactBindingBuilder(context);
                builder.RedirectFromLogout(destination, request, Guid.NewGuid().ToString("N"));
            }

            Logger.Error(ErrorMessages.EndpointBindingInvalid);
            throw new Saml20Exception(ErrorMessages.EndpointBindingInvalid);
        }
コード例 #16
0
            public void DoesNotEncodeRelayStateForResponse()
            {
                // Arrange
                var relaystate = string.Empty.PadRight(10, 'A');
                var bindingBuilder = new HttpRedirectBindingBuilder
                                         {
                                             RelayState = relaystate,
                                             Response = "A random response... !!!! .... "
                                         };

                // Act
                var query = bindingBuilder.ToQuery();

                // Assert
                Assert.That(query.Contains(relaystate));
            }
コード例 #17
0
ファイル: Saml20SignonHandler.cs プロジェクト: 4nderss/SAML2
        /// <summary>
        /// Transfers the client.
        /// </summary>
        /// <param name="identityProvider">The identity provider.</param>
        /// <param name="request">The request.</param>
        /// <param name="context">The context.</param>
        private void TransferClient(IdentityProvider identityProvider, Saml20AuthnRequest request, HttpContext context, Saml2Configuration config)
        {
            IdentityProviderEndpoint destination = ConfigureRequest(identityProvider, request, context);

            switch (destination.Binding) {
            case BindingType.Redirect:
                Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpRedirect);

                var redirectBuilder = new HttpRedirectBindingBuilder
                {
                    SigningKey = _certificate.PrivateKey,
                    Request = request.GetXml().OuterXml
                };

                Logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);

                var redirectLocation = request.Destination + "?" + redirectBuilder.ToQuery();
                context.Response.Redirect(redirectLocation, true);
                break;
            case BindingType.Post:
                Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpPost);

                var postBuilder = new HttpPostBindingBuilder(destination);

                // Honor the ForceProtocolBinding and only set this if it's not already set
                if (string.IsNullOrEmpty(request.ProtocolBinding)) {
                    request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpPost;
                }

                var requestXml = request.GetXml();
                XmlSignatureUtils.SignDocument(requestXml, request.Id, config.ServiceProvider.SigningCertificate);
                postBuilder.Request = requestXml.OuterXml;

                Logger.DebugFormat(TraceMessages.AuthnRequestSent, postBuilder.Request);

                context.Response.Write(postBuilder.GetPage());
                break;
            case BindingType.Artifact:
                Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpArtifact);

                var artifactBuilder = GetBuilder(context);

                // Honor the ForceProtocolBinding and only set this if it's not already set
                if (string.IsNullOrEmpty(request.ProtocolBinding)) {
                    request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpArtifact;
                }

                Logger.DebugFormat(TraceMessages.AuthnRequestSent, request.GetXml().OuterXml);

                artifactBuilder.RedirectFromLogin(destination, request, context.Request.Params["relayState"], (s, o) => context.Cache.Insert(s, o, null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration));
                break;
            default:
                Logger.Error(ErrorMessages.EndpointBindingInvalid);
                throw new Saml20Exception(ErrorMessages.EndpointBindingInvalid);
            }
        }
コード例 #18
0
ファイル: SamlMessage.cs プロジェクト: 4nderss/SAML2
        private string AuthnRequestForIdp(IdentityProvider identityProvider, Saml20AuthnRequest request, IOwinContext context, Saml2Configuration config)
        {
            var logger = SAML2.Logging.LoggerProvider.LoggerFor(typeof(SamlMessage));

            context.Set(IdpTempSessionKey, identityProvider.Id);

            // Determine which endpoint to use from the configuration file or the endpoint metadata.
            var destination = IdpSelectionUtil.DetermineEndpointConfiguration(BindingType.Redirect, identityProvider.Endpoints.DefaultSignOnEndpoint, identityProvider.Metadata.SSOEndpoints);
            request.Destination = destination.Url;

            if (identityProvider.ForceAuth) {
                request.ForceAuthn = true;
            }

            // Check isPassive status
            if (context.Get<bool>(IdpIsPassive)) {
                request.IsPassive = true;
            }

            if (identityProvider.IsPassive) {
                request.IsPassive = true;
            }

            // Check if request should forceAuthn            
            if (context.Get<bool>(IdpForceAuthn)) {
                request.ForceAuthn = true;
            }

            // Check if protocol binding should be forced
            if (identityProvider.Endpoints.DefaultSignOnEndpoint != null) {
                if (!string.IsNullOrEmpty(identityProvider.Endpoints.DefaultSignOnEndpoint.ForceProtocolBinding)) {
                    request.ProtocolBinding = identityProvider.Endpoints.DefaultSignOnEndpoint.ForceProtocolBinding;
                }
            }

            // Save request message id to session
            Utility.AddExpectedResponseId(request.Id);

            switch (destination.Binding) {
            case BindingType.Redirect:
                logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpRedirect);

                var redirectBuilder = new HttpRedirectBindingBuilder
                {
                    SigningKey = config.ServiceProvider.SigningCertificate.PrivateKey,
                    Request = request.GetXml().OuterXml
                };
                if (context.Authentication != null &&
                    context.Authentication.AuthenticationResponseChallenge != null &&
                    context.Authentication.AuthenticationResponseChallenge.Properties != null &&
                    context.Authentication.AuthenticationResponseChallenge.Properties.Dictionary != null &&
                    context.Authentication.AuthenticationResponseChallenge.Properties.Dictionary.Count > 0)
                    redirectBuilder.RelayState = context.Authentication.AuthenticationResponseChallenge.Properties.Dictionary.ToDelimitedString();
                logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);

                var redirectLocation = request.Destination + "?" + redirectBuilder.ToQuery();
                return redirectLocation;
            case BindingType.Post:
                throw new NotImplementedException();
                //logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpPost);

                //var postBuilder = new HttpPostBindingBuilder(destination);

                //// Honor the ForceProtocolBinding and only set this if it's not already set
                //if (string.IsNullOrEmpty(request.ProtocolBinding)) {
                //    request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpPost;
                //}

                //var requestXml = request.GetXml();
                //XmlSignatureUtils.SignDocument(requestXml, request.Id, config.ServiceProvider.SigningCertificate);
                //postBuilder.Request = requestXml.OuterXml;

                //logger.DebugFormat(TraceMessages.AuthnRequestSent, postBuilder.Request);

                //context.Response.Write(postBuilder.GetPage());
                //break;
            case BindingType.Artifact:
                throw new NotImplementedException();
                //logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpArtifact);

                //var artifactBuilder = new HttpArtifactBindingBuilder(context, config);

                //// Honor the ForceProtocolBinding and only set this if it's not already set
                //if (string.IsNullOrEmpty(request.ProtocolBinding)) {
                //    request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpArtifact;
                //}

                //logger.DebugFormat(TraceMessages.AuthnRequestSent, request.GetXml().OuterXml);

                //artifactBuilder.RedirectFromLogin(destination, request);
                //break;
            default:
                logger.Error(SAML2.ErrorMessages.EndpointBindingInvalid);
                throw new Saml20Exception(SAML2.ErrorMessages.EndpointBindingInvalid);
            }
            throw new NotImplementedException();
        }