【问题标题】:Best way to handle unauthenticated request in asp.net Web Api在 asp.net Web Api 中处理未经身份验证的请求的最佳方法
【发布时间】:2015-12-17 01:28:33
【问题描述】:

我有一个标准的 VS2013 MVC5 项目,其中包含一个 Web Api 2。标准项目的设计方式,[Authorize] 属性在请求未通过身份验证时仅返回 401 状态代码,而完全独立的模块嗅探任何 401 代码,暂停它们,而是将 302 重定向发送到登录页面在Startup.Auth.cs 文件中指定。这对 Mvc 控制器来说没问题,但对于 Web Api 控制器来说真的很糟糕,因为例如浏览器会自动将 ajax 请求重定向到登录 url,所以即使响应文本只是登录页面的 html,你最终也会得到 200OK 状态。

这使得编写好的 JavaScript 很难区分您只需要告诉用户重新登录的情况与其他类型的错误。理想情况下,我们应该能够根据状态码进行判断,但 javascript 永远不会看到 401 状态。处理这个问题的最佳方法是什么?

我的第一个想法是写一个授权属性,但使用状态码 403 而不是 401:

public class ApiAuthorizationAttribute : System.Web.Http.AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
        {
            base.OnAuthorization(actionContext);
        }
        else
        {
            actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Not signed in.");
        }
    }
}

当然,specifications 明确指出 403 不正确:

授权无济于事,请求不应重复

我的另一个想法是,也许我应该完全禁用 asp.net 的 401 重定向模块并在自定义授权属性中处理重定向,因为即使对于 Mvc 视图,它也很糟糕,因为它不允许您重定向到不同的登录页面,具体取决于用户尝试访问的网站位置。

还有其他更好的方法来处理这个问题吗?

【问题讨论】:

  • 这个过程在看到未经授权的结果时进行重定向。有没有一种方法可以让它只在使用 MVC 控制器的请求上运行。例如。 MVC 继承自 Controller,但 web api 是 ApiController。所以你可以根据控制器类型重定向,这样 webapi 的东西就不会被重定向。

标签: c# asp.net asp.net-mvc asp.net-web-api2 http-status-code-401


【解决方案1】:

这是我通过更多研究发现的。 401 被 OWIN 中间件拦截。但是,OWIN 确实支持使用 Map 方法的分支配置。所以在Startup.cs 文件中我有这个:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Map(new PathString("/api"), site => ConfigureAuth2(site));
        ConfigureAuth(app);

    }
}

其中ConfigureAuthStartup.Auth.cs 文件中的默认配置方法,而ConfigureAuth2 是该方法的副本,但LoginPath 选项在UseCookieAuthentication 方法中未指定,看起来像这个:

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

根据documentation,当LoginPath未指定时,不会截取此分支的401响应。

因此,通过这种方法,我将所有请求分为两种不同的配置——所有/api 请求都配置为不重定向到 401 状态,而其他所有请求都配置为重定向到登录页面。

这个SO question 谈到了配置分支。

我仍然不确定这是否是最好的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 2023-03-18
    • 1970-01-01
    • 2020-11-13
    相关资源
    最近更新 更多