【问题标题】:How to return a custom view OR a JSON when the Authorization fail, instead of showing a username and password dialog授权失败时如何返回自定义视图或 JSON,而不是显示用户名和密码对话框
【发布时间】:2014-01-05 22:38:05
【问题描述】:

我正在开发一个 asp.net mvc 4 Web 应用程序,我编写了以下自定义授权类:-

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

    public class CheckUserPermissionsAttribute : AuthorizeAttribute
    {

        public string Model { get; set; }
        public string Action { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsAuthenticated)
                return false;
            //code goes here
            if (!repository.can(ADusername, Model, value)) // implement this method based on your tables and logic
            {

                return false;
                //base.HandleUnauthorizedRequest(filterContext);
            }
            return true;

           // base.OnAuthorization(filterContext);
        }
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {

                var viewResult = new JsonResult();
                viewResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
                viewResult.Data = (new { IsSuccess = "Unauthorized", description = "Sorry, you do not have the required permission to perform this action." });
                filterContext.Result = viewResult;

            }
            else
            {
                var viewResult = new ViewResult();

                viewResult.ViewName = "~/Views/Errors/_Unauthorized.cshtml";

                filterContext.Result = viewResult;
            }

            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

但我现在面临的唯一问题是,如果授权失败,则将提示用户输入用户名和密码,尽管我已经覆盖 HandleUnauthorizedRequest 以根据请求是否为 AJAX 返回视图或 JSON .所以你能建议为什么在授权失败时提示用户输入他的用户名和密码,而不是接收 _unauthorized 视图或包含错误消息的 JSON

【问题讨论】:

    标签: asp.net asp.net-mvc-4 iis authorize-attribute


    【解决方案1】:

    但我现在面临的唯一问题是,如果授权失败 然后会提示用户输入用户名和密码, 虽然我已经覆盖了 HandleUnauthorizedRequest 以返回一个 根据请求是否为 AJAX 查看或 JSON。

    那是因为您绝对总是在 HandleUnauthorizedRequest 方法中点击以下行:

    base.HandleUnauthorizedRequest(filterContext);
    

    你知道这条线是做什么的吗?它调用基本方法。你知道基本方法是做什么的吗?它返回 401 状态码。您知道在使用表单身份验证的 ASP.NET 应用程序中返回 401 状态响应代码时会发生什么吗?您将获得登录页面。

    是的,如果您使用 AJAX 或其他东西并打算返回一些 JSON 或其他东西,请确保永远不会调用基本内容。顺便说一句,在您的 else 条件下,您似乎正在尝试渲染一些 ~/Views/Errors/_Unauthorized.cshtml 视图,这显然再次无用,因为您还调用了将简单地重定向到登录页面的基本方法。

    我认为在我回答的这个阶段你已经知道该怎么做:去掉你的 HandleUnauthorizedRequest 方法的最后一行,你通过调用基本方法将所有的努力都扔进了垃圾箱。

    如果您想正确执行操作并返回 401 状态代码而不是获取登录页面而是返回一些自定义 JSON,您可以使用 Response 对象上的 SuppressFormsAuthenticationRedirect 属性。如果您使用的是没有此属性的旧版 .NET 框架,您可能会发现 following blog post 很有用,Phil Haack 在其中解释了如何处理这种情况。

    【讨论】:

    • 是的,我删除了 base.HandleUnauthorizedRequest(filterContext);现在一切正常。但是你能告诉我为什么返回 401 而不是 true 或 false 更好吗? ..顺便说一句,我没有使用表单身份验证,而是我的应用程序使用 Windows 身份验证。
    • 为什么返回 401 比返回 true 或 false 更好?因为 HTTP 协议规定,如果用户无权访问某些资源,服务器应返回 401 状态码。那么,既然 HTTP 协议已经具备处理这种情况所需的一切,为什么还要用真假东西重新发明轮子呢?
    • 但由于在我的 ajax 调用(ajax.actionlink 和 ajax.beginform)中,我希望 OnSuccess 脚本上的 JSON 显示未经授权的消息,所以如果我返回 401,那么我需要调用 onfailure 脚本.所以目前事情进展顺利,我正在考虑保持现状?如果这可能会导致其他问题,您能提出建议吗?
    • 不,它可能不会导致其他问题。只是处理 401 状态码的正确方法是订阅 onerror 回调。正如我在之前的评论中所说,当用户无权访问某些资源时,正确的做法是返回 401 状态码。但是您当然可以违反 HTTP 协议并在 AJAX 请求的 success 回调中处理您的错误 :-)
    • 但在这种情况下,我将如何同时返回 JSON 和 401。这可以从我的 HandleUnauthorizedRequest 方法返回两个值吗??
    猜你喜欢
    • 2016-09-04
    • 1970-01-01
    • 2018-07-04
    • 2021-04-21
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 2021-08-18
    • 2017-07-19
    相关资源
    最近更新 更多