ASP.NET在控制器上的未授权访问应该返回401而不是200和登录页面

时间:2015-10-27 18:01:00

标签: asp.net asp.net-mvc asp.net-identity asp.net-core asp.net-core-mvc

ASP.NET 5应用程序中,我像这样配置了MVC和Identity框架:

app.UseMvc(config=>{
    config.MapRoute("Default", "{controller}/{action}/{id?}", new
            {
                controller = "Home",
                action = "Index"
            });
});

并添加身份服务:

   services.AddAuthentication();
   services.AddAuthorization();

   services.AddIdentity<CrmUser, CrmUserRole>(config => { 
         config.User.RequireUniqueEmail = true;
          })
          .AddUserStore<MongoUserStore>()
          .AddRoleStore<MongoUserStore>()
          .AddDefaultTokenProviders();

 app.UseIdentity()
    .UseCookieAuthentication(i => { i.LoginPath = "/Account/Login";});

示例定义如下:

public class MyApiController : Microsoft.AspNet.Mvc.Controller
{
    [Authorize]
    public async Task<ActionResult> Foo()
    {
        return Ok();
    }
}

这很好用,但我也有一些控制器,我想以API方式使用。在ASP.NET 5中,它们都具有相同的基类,因此API和视图控制器之间没有区别。

因此,在拨打需要授权的未经授权的API时,我会收到HTTP 200和“登录”页面,而不是HTTP 401

Shawn Wildermuth的博文中,我发现了这个

services.AddCookieAuthentication(config =>
    {
        config.LoginPath = "/Auth/Login";
        config.Events = new CookieAuthenticationEvents()
        {
            OnRedirect = ctx =>
            {
                if (ctx.Request.Path.StartsWithSegments("/api") &&
                ctx.Response.StatusCode == 200)
                {
                    ctx.Response.StatusCode =     (int)HttpStatusCode.Unauthorized;
                    return Task.FromResult<object>(null);
                }
                else
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                    return Task.FromResult<object>(null);
                }
            }
        };
    });

但这应该是预期的方法吗?对我来说,这有点味道。

3 个答案:

答案 0 :(得分:2)

此问题已在RC1修复。

点击此处查看GitHub评论:Issue

要升级到RC1,请转到http://get.asp.net

为了更加确定,您还可以在获取最新版本之前清除%userprofile%\.dnx\文件夹。

答案 1 :(得分:0)

对此的一个解决方案是使用以下标头发送请求:

[{"key":"X-Requested-With","value":"XMLHttpRequest"}]

以下是使用Postman 而不使用标题返回200和登录网页html的示例 Screenshot of Postman not sending the header returns 200 and login webpage html]

标题返回401且没有内容(请注意旁边没有勾号) With the header returns 401 and no content

示例应用程序基于具有单个用户身份验证的ASP.NET Core默认解决方案

为什么会这样: CookieAuthenticationEvents.OnRedirectToLogin()使用IsAjaxRequest(context.Request)来决定是返回401还是重定向。所以你必须有一个标题,使IsAjaxRequest(context.Request)返回true。如果您通过AJAX调用API,似乎很多JavaScript库会自动为您添加,但您可能没有使用它们。

您可能会发现有用的相关问题

此行为为introduced,因为提出了request OP(他们在问题中提到)

在撰写本文时,

链接到CookieAuthenticationEvents.csawk '/Jul 24/ && /987654321/' Input_file

答案 2 :(得分:0)

一个(解决方法)选项是使coockie选项将您重定向到控制器操作返回(未授权)结果 抱歉,我在使用手机回复时,我会尝试在使用自己的电脑时提高答案...