/// <summary>
        /// Handle error status codes.
        /// </summary>
        /// <remarks>
        /// This is limited to handling the following:
        ///  - 401 Unauthorized
        ///  - 403 Forbidden
        ///  - 404 Not Found
        ///  - 500 Server Error
        /// </remarks>
        /// <param name="httpContext">The HTTP context instance.</param>
        /// <param name="statusCode">The HTTP status code.</param>
        /// <param name="statusDescription">The HTTP status description.</param>
        /// <returns><c>true</c> if the error status code was handled; otherwise, <c>false</c>.</returns>
        public static bool HandleErrorStatusCode(this HttpContextWrapper httpContext, int statusCode, string statusDescription)
        {
            var statusCodesToHandle = new List <int> {
                401, 403, 404, 500
            };

            // Only handle specific status code errors and only when custom error pages are enabled
            if (httpContext.IsCustomErrorEnabled && statusCodesToHandle.Contains(statusCode))
            {
                // Clear response, set error code and skip IIS custom error page
                httpContext.Response.Clear();
                httpContext.Response.StatusCode             = statusCode;
                httpContext.Response.TrySkipIisCustomErrors = true;

                // Add status description which will be used in the ErrorController errors pages
                if (!string.IsNullOrEmpty(statusDescription))
                {
                    httpContext.Items.Add("ErrorStatusCodeDescription", statusDescription);
                }

                // Clear server
                httpContext.Server.ClearError();

                var errorPath = string.Format("~/Error/Http{0}", statusCode);

                if (HttpRuntime.UsingIntegratedPipeline)
                {
                    // Transfer to error path
                    httpContext.Server.TransferRequest(errorPath, true);
                }
                else
                {
                    // Get original path
                    string path = httpContext.Request.Path;

                    // Rewrite to error path
                    httpContext.RewritePath(errorPath, false);

                    // Process error path request for response
                    new InternalHttpHandler().ProcessRequest(httpContext);

                    // Rewrite path to original path so the user appears to be on the url they originally requested
                    httpContext.RewritePath(path, false);
                }

                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns a response by executing the Error controller with the specified action.
        /// </summary>
        /// <param name="action">
        /// The action.
        /// </param>
        private void DisplayErrorPage(string action)
        {
            var routeData = new RouteData();

            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", action);

            this.Server.ClearError();
            this.Response.Clear();

            var httpContext    = new HttpContextWrapper(this.Context);
            var requestContext = new RequestContext(httpContext, routeData);

            IController errorController =
                ControllerBuilder.Current.GetControllerFactory().CreateController(
                    new RequestContext(
                        httpContext,
                        routeData),
                    "Error");

            // Clear the query string, in particular to avoid HttpRequestValidationException being re-raised
            // when the error view is rendered by the Error Controller.
            httpContext.RewritePath(httpContext.Request.FilePath, httpContext.Request.PathInfo, string.Empty);

            errorController.Execute(requestContext);
        }
        /// <summary>
        /// Handles the Begin event of the request control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void context_BeginRequest(object sender, EventArgs e)
        {
            #region LoadApplicationRules Event

            if (Manager.ApplicationRulesNeedLoading)
            {
                // call load application rules
                var loadRulesArgs = new LoadRulesEventArgs();
                OnLoadApplicationRules(loadRulesArgs);

                Manager.LoadApplicationRules(loadRulesArgs);
            }

            #endregion

            var context      = new HttpContextWrapper(((HttpApplication)sender).Context);
            var rewrittenUrl = Manager.RunRules(context);

            // make sure the rewrittenUrl returned is not null
            // a null value can indicate a proxy request
            if (rewrittenUrl != null)
            {
                // configure IIS7 for worker request
                // this will not do anything if the IIS7 worker request is not found
                Manager.ModifyIIS7WorkerRequest(context);

                // get the path and query for the rewritten URL
                string rewrittenUrlPath = rewrittenUrl.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped);

                // rewrite path using new URL
                if (HttpRuntime.UsingIntegratedPipeline && Manager.Configuration.Rewriter.AllowIis7TransferRequest)
                {
                    var request = context.Request;
                    var headers = new NameValueCollection(context.Request.Headers);

                    int    transferCount       = 1;
                    string transferCountHeader = headers["X-Rewriter-Transfer"];
                    if (!String.IsNullOrEmpty(transferCountHeader) && Int32.TryParse(transferCountHeader, out transferCount))
                    {
                        transferCount++;
                    }

                    headers["X-Rewriter-Transfer"] = transferCount.ToString(CultureInfo.InvariantCulture);

                    context.Server.TransferRequest(
                        rewrittenUrlPath,
                        true,
                        request.HttpMethod,
                        headers
                        );
                }
                else
                {
                    context.RewritePath(rewrittenUrlPath, Manager.Configuration.Rewriter.RebaseClientPath);
                }
            }
        }
        /// <summary>
        /// Handles the PostMapRequestHandler event of the context control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void context_PostMapRequestHandler(object sender, EventArgs e)
        {
            var context = new HttpContextWrapper(((HttpApplication)sender).Context);

            // check to see if this is a proxy request
            if (context.Items.Contains(Manager.ProxyHandlerStorageName))
            {
                var proxy = context.Items[Manager.ProxyHandlerStorageName] as IHttpProxyHandler;

                context.RewritePath("~" + proxy.ResponseUrl.PathAndQuery);
                context.Handler = proxy;
            }
        }
        private void OnBeginRequest(object sender, EventArgs e)
        {
            HttpApplication app     = (HttpApplication)sender;
            HttpContextBase context = new HttpContextWrapper(app.Context);
            string          path    = context.Request.Path;

            //
            // Check to see if we are dealing with a request for the "elmah.axd" handler
            // and if so, we need to rewrite the path!
            //

            int handlerPosition = path.IndexOf(_handlerPathWithForwardSlash, StringComparison.OrdinalIgnoreCase);

            if (handlerPosition >= 0)
            {
                context.RewritePath(
                    path.Substring(0, handlerPosition + _handlerPathLength),
                    path.Substring(handlerPosition + _handlerPathLength),
                    context.Request.QueryString.ToString());
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Determines whether node is accessible to user.
        /// </summary>
        /// <param name="controllerTypeResolver">The controller type resolver.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="context">The context.</param>
        /// <param name="node">The node.</param>
        /// <returns>
        ///     <c>true</c> if accessible to user; otherwise, <c>false</c>.
        /// </returns>
        public bool IsAccessibleToUser(IControllerTypeResolver controllerTypeResolver, DefaultSiteMapProvider provider, HttpContext context, SiteMapNode node)
        {
            // Is security trimming enabled?
            if (!provider.SecurityTrimmingEnabled)
            {
                return(true);
            }

            // Is it an external node?
            var nodeUrl = node.Url;

            if (nodeUrl.StartsWith("http") || nodeUrl.StartsWith("ftp"))
            {
                return(true);
            }

            // Is it a regular node?
            var mvcNode = node as MvcSiteMapNode;

            if (mvcNode == null)
            {
                throw new AclModuleNotSupportedException(
                          Resources.Messages.AclModuleDoesNotSupportRegularSiteMapNodes);
            }

            // Clickable? Always accessible.
            if (mvcNode.Clickable == false)
            {
                return(true);
            }

            // Time to delve into the AuthorizeAttribute defined on the node.
            // Let's start by getting all metadata for the controller...
            var controllerType = controllerTypeResolver.ResolveControllerType(mvcNode.Area, mvcNode.Controller);

            if (controllerType == null)
            {
                return(false);
            }

            // Find routes for the sitemap node's url
            HttpContextBase httpContext    = new HttpContextWrapper(context);
            string          originalPath   = httpContext.Request.Path;
            var             originalRoutes = RouteTable.Routes.GetRouteData(httpContext);

            httpContext.RewritePath(nodeUrl, true);

            HttpContextBase httpContext2 = new HttpContext2(context);
            RouteData       routes       = mvcNode.GetRouteData(httpContext2);

            if (routes == null)
            {
                return(true); // Static URL's will have no route data, therefore return true.
            }
            foreach (var routeValue in mvcNode.RouteValues)
            {
                routes.Values[routeValue.Key] = routeValue.Value;
            }
            if (!routes.Route.Equals(originalRoutes.Route) || originalPath != nodeUrl || mvcNode.Area == String.Empty)
            {
                routes.DataTokens.Remove("area");
                //routes.DataTokens.Remove("Namespaces");
                //routes.Values.Remove("area");
            }
            var requestContext = new RequestContext(httpContext, routes);

            // Create controller context
            var controllerContext = new ControllerContext();

            controllerContext.RequestContext = requestContext;

            // Whether controller is built by the ControllerFactory (or otherwise by Activator)
            bool factoryBuiltController = false;

            try
            {
                string controllerName = requestContext.RouteData.GetRequiredString("controller");
                controllerContext.Controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext, controllerName) as ControllerBase;
                factoryBuiltController       = true;
            }
            catch
            {
                try
                {
                    controllerContext.Controller = Activator.CreateInstance(controllerType) as ControllerBase;
                }
                catch
                {
                }
            }

            ControllerDescriptor controllerDescriptor = null;

            if (typeof(IController).IsAssignableFrom(controllerType))
            {
                controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
            }
            else if (typeof(IAsyncController).IsAssignableFrom(controllerType))
            {
                controllerDescriptor = new ReflectedAsyncControllerDescriptor(controllerType);
            }

            ActionDescriptor actionDescriptor = null;

            try
            {
                actionDescriptor = controllerDescriptor.FindAction(controllerContext, mvcNode.Action);
            }
            catch
            {
            }
            if (actionDescriptor == null)
            {
                actionDescriptor = controllerDescriptor.GetCanonicalActions().Where(a => a.ActionName == mvcNode.Action).FirstOrDefault();
            }

            // Verify security
            try
            {
                if (actionDescriptor != null)
                {
#if NET35
                    IEnumerable <AuthorizeAttribute> authorizeAttributesToCheck =
                        actionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).OfType
                        <AuthorizeAttribute>().ToList()
                        .Union(
                            controllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).OfType
                            <AuthorizeAttribute>().ToList());
#else
                    IFilterProvider      filterProvider = ResolveFilterProvider();
                    IEnumerable <Filter> filters;

                    // If depencency resolver has an IFilterProvider registered, use it
                    if (filterProvider != null)
                    {
                        filters = filterProvider.GetFilters(controllerContext, actionDescriptor);
                    }
                    // Otherwise use FilterProviders.Providers
                    else
                    {
                        filters = FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor);
                    }

                    IEnumerable <AuthorizeAttribute> authorizeAttributesToCheck =
                        filters
                        .Where(f => typeof(AuthorizeAttribute).IsAssignableFrom(f.Instance.GetType()))
                        .Select(f => f.Instance as AuthorizeAttribute);
#endif

                    // Verify all attributes
                    foreach (var authorizeAttribute in authorizeAttributesToCheck)
                    {
                        try
                        {
                            var currentAuthorizationAttributeType = authorizeAttribute.GetType();

                            var builder             = new AuthorizeAttributeBuilder();
                            var subclassedAttribute =
                                currentAuthorizationAttributeType == typeof(AuthorizeAttribute) ?
                                new InternalAuthorize(authorizeAttribute) :    // No need to use Reflection.Emit when ASP.NET MVC built-in attribute is used
                                (IAuthorizeAttribute)builder.Build(currentAuthorizationAttributeType).Invoke(null);

                            // Copy all properties
                            ObjectCopier.Copy(authorizeAttribute, subclassedAttribute);

                            if (!subclassedAttribute.IsAuthorized(controllerContext.HttpContext))
                            {
                                return(false);
                            }
                        }
                        catch
                        {
                            // do not allow on exception
                            return(false);
                        }
                    }
                }

                // No objection.
                return(true);
            }
            finally
            {
                // Restore HttpContext
                httpContext.RewritePath(originalPath, true);

                // Release controller
                if (factoryBuiltController)
                {
                    ControllerBuilder.Current.GetControllerFactory().ReleaseController(controllerContext.Controller);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Catchall handler when errors are thrown outside the MVC pipeline
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender, EventArgs e)
        {
            var ex          = Server.GetLastError();
            var contextBase = new HttpContextWrapper(Context);

            try
            {
                if ((ex as HttpException).GetHttpCode() == 404)
                {
                    var s = "~/Home/Redir" + contextBase.Request.FilePath;
                    contextBase.RewritePath(s, false);
                    contextBase.Server.TransferRequest(s);
                }
            }
            catch {}

            if (Context.Items["ErrorID"] != null)
            {
                return;  //this one has already been handled in one of the MVC error filters
            }
            if (ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

            Server.ClearError();
            if (ex == null)
            {
                return;
            }
            var code = (ex is HttpException) ? (ex as HttpException).GetHttpCode() : 500;

            var bAjax    = IsAjaxRequest();
            var sMessage = (bAjax) ? "AJAX call error" : "";
            var eid      = Logging.WriteDebugInfoToErrorLog(sMessage, ex);

            Context.Items.Add("ErrorID", eid);  //to keep us from doing this again in the same call

            Response.Clear();

            if (bAjax)
            {
                //this is a json call; tryskip will return our IDs in response.write, 500 will throw in jquery
                Response.TrySkipIisCustomErrors = true;
                Response.StatusCode             = 500;
                Response.StatusDescription      = String.Format("{0} Application Error", Utils.ApplicationName);
                Response.ContentType            = "application/json";
                Response.Write(JsonConvert.SerializeObject(new ErrResponsePoco {
                    DbErrorId = eid
                }));
                Response.End();
            }
            else
            {
                try
                {
                    SiteUtils.ReturnViaCode(contextBase, code);
                }
                // ReSharper disable once EmptyGeneralCatchClause
                catch (Exception) { }
            }
        }