Пример #1
0
        private static CommandResult HandleRequest(UnbindResult unbindResult, IOptions options)
        {
            var request = Saml2LogoutRequest.FromXml(unbindResult.Data);

            var idp = options.IdentityProviders[request.Issuer];

            if (options.SPOptions.SigningServiceCertificate == null)
            {
                throw new ConfigurationErrorsException(string.Format(CultureInfo.InvariantCulture,
                                                                     "Received a LogoutRequest from \"{0}\" but cannot reply because single logout responses " +
                                                                     "must be signed and there is no signing certificate configured. Looks like the idp is " +
                                                                     "configured for Single Logout despite AuthServices not exposing that functionality in the metadata.",
                                                                     request.Issuer.Id));
            }

            if (idp.SingleLogoutServiceResponseUrl == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                                                  "Received a LogoutRequest from \"{0}\" but cannot reply because on logout endpoint is " +
                                                                  "configured on the idp. Set a SingleLogoutServiceUrl if the idp is configured manually, " +
                                                                  "or check that the idp metadata contains a SingleLogoutService endpoint.",
                                                                  idp.EntityId.Id));
            }

            var response = new Saml2LogoutResponse(Saml2StatusCode.Success)
            {
                DestinationUrl     = idp.SingleLogoutServiceResponseUrl,
                SigningCertificate = options.SPOptions.SigningServiceCertificate,
                SigningAlgorithm   = idp.OutboundSigningAlgorithm,
                InResponseTo       = request.Id,
                Issuer             = options.SPOptions.EntityId,
                RelayState         = unbindResult.RelayState
            };

            options.SPOptions.Logger.WriteInformation("Got a logout request " + request.Id
                                                      + ", responding with logout response " + response.Id);

            var result = Saml2Binding.Get(idp.SingleLogoutServiceBinding).Bind(response);

            result.TerminateLocalSession = true;
            return(result);
        }
Пример #2
0
        private static CommandResult InitiateLogout(HttpRequestData request, string returnPath, IOptions options)
        {
            var idpEntityId = ClaimsPrincipal.Current.FindFirst(AuthServicesClaimTypes.LogoutNameIdentifier)?.Issuer
                              ?? ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier)?.Issuer;

            CommandResult    commandResult;
            IdentityProvider idp;

            if (idpEntityId != null &&
                options.IdentityProviders.TryGetValue(new EntityId(idpEntityId), out idp) &&
                ClaimsPrincipal.Current.FindFirst(AuthServicesClaimTypes.SessionIndex) != null &&
                idp.SingleLogoutServiceUrl != null &&
                options.SPOptions.SigningServiceCertificate != null &&
                !idp.DisableOutboundLogoutRequests)
            {
                var logoutRequest = idp.CreateLogoutRequest();

                commandResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
                                .Bind(logoutRequest);

                commandResult.RequestState = new StoredRequestState(
                    idp.EntityId,
                    GetReturnUrl(request, returnPath, options),
                    logoutRequest.Id,
                    null);

                commandResult.SetCookieName = "Kentor." + logoutRequest.RelayState;
            }
            else
            {
                commandResult = new CommandResult
                {
                    HttpStatusCode = HttpStatusCode.SeeOther,
                    Location       = GetReturnUrl(request, returnPath, options)
                };
            }

            commandResult.TerminateLocalSession = true;

            return(commandResult);
        }
Пример #3
0
        public CommandResult Run(HttpRequestData request, IOptions options)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            var binding = Saml2Binding.Get(request);

            if (binding != null)
            {
                try
                {
                    var samlResponse = Saml2Response.Read(binding.Unbind(request));

                    return(ProcessResponse(options, samlResponse));
                }
                catch (FormatException ex)
                {
                    throw new BadFormatSamlResponseException(
                              "The SAML Response did not contain valid BASE64 encoded data.", ex);
                }
                catch (XmlException ex)
                {
                    throw new BadFormatSamlResponseException(
                              "The SAML response contains incorrect XML", ex);
                }
            }

            throw new NoSamlResponseFoundException();
        }
Пример #4
0
        public static CommandResult Run(
            HttpRequestData request,
            string returnPath,
            IOptions options)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var binding = Saml2Binding.Get(request);

            if (binding != null)
            {
                var unbindResult = binding.Unbind(request, options);
                VerifyMessageIsSigned(unbindResult, options);
                switch (unbindResult.Data.LocalName)
                {
                case "LogoutRequest":
                    return(HandleRequest(unbindResult, options));

                case "LogoutResponse":
                    return(HandleResponse(unbindResult, request));

                default:
                    throw new NotImplementedException();
                }
            }

            return(InitiateLogout(request, returnPath, options));
        }
Пример #5
0
        private static CommandResult InitiateLogout(HttpRequestData request, Uri returnUrl, IOptions options)
        {
            string idpEntityId       = null;
            Claim  sessionIndexClaim = null;

            if (request.User != null)
            {
                idpEntityId       = request.User.FindFirst(AuthServicesClaimTypes.LogoutNameIdentifier)?.Issuer;
                sessionIndexClaim = request.User.FindFirst(AuthServicesClaimTypes.SessionIndex);
            }

            IdentityProvider idp;
            var knownIdp = options.IdentityProviders.TryGetValue(new EntityId(idpEntityId), out idp);

            options.SPOptions.Logger.WriteVerbose("Initiating logout, checking requirements for federated logout"
                                                  + "\n  Issuer of LogoutNameIdentifier claim (should be Idp entity id): " + idpEntityId
                                                  + "\n  Issuer is a known Idp: " + knownIdp
                                                  + "\n  Session index claim (should have a value): " + sessionIndexClaim
                                                  + "\n  Idp has SingleLogoutServiceUrl: " + idp?.SingleLogoutServiceUrl?.OriginalString
                                                  + "\n  There is a signingCertificate in SPOptions: " + (options.SPOptions.SigningServiceCertificate != null)
                                                  + "\n  Idp configured to DisableOutboundLogoutRequests (should be false): " + idp?.DisableOutboundLogoutRequests);

            CommandResult commandResult;

            if (idpEntityId != null &&
                knownIdp &&
                sessionIndexClaim != null &&
                idp.SingleLogoutServiceUrl != null &&
                options.SPOptions.SigningServiceCertificate != null &&
                !idp.DisableOutboundLogoutRequests)
            {
                var logoutRequest = idp.CreateLogoutRequest(request.User);

                commandResult = Saml2Binding.Get(idp.SingleLogoutServiceBinding)
                                .Bind(logoutRequest);

                commandResult.RelayState   = logoutRequest.RelayState;
                commandResult.RequestState = new StoredRequestState(
                    idp.EntityId,
                    returnUrl,
                    logoutRequest.Id,
                    null);

                if (!options.SPOptions.Compatibility.DisableLogoutStateCookie)
                {
                    commandResult.SetCookieName = "Kentor." + logoutRequest.RelayState;
                }

                options.SPOptions.Logger.WriteInformation("Sending logout request to " + idp.EntityId.Id);
            }
            else
            {
                commandResult = new CommandResult
                {
                    HttpStatusCode = HttpStatusCode.SeeOther,
                    Location       = returnUrl
                };
                options.SPOptions.Logger.WriteInformation("Doing a local only logout.");
            }

            commandResult.TerminateLocalSession = true;

            return(commandResult);
        }