Prevent redirect to /Account/Login in asp.net core 2.2

I faced this issue and made a workaround , I just create a controller "Account" and write the Redirection inside it:

    public class AccountController : Controller
    {
        public IActionResult Login()
        {
            return RedirectToAction("Login", "Home");
        }
    }

 services.ConfigureApplicationCookie(options => {
            options.AccessDeniedPath = "/Account/Login";
            options.LoginPath = "/Account/Denied";
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
            options.Events.OnRedirectToLogin = context => {
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                return Task.CompletedTask;
            };
        });

Hey there and welcome to StackOverflow 👋

The behaviour you experience is linked to the fact that you use ASP.NET Identity. When you call services.AddIdentity, behind the scenes a cookie-based authentication scheme is registered and set as the default challenge scheme, as you can see in the code here on GitHub.

Even though you registered a cookie authentication scheme yourself and set it as the default scheme, the specific default schemes — like AuthenticateScheme, ChallengeScheme, SignInScheme, etc... — take precendence. DefaultScheme is used by the authentication system only when the specific one is not set.

To answer your question, you could apply the configuration settings to the ASP.NET Identity cookie options by using the helper method services.ConfigureApplicationCookie, like so:

// ===== Add Identity ========
services.AddIdentity<User, IdentityRole>(o =>
{
    o.User.RequireUniqueEmail = true;
    o.Tokens.EmailConfirmationTokenProvider = "EMAILCONF";
    // I want to be able to resend an `Email` confirmation email
    // o.SignIn.RequireConfirmedEmail = true; 
}).AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ContestContext>()
    .AddTokenProvider<EmailConfirmationTokenProvider<User>>("EMAILCONF")
    .AddDefaultTokenProviders();

services.Configure<DataProtectionTokenProviderOptions>(o =>
    o.TokenLifespan = TimeSpan.FromHours(3)
);

services.Configure<EmailConfirmationTokenProviderOptions>(o =>
    o.TokenLifespan = TimeSpan.FromDays(2)
);

// ===== Configure Identity =======
service.ConfigureApplicationCookie(options =>
{
    options.Cookie.Name = "auth_cookie";
    options.Cookie.SameSite = SameSiteMode.None;
    options.LoginPath = new PathString("/api/contests");
    options.AccessDeniedPath = new PathString("/api/contests");

    // Not creating a new object since ASP.NET Identity has created
    // one already and hooked to the OnValidatePrincipal event.
    // See https://github.com/aspnet/AspNetCore/blob/5a64688d8e192cacffda9440e8725c1ed41a30cf/src/Identity/src/Identity/IdentityServiceCollectionExtensions.cs#L56
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };
});

It also means that you can safely remove the part where you add a cookie-based authentication scheme since this is taken care of by ASP.NET Identity itself.

Let me know how you go!


If you are not using ASP.NET Identity, you can follow the same pattern that kuldeep chopra mentioned in another answer, but instead inside the AddCookie method:

public void ConfigureServices(IServiceCollection services)
{
 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie((o) =>
    {
      o.Cookie.HttpOnly = true;
      o.LoginPath = string.Empty;
      o.AccessDeniedPath = string.Empty;
      o.Events.OnRedirectToLogin = context =>
      {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
      };
    });
}

It is not enough to just set the paths to empty/null.