web-dev-qa-db-fra.com

Comment retourner 401 au lieu de 302 dans ASP.NET Core?

J'essaie d'obtenir ASP.NET Core Identity pour renvoyer 401 lorsqu'un utilisateur n'est pas connecté. J'ai ajouté un [Authorize] attribut à ma méthode et au lieu de renvoyer 401, il renvoie 302. J'ai essayé une tonne de suggestions mais rien ne semble fonctionner, y compris services.Configure et app.UseCookieAuthentication définissant LoginPath sur null ou PathString.Empty.

24
Eric B

Depuis ASP.NET Core 2.x:

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

Pour asp.net mvc core UTILISEZ CECI AU LIEU

 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;
            };
        });
12
Francis Ofosu
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);
      }
   };
});

La source:

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

11
Mark Perry

Bon après avoir fouillé dans les tests unitaires de base asp.net J'ai finalement trouvé une solution de travail. Vous devez ajouter ce qui suit à votre appel à services.AddIdentity

services.AddIdentity<ApplicationUser, IdentityRole>(o => {
    o.Cookies.ApplicationCookie.AutomaticChallenge = false;
});
5
Eric B

Pour ASP.NET Core 3.x (préversion) utilisant l'authentification Identité avec cookie, voici ce qui a fait l'affaire:

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

C'est ce que nous voyons partout dans différentes variantes. MAIS, le point essentiel ici est que ConfigureApplicationCookie doit être spécifié [~ # ~] après [~ # ~] AddIdentity. C'est "triste" mais vrai. Cette SO réponse a finalement apporté de la lumière dans l'obscurité.

Je me gratte la tête depuis plus d'une journée et j'ai essayé différentes variations:

  • Remplacez l'attribut Authorize (plus tant à remplacer dans 3.x)
  • Spécification d'options.Cookie.EventType avec un cookie (erreur d'exécution)
  • options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme (Il a été dit que le porteur JWT ne redirigerait pas vers une page de connexion)
  • Et bien sûr, configurer le ApplicationCookie (mais avant l'appel à AddIdentity qui ne fonctionne pas.

Tout cela n'a pas fonctionné. Mais avec la réponse ci-dessus, j'ai finalement obtenu le 401 UnAuthorized retourné (qui devrait être UnAuthenticated d'ailleurs)

0
Bernoulli IT

Pour moi, sur ASP.NET Core 2.2.0, cela a fonctionné:

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
SirGordon