How to return 401 instead of 302 in ASP.NET Core?

后端 未结 8 2018
迷失自我
迷失自我 2020-11-29 03:36

I\'m trying to get ASP.NET Core Identity to return 401 when a user isn\'t logged in. I\'ve added an [Authorize] attribute to my method and instead of returning

相关标签:
8条回答
  • 2020-11-29 03:49

    Okay after digging around in the asp.net core unit tests I finally found a working solution. You have to add the following to your call to services.AddIdentity

    services.AddIdentity<ApplicationUser, IdentityRole>(o => {
        o.Cookies.ApplicationCookie.AutomaticChallenge = false;
    });
    
    0 讨论(0)
  • 2020-11-29 03:52

    For ASP.NET Core 3.x (preview) using Identity with Cookie authentication this is what did the trick:

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

    This is what we see around everywhere in different variations. BUT, the essential point here is that ConfigureApplicationCookie must be specified AFTER AddIdentity. It's "sad" but true. This SO answer finally brought light in the darkness.

    I have been scratching my head for over a day and tried many different variations:

    • Override the Authorize attribute (not so much to override in 3.x anymore)
    • Specifying options.Cookie.EventType with a Cookie (runtime error)
    • options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme (It was said that JWT bearer would not redirect to a login page)
    • And of course configuring the ApplicationCookie (but before the call to AddIdentity which doesn't work.

    That all didn't work. But with the answer above I finally got the 401 Unauthorized returned (which should be Unauthenticated by the way)

    0 讨论(0)
  • 2020-11-29 03:52

    For me on ASP.NET Core 2.2.0 only this worked:

    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;
                };
            }
        );
    
    0 讨论(0)
  • 2020-11-29 03:55
    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);
          }
       };
    });
    

    Source:

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

    0 讨论(0)
  • 2020-11-29 03:57

    As of ASP.NET Core 2.x:

    services.ConfigureApplicationCookie(options =>
    {
        options.Events.OnRedirectToLogin = context =>
        {
            context.Response.StatusCode = 401;    
            return Task.CompletedTask;
        };
    });
    
    0 讨论(0)
  • 2020-11-29 03:58

    For asp.net mvc core USE THIS INSTEAD

     services.ConfigureApplicationCookie(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;
                };
            });
    
    0 讨论(0)
提交回复
热议问题