Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 在MVC中设置403错误页_Asp.net Mvc 3_C# 4.0_Http Status Code 403_Unauthorized - Fatal编程技术网

Asp.net mvc 3 在MVC中设置403错误页

Asp.net mvc 3 在MVC中设置403错误页,asp.net-mvc-3,c#-4.0,http-status-code-403,unauthorized,Asp.net Mvc 3,C# 4.0,Http Status Code 403,Unauthorized,我重写该类以执行自定义授权 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute { protected override void HandleUnauthorizedRequest(Syste

我重写该类以执行自定义授权

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult(403);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}
现在在web.config中,我已经配置了403错误页面

<customErrors defaultRedirect="/Shared/Error" mode="On">
  <error statusCode="403" redirect="/Shared/UnAuthorize" />
</customErrors>

但浏览器仍然显示403的默认错误页,
这里我缺少的是任何想法,对我来说,HttpStatusCodeResult(403)似乎位于错误的if分支中。我认为代码应该是这样的:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult(403);
        }
    }
}

除了Max B,还有一个小提示/说明。回答:

使用自定义错误时,我会生成一个
错误控制器
,并生成一个未授权操作结果,然后执行以下操作:

<error statusCode="403" redirect="/Errors/UnAuthorize" />

这样,我可以在控制器中添加额外信息或执行其他操作,例如:

  • 就像登录到数据库,有人试图访问经过身份验证的区域
  • 错误计数
  • 可能是一个bug或报表,他们可以使用它来发送管理员信息

通过这种方式,您可以更多地控制正在发生的事情。

或者您可以使用此替代解决方案,而不是使用:

filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult(403);
您可以将其更改为:

if (filterContext.HttpContext.Request.IsAuthenticated)
        {               
            throw new UnauthorizedAccessException();
        }
并重写控制器/BaseController中的方法OneException(ExceptionContext filterContext除外)

protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled)
        {
            return;
        }

        if (filterContext.Exception.GetType() == typeof(UnauthorizedAccessException))
        {   
            filterContext.Result = new ViewResult
            {
                ViewName = "~/Views/Error/NotAuthorized.cshtml"
            };
            filterContext.ExceptionHandled = true;
            return;
        }

        base.OnException(filterContext);
    }

当我写我自己的自定义属性时,我遇到了与您完全相同的问题。当我在web.config中添加“customErrors”标记时,403的自定义错误页面将不会显示。 我就是这样解决的:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
           filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary(
                    new
                        { 
                            controller = "Error", 
                            action = "Unauthorised" 
                        })
                ); 

        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

分配了一个我想显示给filterContext.Result的路由,而不是分配403 HttpStatusCode。

我知道这是一个非常老的问题,但我为可能有相同问题的人发布。和我一样,我也有同样的问题并解决了它。如果要在web.config中触发customErrors元素,可以在下面进行尝试

protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
    throw new HttpException(403, "Forbidden");
}
如何在mvc中处理401(未授权)、403(禁止)和500(内部服务器错误)。用于ajax/非ajax调用和aspx表单下的身份验证

无论请求是否为ajax,都可以对其进行修改,以不同方式处理各种未捕获的异常,并做出不同的反应。auth部分允许它绕过任何常规mvc web表单重定向到登录页面,而是返回401 unauthorized,这样您的客户端js框架就可以更容易地对http状态401/403做出反应

// FilterConfig.cs:
filters.Add(new ApplicationAuthorizeAttribute());
filters.Add(new ApplicationHandleErrorAttribute());

public class ApplicationAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // Note: To reach here, a Web.config path-specific rule 'allow users="?"' is needed (otherwise it redirects to login)

        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;

        if (request.IsAjaxRequest())
        {
            response.SuppressFormsAuthenticationRedirect = true;
            response.TrySkipIisCustomErrors = true;
        }

        filterContext.Result = new HttpUnauthorizedResult();
    }
}

