예제 #1
0
        private void rewritePathIfShortcutUrl()
        {
            var ewfResolvers = new[]
            {
                new ShortcutUrlResolver(
                    "ewf",
                    ConnectionSecurity.SecureIfPossible,
                    () => {
                    var page = MetaLogicFactory.CreateBasicTestsPageInfo();
                    return(page.UserCanAccessResource ? page : null);
                }),
                new ShortcutUrlResolver(
                    "ewf/impersonate",
                    ConnectionSecurity.SecureIfPossible,
                    () => {
                    if (!UserManagementStatics.UserManagementEnabled)
                    {
                        return(null);
                    }
                    var page = MetaLogicFactory.CreateSelectUserPageInfo("");
                    return(page.UserCanAccessResource ? page : null);
                })
            };

            var url = GetRequestAppRelativeUrl(Request);

            foreach (var resolver in ewfResolvers.Concat(GetShortcutUrlResolvers()))
            {
                if (resolver.ShortcutUrl.ToLower() != url.ToLower())
                {
                    continue;
                }

                // Redirect to the same shortcut URL to fix the connection security, normalize the base URL, normalize the shortcut URL casing, or any combination of
                // these.
                var canonicalAbsoluteUrl = GetDefaultBaseUrl(resolver.ConnectionSecurity.ShouldBeSecureGivenCurrentRequest(false)) +
                                           resolver.ShortcutUrl.PrependDelimiter("/");
                if (canonicalAbsoluteUrl != RequestState.Url)
                {
                    NetTools.Redirect(canonicalAbsoluteUrl);
                }

                if (ConfigurationStatics.IsIntermediateInstallation && !RequestState.IntermediateUserExists)
                {
                    throw new AccessDeniedException(true, null);
                }

                var resource = resolver.Function();
                if (resource == null)
                {
                    throw new AccessDeniedException(false, resolver.LogInPageGetter?.Invoke());
                }
                if (resource is ExternalResourceInfo)
                {
                    NetTools.Redirect(resource.GetUrl());
                }
                HttpContext.Current.RewritePath(getTransferPath(resource), false);
                break;
            }
        }
예제 #2
0
        /// <summary>
        /// This method will not work properly unless the application is initialized, RequestState is not null, and the authenticated user is available.
        /// </summary>
        private void handleError(object sender, EventArgs e)
        {
            // The reason we don't write our error page HTML directly to the response, like ASP.NET does, is that this limits the functionality of the error pages
            // and requires them to be built differently than all other pages. We don't transfer to the error pages either, because application errors can occur at
            // any time in the ASP.NET life cycle and transferring to a page causes it to immediately execute even if it's not the normal time for this to happen.
            // Redirecting works, but has the drawback of not being able to send proper HTTP error codes in the response since the redirects themselves require a
            // particular code. TransferRequest seems to be the only method that gives us everything we want.

            ExecuteWithBasicExceptionHandling(
                delegate {
                // This code should happen first to prevent errors from going to the Windows event log.
                var exception = Server.GetLastError();
                Server.ClearError();

                RequestState.RollbackDatabaseTransactions();
                DataAccessState.Current.ResetCache();

                var errorIsWcf404 = exception.InnerException is System.ServiceModel.EndpointNotFoundException;

                // We can remove this as soon as requesting a URL with a vertical pipe doesn't blow up our web applications.
                var argException = exception as ArgumentException;
                var errorIsBogusPathException = argException != null && argException.Message == "Illegal characters in path.";

                // In the first part of this condition we check to make sure the base exception is also an HttpException, because we had a problem with WCF wrapping an
                // important non-HttpException inside an HttpException that somehow had a code of 404. In the second part of the condition (after the OR) we use
                // InnerException instead of GetBaseException because the ResourceNotAvailableException always has an inner exception that describes the specific
                // problem that occurred. The third part of the condition handles ResourceNotAvailableExceptions from HTTP handlers such as CssHandler; these are not
                // wrapped with another exception.
                if ((exception is HttpException && (exception as HttpException).GetHttpCode() == 404 && exception.GetBaseException() is HttpException) ||
                    exception.InnerException is ResourceNotAvailableException || exception is ResourceNotAvailableException || onErrorProneAspNetHandler ||
                    errorIsWcf404 || errorIsBogusPathException)
                {
                    setStatusCode(404);
                    return;
                }

                if (!handleErrorIfOnErrorPage("An exception occurred", exception))
                {
                    var accessDeniedException = exception.GetBaseException() as AccessDeniedException;
                    var pageDisabledException = exception.GetBaseException() as PageDisabledException;
                    if (accessDeniedException != null)
                    {
                        if (accessDeniedException.CausedByIntermediateUser)
                        {
                            transferRequest(MetaLogicFactory.CreateIntermediateLogInPageInfo(RequestState.Url), true);
                        }
                        else
                        {
                            var userNotYetAuthenticated = RequestState.UserAccessible && AppTools.User == null && UserManagementStatics.UserManagementEnabled;
                            if (userNotYetAuthenticated && !ConfigurationStatics.IsLiveInstallation && !RequestState.ImpersonatorExists)
                            {
                                transferRequest(MetaLogicFactory.CreateSelectUserPageInfo(RequestState.Url), true);
                            }
                            else if (userNotYetAuthenticated && FormsAuthStatics.FormsAuthEnabled)
                            {
                                if (accessDeniedException.LogInPage != null)
                                {
                                    // We pass false here to avoid complicating things with ThreadAbortExceptions.
                                    Response.Redirect(accessDeniedException.LogInPage.GetUrl(), false);

                                    CompleteRequest();
                                }
                                else
                                {
                                    transferRequest(MetaLogicFactory.CreateLogInPageInfo(RequestState.Url), true);
                                }
                            }
                            else
                            {
                                transferRequest(getErrorPage(MetaLogicFactory.CreateAccessDeniedErrorPageInfo(!RequestState.HomeUrlRequest)), true);
                            }
                        }
                    }
                    else if (pageDisabledException != null)
                    {
                        transferRequest(MetaLogicFactory.CreatePageDisabledErrorPageInfo(pageDisabledException.Message), true);
                    }
                    else
                    {
                        RequestState.SetError("", exception);
                        transferRequest(getErrorPage(MetaLogicFactory.CreateUnhandledExceptionErrorPageInfo()), true);
                    }
                }
            },
                true,
                true);
        }
