最好的办法来处理asp.net网页API未经身份验证的要求 [英] Best way to handle unauthenticated request in asp.net Web Api

查看:368
本文介绍了最好的办法来处理asp.net网页API未经身份验证的要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网页API 2中有一个标准的VS2013 MVC5项目。标准项目的设计方式,在 [授权] 属性简单地返回401状态code,如果请求未通过身份验证,而一个完全独立的模块嗅探任何401 codeS,停止他们,而是发送一个302重定向到 Startup.Auth.cs 文件中指定的登录页面。这是确定为MVC控制器,但真的很糟糕的网页API控制器,​​因为例如浏览器将自动重定向Ajax请求到登录的网址,所以你最终与即使响应文本登录页面只是一个HTML 200OK状态结束。

I have a standard VS2013 MVC5 project with a Web Api 2 in it. The way the standard project is designed, the [Authorize] attributes simply return a 401 status code if the request is not authenticated, while a totally separate module sniffs for any 401 codes, halts them, and instead sends a 302 redirect to the login page specified in the Startup.Auth.cs file. That's ok for Mvc controllers, but really stinks for Web Api controllers because for example browsers will automatically redirect ajax requests to the login url, so you ultimately end up with a 200OK status even though the response text is just the html of the login page.

这使得它很难写出好的JavaScript的,可以在这里你只需要告诉用户重新登录,与其他种类的错误的情况区分。理想情况下,我们应该能够根据状态code说,但JavaScript的从来没有看到401状态。什么是处理这个问题的最好方法?

That makes it hard to write good javascript that can distinguish between a case where you just need to tell the user to log back in versus other kinds of errors. Ideally we should be able to tell based on the status code, but javascript never ever sees the 401 status. What is the best way to handle this?

我首先想到的是写一个授权属性,但使用状态code 403,而不是401:

My first thought was to write an authorization attribute but use status code 403 instead of 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.");
        }
    }
}

当然,规格明确指出403是不正确的:

Of course, specifications explicitly state that 403 is incorrect:

授权不会帮助和请求不应该重复

Authorization will not help and the request SHOULD NOT be repeated

我的另一个想法是,也许我应该完全禁用asp.net的401重定向模块和处理自定义授权属性重定向,因为即使MVC的意见是糟糕的,因为它不会让你重定向到根据不同的登录页面凡在该网站的用户试图访问。

My other thought is that maybe I should disable asp.net's 401 redirect module altogether and handle redirects in custom authorization attributes, because even for Mvc views it is lousy because it doesn't allow you to redirect to different login pages depending on where in the site the user is trying to visit.

是否有其他更好的处理这种方式?

Are there other, better approaches to handling this?

推荐答案

下面是我能找到更多的研究。 401是由OWIN中间件截获。但是,OWIN不支持使用地图法的分支结构。所以在 Startup.cs 文件我有这样的:

Here's what I was able to find with a bit more research. The 401 is intercepted by the OWIN middleware. But, OWIN does support branching configurations using the Map method. So in the Startup.cs file I have this:

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

    }
}

其中, ConfigureAuth 是来自于 Startup.Auth.cs 文件,而<$默认的配置方法C $ C> ConfigureAuth2 是该方法的一个副本,但与 LOGINPATH 选项在 UseCookieAuthentication 方法,它看起来像这样:

where ConfigureAuth is the default configuration method that comes in the Startup.Auth.cs file, while ConfigureAuth2 is a duplicate of that method but with the LoginPath option left unspecified in the UseCookieAuthentication method, which looks like this:

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))
            }
        });

按照文档,当 LOGINPATH 是不确定的,401响应将不会被拦截此分支。

According to the documentation, when the LoginPath is unspecified, 401 responses won't be intercepted for this branch.

所以用这个方法,我分支的所有请求分为两种不同的配置 - 所有的 / API 请求将不配置在401重定向状态,而一切被配置重定向到登录页面。

So with this approach I'm branching all requests into two different configurations--all /api requests get configured not to redirect on 401 statuses, while everything else gets configured to redirect to the login page.

这<一个href=\"http://stackoverflow.com/questions/22215428/run-different-frameworks-side-by-side-with-owin\">SO问题讨论了一些关于分支的配置。

This SO question talked a bit about branching the configuration.

我仍然不知道这是最好的办法,但。

I'm still not sure if this is the best approach though.

这篇关于最好的办法来处理asp.net网页API未经身份验证的要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