问题

当 IIS 7.0 上的 ASP.NET MVC 5 应用程序中的 IAuthorizationFilter 失败时,直接返回 401 和登录页面的简单方法是什么,避免 302 重定向?

可能的替代问题:这是一个坏主意吗?

——

背景

我实现了 Application_EndRequest() shim 来解决由 FormsAuthentication 引起的 AJAX 问题。它将所有 401 UNAUTHORIZED 转换为 302 FOUND(即重定向)。但是,这会导致其他问题,因为现在所有 302 重定向都转换为 401。所以为了解决这个问题,我去掉了 500 SERVER ERROR404 NOT FOUND 的重定向,我认为还有一些我错过了......

也许我对此进行了过度设计,但是在此练习之后,首先为 401 返回 302 似乎是不正确的。解决了一个问题,创造了新的问题。我认为技术上理想的答案是就地处理 401。然后服务器发送一个诚实的状态代码,无论 AJAX 与否,如果 AJAX 客户端接收到登录 HTML,这没什么大不了的。

——

我的进步

在没有 FormsAuthentication 的情况下使用 FormsAuthentication cookie

我尝试了一种方法,使用:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <error statusCode="401" responseMode="ExecuteURL" path="/Account/AuthReq" />
</httpErrors>

但是,为了完成这项工作,我必须从 FormsAuthentication 中提取 Web.config ,并且当我提取表单例份验证时,我的自定义 AuthorizeAttribute 停止运行。我认为我实际使用的 FormsAuthentication 代码很少,但我有点害怕摆脱它,因为我不想将自己的无知应用于管理安全身份验证 cookie。

据我所知,如果我不想要 401 -> 302 处理,下面的代码代表了我目前唯一依赖 FormsAuthentication 的地方。
/// <summary>
///     Stores this SessionIdentity in the Forms Authentication token for use next request
/// </summary>
public void Write(HttpContext httpContext) {
    httpContext.Response.AppendCookie(FormsAuthentication.GetAuthCookie(serialize(), false));
}

/// <summary>
///     Constructs a SessionIdentity from the Forms Authentication token
/// </summary>
public static SessionIdentity Read(HttpContext httpContext) {
    IIdentity identity = httpContext.User.Identity;
    return identity.IsAuthenticated
                ? deserialize(identity.Name)
                : Unauthenticated;
}

/// <summary>
///     Removes the SessionIdentity Forms Authentication token for the next request
/// </summary>
public static void Clear(HttpContext httpContext) {
    var clearAuthCookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
    clearAuthCookie.Expires = DateTime.Now.AddYears(-1);
    httpContext.Response.Cookies.Add(clearAuthCookie);
}

似乎我可以避免对 Web.Config 中 FormsAuthentication 的依赖,并且仍然能够使用 OEM 加密票证,只需利用 FormsAuthentication.Decrypt() 而不是我上面所做的 HttpContext.User.Identity 。我尚未调查此更改是否与全新的基于 Claims 的票证或 MVC5 中全新的 AuthenticationFilter 相关。

使用 AppHarbor 的 .NET 开放身份验证库

尽管我不确定这对我的场景是否正确,但对此处类似主题的一些答案表明无法禁用 FormsAuthentication 的 302 重定向操作。然而,很明显 ASP.NET 中没有包含替代身份验证机制。

AppHarbor 发布了 GitHub 的替代库,并在 their blog 上进行了讨论。

最佳答案

检查 SuppressFormsAuthenticationRedirect 属性。

然后编写自定义 Authorize 属性:

public class MyAuthorizeAttribute: AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.HttpContext.Response.StatusCode = 401;
        filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
        filterContext.Result = new ViewResult
        {
            ViewName = "~/Views/Account/Login.cshtml",
        };
    }
}

可用于装饰 protected Controller / Action :
[MyAuthorize]
public ActionResult Admin()
{
    return View();
}

显然,如果您不想让 401 状态代码接管,您可能还想删除 web.config 中的任何自定义错误页面。

关于asp.net - 401 未经授权的就地处理(无重定向)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20576697/

10-09 03:48