예제 #3
0
        private void rewritePathIfShortcutUrl()
        {
            var ewfResolvers = new[]
            {
                new ShortcutUrlResolver(
                    "ewf",
                    ConnectionSecurity.SecureIfPossible,
                    () => {
                    var page = MetaLogicFactory.CreateBasicTestsPageInfo();
                    return(page.UserCanAccessResource ? page : null);
                }),
                new ShortcutUrlResolver(
                    "ewf/impersonate",
                    ConnectionSecurity.SecureIfPossible,
                    () => {
                    if (!UserManagementStatics.UserManagementEnabled)
                    {
                        return(null);
                    }
                    var page = MetaLogicFactory.CreateSelectUserPageInfo("");
                    return(page.UserCanAccessResource ? page : null);
                })
            };

            var url = GetRequestAppRelativeUrl(Request);

            foreach (var resolver in ewfResolvers.Concat(GetShortcutUrlResolvers()))
            {
                if (resolver.ShortcutUrl.ToLower() != url.ToLower())
                {
                    continue;
                }

                // Redirect to the same shortcut URL to fix the connection security, normalize the base URL, normalize the shortcut URL casing, or any combination of
                // these.
                var canonicalAbsoluteUrl = GetDefaultBaseUrl(resolver.ConnectionSecurity.ShouldBeSecureGivenCurrentRequest(false)) +
                                           resolver.ShortcutUrl.PrependDelimiter("/");
                if (canonicalAbsoluteUrl != RequestState.Url)
                {
                    NetTools.Redirect(canonicalAbsoluteUrl);
                }

                if (ConfigurationStatics.IsIntermediateInstallation && !RequestState.IntermediateUserExists)
                {
                    throw new AccessDeniedException(true, null);
                }

                var resource = resolver.Function();
                if (resource == null)
                {
                    throw new AccessDeniedException(false, resolver.LogInPageGetter?.Invoke());
                }
                if (resource is ExternalResourceInfo)
                {
                    NetTools.Redirect(resource.GetUrl());
                }
                HttpContext.Current.RewritePath(getTransferPath(resource), false);
                return;
            }

            // ACME challenge response; see https://tools.ietf.org/html/rfc8555#section-8.3
            var absoluteUrl = new Uri(RequestState.Url);

            if (absoluteUrl.Scheme == "http" && absoluteUrl.Port == 80 && absoluteUrl.AbsolutePath.StartsWith("/.well-known/acme-challenge/"))
            {
                var systemManager = ConfigurationStatics.MachineConfiguration?.SystemManager;
                if (systemManager != null)
                {
                    NetTools.Redirect(
                        systemManager.HttpBaseUrl.Replace("https://", "http://") +
                        "/Pages/Public/AcmeChallengeResponse.aspx?Token={0}".FormatWith(HttpUtility.UrlEncode(absoluteUrl.Segments.Last())));
                }
            }
        }