/// <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); }
/// <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()); } }
/// <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); } } }
/// <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) { } } }