Redirect to login when unauthorized in ASP.NET Cor

2020-02-09 07:00发布

问题:

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?

回答1:

You can configure the path using CookieAuthenticationOptions class.

Something like this.

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


回答2:

With the current aspnet 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.



回答3:

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:

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


回答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://docs.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.