Adding [Authorize] to controller failing to redirect to Identity Login route. ASP.NET CORE 3.1 MVC

2k Views Asked by At

I have a asp.net core 3.1 MVC project. It has Identity added to it. When I normally click a button to go to login page or registration page, it works as expected. However the moment I am using [Authorize] on controller or global authorization filter in Startup.cs file, the page does not redirect to the login page.

The redirection link in that case is

https://localhost:5001/Account/Login?ReturnUrl=%2F

where as the link should be

https://localhost:5001/Identity/Account/Login?ReturnUrl=%2F

If you look closely the area name "Identity" is missing from the link that I am getting. I am gussing there is something wrong with my Startup.cs file configuration but cannot figure out what. I have Multiple Areas in my project along with Identity

Startup.cs

public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        /*services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();*/

        services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
        services.AddTransient<IEmailSender, EmailSender>();
        services.AddControllersWithViews();
        services.AddRazorPages().AddMvcOptions(options => options.Filters.Add(new AuthorizeFilter()));
        services.AddSingleton<IConfiguration>(Configuration);
        services.AddMvc(options => options.EnableEndpointRouting = false);
        services.AddMvc().AddRazorRuntimeCompilation();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {

            endpoints.MapRazorPages().RequireAuthorization();
            endpoints.MapControllerRoute(
               name: "Identity",
               pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

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

Any help would be much appreciate. thank you.

2

There are 2 best solutions below

1
On BEST ANSWER

Define the login path in services.ConfigureApplicationCookie like this:

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = new PathString("/Identity/Account/Login");
    //other properties
});
1
On

I just had a look around on GitHub and found Account/Login being set as a default in CookieAuthenticationDefaults. I then found that being used by PostConfigureCookieAuthenticationOptions, which sets sensible configuration options when none have been specified. From that, it looks to me like you have to configure that like this:

services.ConfigureApplicationCookie(x => x.LoginPath = "/identity/account/login");

x in this case is of type CookieAuthenticationOptions, which is what PostConfigureCookieAuthenticationOptions is reading from.