Redirect to login when unauthorized in ASP.NET Core
C#asp.netasp.net Coreasp.net Identityasp.net Core-MvcC# Problem Overview
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:
- created a ASP.NET Core project from the Visual Studio template
- added
[Authorize]
to some arbitrary action - 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?
C# Solutions
Solution 1 - C#
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.
Solution 2 - C#
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(...
Solution 3 - C#
You can configure the path using CookieAuthenticationOptions
class.
Something like this.
app.UseCookieAuthentication(new CookieAuthenticationOptions {
LoginPath = new PathString("/Login/"),
AuthenticationType = "My-Magical-Authentication",
// etc...
},
});
Solution 4 - C#
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
Solution 5 - C#
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>();
}
My personal preference for authentication is the hybrid flow of IdentityServer4, gives you a scope for configuring multiple applications using a single sign on.
Solution 6 - C#
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;
});
Solution 7 - C#
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();
});
Solution 8 - C#
The code above works fine for me using Identity Authentication in asp net core 3.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";
});
- Create an Action in your Controller responsable for manage the user account (In my case is the User class)
public IActionResult PageNotAllowed()
{
return View();
}
- Final step you just need to create the
PageNotAllowed
View at your own taste.