61

In the previous ASP.NET MVC, there was an option to redirect to the login action, if the user was not authenticated.

I need the same thing with ASP.NET Core, so I:

  1. created a ASP.NET Core project from the Visual Studio template
  2. added [Authorize] to some arbitrary action
  3. opened the corresponding view in my browser

I don't expect a redirect because I haven't configured it. BUT, it automatically redirects to the login action!

Where/how is this option set?

2
  • 2
    The framework is able to find the login action, as it uses convention over configuration. Commented Oct 24, 2016 at 12:51
  • 16
    @sudheeshix If that is not documented anywhere, then it is a form of magic. Actually, even if it's documented. There's too much of this going on nowadays, especially in ASP.NET. Commented Oct 24, 2016 at 13:08

9 Answers 9

39

With ASP.NET Core version 2.1.0, this has changed, now you can use the extensions:

services.ConfigureApplicationCookie(options => options.LoginPath = "/login");

or

services
.AddAuthentication()
.AddCookie(options =>
{
    options.LoginPath = "/login";
    options.LogoutPath = "/logout";
});

You can see more about migrating in to 2.0 in this article.

Sign up to request clarification or add additional context in comments.

1 Comment

I would like to add that ConfigureApplicationCookie should be placed after AddIdentity. Otherwise it has no effect.
24

The redirect did not work in my app at all and none of the solutions here fixed it, but using Status Code Pages did:

app.UseStatusCodePages(async context => 
{
    var response = context.HttpContext.Response;

    if (response.StatusCode == (int)HttpStatusCode.Unauthorized ||
            response.StatusCode == (int)HttpStatusCode.Forbidden)
        response.Redirect("/Authentication");
});

app.UseMvc(...        

4 Comments

Where in the pipeline call stack did you place this?
It should be the first one or one of the first, but certainly before app.UseMvc
This does not seem to work for me when hosting my ASP.NET Core 6 app on an IIS webserver. The server would still just return 401 Unauthorized to the client after the session expired instead of redirecting the user to the login page. All other solutions I found (ConfigureApplicationCookie, AddCookie etc.) didn't work either.
@Chris You probably need move it higher in your service registration stack
13

You can configure the path using CookieAuthenticationOptions class.

Something like this.

app.UseCookieAuthentication(new CookieAuthenticationOptions {
        LoginPath = new PathString("/Login/"),
        AuthenticationType = "My-Magical-Authentication",
        // etc...
        },
});

Here is the updated link for CookieAuthenticationHandler

5 Comments

I saw that in this article, but that says "Using Cookie Middleware without ASP.NET Core Identity". I am using Identity.
Also, I not only want to control this setting, I want to understand where/how it is happening. I don't understand how it knows to find my login view. That is what I want to understand.
Please look into this code - github.com/aspnet/Security/blob/dev/src/…
@Anuraj link is dead, you know the new one?
8

this code block in the startup file works for me in .Net Core 3.1

services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });

1 Comment

I've added this but it hasn't changed anything, it still redirects to /Account .
6

For anyone that's interested it can also be done with the AddIdentity service provider.

services.AddIdentity<User, IdentityRole>(options =>
    {
        options.Cookies.ApplicationCookie.AutomaticAuthenticate = true;
        options.Cookies.ApplicationCookie.AutomaticChallenge = true;
        options.Cookies.ApplicationCookie.LoginPath = "/Auth/Login";
    })
    .AddEntityFrameworkStores<MehandiContext>()
    .AddDefaultTokenProviders();

And as explained here: https://stackoverflow.com/a/41643105/5784635

I attempted this in April 2017 and "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0" doesn't redirect I had to use the 1.0.1 version

4 Comments

Works fine for me in version 1.1.0 (July 2017)
Anton / @Wouter, are you guys using .NETCore?
Using .net core 1.1
In 2.0 and later versions: If you want to tweak Identity cookies, they're no longer part of IdentityOptions. Rather we have to use ConfigureApplicationCookie method. Such as services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn"); for more, see here: learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/…
5

The way that dotnet core scaffolds Cookie Authentication is using the Identity framework. For a fresh project, I recommend going to the command line and doing something like this:

dotnet new mvc -o ExampleProject --auth Individual

You can gain full control of the authentication process by modifying the folowing method in Startup.cs to look like this:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<IdentityUser, IdentityRole>()
        // services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddRazorPagesOptions(options =>
        {
            options.AllowAreas = true;
            options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
            options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
        });

    services.ConfigureApplicationCookie(options =>
    {
        options.LoginPath = $"/Identity/Account/Login";
        options.LogoutPath = $"/Identity/Account/Logout";
        options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
    });

    // using Microsoft.AspNetCore.Identity.UI.Services;
    services.AddSingleton<IEmailSender, EmailSender>();
}

Reference: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-2.2&tabs=visual-studio#full

My personal preference for authentication is the hybrid flow of IdentityServer4, gives you a scope for configuring multiple applications using a single sign on.

1 Comment

did the trick for me. using asp.net core 3.1 mvc proj, thanks
2

placing should be important in configuration middleware piplines.

app.UseSession();
        app.UseAuthentication();
        app.UseStatusCodePages(context => {
            var response = context.HttpContext.Response;
            if (response.StatusCode == (int)HttpStatusCode.Unauthorized ||
                response.StatusCode == (int)HttpStatusCode.Forbidden)
                response.Redirect("/Login");
            return Task.CompletedTask;
        });
        app.UseClaimsMiddleware();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Login}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });

1 Comment

I'm using ASP.Net Core .NET 8 and the app.UseStatusCodePages worked for me. In my OnAuthorization filter I'm checking the Users security Level in a table (if they have access) and then if not enough access, then I'm using using context.Result = new ForbidResult(), which takes me to my custom page. Thanks for the code! In my instance I created a "AccessDenied" Controller and View. The result is very clean!
1

The reason why application knows where the login page is because by default "Login" page supposed to be placed in "Account" folder and page supposed to be called "Login" so, like "Account/Login"

So, if you change the "Account" folder to something else like "AccountFolder" then you will get a http 404 as page not found.

To explicitly specify where the login page is go to "Program.cs" file add the following "LoginPath" defination.

builder.Services.AddAuthentication().AddCookie("YourCookieName", options =>
{
    options.Cookie.Name = "YourCookieName";
    options.LoginPath = "/Account/Login";
});

The above example is from .NET 6

1 Comment

Hello, I have done this but a 401 error page is shown :-(
0

The code above works fine for me using Identity Authentication in asp net core 3.1

  1. First you must add the following code to your Startup.cs file
services.ConfigureApplicationCookie(options =>
{
     options.Cookie.Name = ".AspNetCore.Identity.Application";
     options.AccessDeniedPath = "/User/PageNotAllowed";               
});
  1. Create an Action in your Controller responsable for manage the user account (In my case is the User class)
public IActionResult PageNotAllowed()
{
    return View();
}
  1. Final step you just need to create the PageNotAllowed View at your own taste.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.