public class ApplicationHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        var exception = context.Exception is AggregateException
            ? ((AggregateException)context.Exception).InnerExceptions.First()
            : context.Exception;
        var request = context.HttpContext.Request;
        var response = context.HttpContext.Response;
        var isAjax = request.IsAjaxRequest();

        if (exception is MyCustomPermissionDeniedException)
        {
            filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
            response.TrySkipIisCustomErrors = isAjax;
            filterContext.ExceptionHandled = true;
            return;
        }

#if DEBUG
        if (!isAjax)
        {
            // Show default aspx yellow error page for developers
            return;
        }
#endif

        var requestUri = request.Url == null ? "" : request.Url.AbsoluteUri;
        MyCustomerLogger.Log(exception, requestUri);

        response.Clear();
        response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;

#if DEBUG
        var errorMessage = exception.Message;
#else
        var errorMessage = "An error occurred, please try again or contact the administrator.";
#endif

        response.Write(isAjax
            ? JsonConvert.SerializeObject(new {Message = errorMessage})
            : errorMessage);
        response.End();
        response.TrySkipIisCustomErrors = true;
        context.ExceptionHandled = true;
    }
}
Web.config:

<system.webServer>

<authentication mode="Forms">
  <forms name=".MYAUTHCOOKIE" protection="All" loginUrl="/Account/Login" timeout="18000" slidingExpiration="true" enableCrossAppRedirects="false" />
</authentication>

<authorization>
  <deny users="?" />
</authorization>

</system.webServer>

<!-- ajax api security done via ApplicationAuthorizeAttribute -->
<location path="api">
  <system.web>
    <authorization>
      <allow users="?"/>
    </authorization>
  </system.web>
</location>
jquery处理错误的客户端代码示例:

$.ajaxSetup({
    complete: function onRequestCompleted(xhr, textStatus) {
        if (xhr.readyState == 4 && xhr.status == 401) {
            // Not needed with smart status: && xhr.responseText.substring(0, 150).indexOf("<title>Log in") != -1
            //location.href = "/Account/Login";
            alert("Your session has timed out.");
        }
    }
});
$.ajaxSetup({
完成:函数onRequestCompleted(xhr,textStatus){
if(xhr.readyState==4&&xhr.status==401){
//智能状态不需要:&&xhr.responseText.substring(0,150).indexOf(“登录”)!=-1
//location.href=“/Account/Login”;
警报(“您的会话已超时。”);
}
}
});

或者,您可以让所有身份验证通过ApplicationHandleErrorAttribute,并删除该web.config deny users=“?”。但是我有一个传统的aspx页面,它没有点击mvc过滤,所以我想要deny users=“?”

实际上我也在做同样的事情,Shared is controller和Unauthorized is action,但我仍然收到相同的默认http 403页面错误,而不是我定义的pagevery helpfull link@SaboorAwan。我也试过同样的方法,但运气不好。从未调用控制器方法。你是用这个答案还是你发布的链接来解决问题的?你可能想测试一下。。。它在经过身份验证时绕过了授权要求。与其他解决方案相比,它工作完美且更容易。您将它放在何处?我想补充一下。它可以是特定于区域的吗?@RageCompex您可以将它们放在自定义属性类中。您能详细介绍一下“特定区域”吗?我的50美分,使用System.Net.HttpStatusCode枚举获取状态代码。例如:(int)HttpStatusCode.Forbidden您实际上应该能够将F12(resharper反编译?ms symbol server?)导入到:ControllerActionInvoker、HandleErrorAttribute、AuthorizeAttribute。这本书很有启发性。ControllerActionInvoker以不同的方式使用4种过滤器类型中的每一种。(auth、action、result、exception)例如,转到您的控制器,在基类“controller”上点击F12,在“iaAuthorizationFilter”上点击F12,在“OnAuthorization”上点击Shift-F12。
$.ajaxSetup({
    complete: function onRequestCompleted(xhr, textStatus) {
        if (xhr.readyState == 4 && xhr.status == 401) {
            // Not needed with smart status: && xhr.responseText.substring(0, 150).indexOf("<title>Log in") != -1
            //location.href = "/Account/Login";
            alert("Your session has timed out.");
        }
    }
});