如何在ASP.NET Core中返回401而不是302?

时间:2016-08-06 05:36:24

标签: c# asp.net-core asp.net-core-identity

当用户未登录时,我试图让ASP.NET Core Identity返回401.我已经为我的方法添加了[Authorize]属性,而不是返回401它返回302.我已经尝试了大量的建议,但似乎没有任何效果,包括services.Configureapp.UseCookieAuthentication设置LoginPathnull或{{1} }。

8 个答案:

答案 0 :(得分:42)

ASP.NET Core 2.x

开始
services.ConfigureApplicationCookie(options =>
{
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = 401;    
        return Task.CompletedTask;
    };
});

答案 1 :(得分:14)

如果请求标头包含 X-Requested-With:XMLHttpRequest ,则状态代码将为401而不是302

private static bool IsAjaxRequest(HttpRequest request)
    {
        return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
            string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal);
    }

请参阅gitHub:https://github.com/aspnet/Security/blob/5de25bb11cfb2bf60d05ea2be36e80d86b38d18b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs#L40-L52

答案 2 :(得分:11)

services.Configure<IdentityOptions>(options =>
{
   options.Cookies.ApplicationCookie.LoginPath = new PathString("/");
   options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
   {
      OnRedirectToLogin = context =>
      {
         if (context.Request.Path.Value.StartsWith("/api"))
         {
            context.Response.Clear();
            context.Response.StatusCode = 401;
            return Task.FromResult(0);
         }
         context.Response.Redirect(context.RedirectUri);
         return Task.FromResult(0);
      }
   };
});

来源:

https://www.illucit.com/blog/2016/04/asp-net-5-identity-302-redirect-vs-401-unauthorized-for-api-ajax-requests/

答案 3 :(得分:11)

对于Asp.net Core 2 使用这个INSTEAD

package main


import (
 "fmt"
)


type Example struct {
  Id []int
  Name []string
}

func (data *Example) AppendExample(id int,name string) {
   data.Id = append(data.Id, id)
   data.Name = append(data.Name, name)
}

var MyMap map[string]Example

func main() {

  var object Example
  object.AppendExample(1,"SomeText")

  MyMap = make(map[string]Example)
  MyMap["key1"] = object
  fmt.Println(MyMap)
}

答案 4 :(得分:5)

好的,在asp.net core unit tests中挖掘后,我终于找到了一个有效的解决方案。您必须在致电services.AddIdentity

时添加以下内容
services.AddIdentity<ApplicationUser, IdentityRole>(o => {
    o.Cookies.ApplicationCookie.AutomaticChallenge = false;
});

答案 5 :(得分:1)

对于使用Identity和Cookie身份验证的 ASP.NET Core 3.x (预览版),窍门是:

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<IdentityContext>()
    .AddDefaultTokenProviders()
    .AddRoles<IdentityRole>();

services.ConfigureApplicationCookie(options =>
{
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.Headers["Location"] = context.RedirectUri;
        context.Response.StatusCode = 401;
        return Task.CompletedTask;
    };
});

这是我们到处都可以看到的不同变化形式。但是,这里的重点是必须之后{strong> ConfigureApplicationCookie 指定 AddIdentity 。这是“悲伤”的事实。 SO answer终于在黑暗中带来了光明。

我已经head头了一天,尝试了不同的尝试:

  • 覆盖Authorize属性(不再需要在3.x中覆盖)
  • 用cookie指定options.Cookie.EventType(运行时错误)
  • options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme(据说JWT承载不会重定向到登录页面)
  • 当然还要配置ApplicationCookie(但在调用AddIdentity之前是无效的。

那一切都不起作用。但是有了上面的答案,我终于得到了401 UnAuthorized返回(顺便说一句,应该是 UnAuthenticated

答案 6 :(得分:0)

对我而言,仅在ASP.NET Core 2.2.0上有效:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(
        options =>
        {
            options.LoginPath = new PathString("/Account/Login");
            options.LogoutPath = new PathString("/Account/Logout");

            options.Events.OnRedirectToLogin = context =>
            {
                if (context.Request.Path.StartsWithSegments("/api")
                    && context.Response.StatusCode == StatusCodes.Status200OK)
                {
                    context.Response.Clear();
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    return Task.CompletedTask;
                }
                context.Response.Redirect(context.RedirectUri);
                return Task.CompletedTask;
            };
        }
    );

答案 7 :(得分:0)

接下来,我将先前的答案合并为以下内容:

1。 Startup.cs

services.ConfigureApplicationCookie(options =>
        {
            options.LoginPath = new PathString("/Account/Login");
            options.LogoutPath = new PathString("/Account/Logout");

            options.Events.OnRedirectToAccessDenied = context =>
            {
                if (wlt_AjaxHelpers.IsAjaxRequest(context.Request))
                {
                    context.Response.Clear();
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    return Task.CompletedTask;
                }
                context.Response.Redirect(context.RedirectUri);
                return Task.CompletedTask;
            };
        });

2。助手自定义类

public static class wlt_AjaxHelpers
     {

        public static bool IsAjaxRequest( HttpRequest request )
        {

            return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
                string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal);
        }

    }