Requirement is that I have MVC & WebAPI in the project. MVC views will be delivered for initial rendering like Login, base views of features (ex:- Users/Index, Dashboard/Index etc..) Web APIs will be used for other work within these views via AJAX with JWT.
I am using Asp.Net core Identity for user management related work running on .Net 5.0
I am confused with configuring multiple identity schemes and the proper configuration of authentication/authorization pipeline in conigureservices() & configure() in startup.
To configure multiple auth schemes I referred to https://stackoverflow.com/a/64887479/2058413 since it's done using same versions that I use. So my startup methods are below which is similar to the code in that thread.
public void ConfigureServices(IServiceCollection services) { string connectionString = Configuration.GetConnectionString("default"); services.AddDbContext<AppDBContext>(c => c.UseSqlServer(connectionString)); services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<AppDBContext>(); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(x => { x.LoginPath = "/Account/Login"; x.ExpireTimeSpan = TimeSpan.FromMinutes(10d); x.AccessDeniedPath = "/Account/Register"; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("123456")), ValidateIssuer = false, ValidateAudience = false }; }); services.AddAuthorization(options => { var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme); defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser(); options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build(); }); services.AddControllersWithViews(); }
My App configure method is below
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
Then the test method in controller(where user should get redirected to after authentication) is below
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public IActionResult Index()
{
return View();
}
To my understanding the order of the pipeline configuration is correct. Now here are the problems I face.
As specified in .AddCookie(option=>) , user doesn't get redirected to login page. However, if I remove the JwtBearerDefaults.AuthenticationScheme from the services.AddAuthorization(…) it gets redirected to login page properly. Why is that?
So I remove JwtBearerDefaults.AuthenticationScheme; which takes me to login and after successful login I can see that HttpContext.User.Identity.IsAuthenticated is set to true. But it doesn't redirect to Home/Index. No errors thrown and in browser console [network tab] it shows a 302 and redirect back to login. Since I have added [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] to Index method in HomeController, I tried removing the scheme and adding [Authorize] and tried again. Still it gets redirected to login page. This is another thing I am confused about.
So I removed everything related to dual scheme authentication and left the ConfigureService() with below code
string connectionString = Configuration.GetConnectionString("default"); services.AddDbContext<AppDBContext>(c => c.UseSqlServer(connectionString)); services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<AppDBContext>(); services.AddControllersWithViews();
Now everything works fine (redirection to login if not authenticated and also redirects to /Home/Index after authorization).
I went through below links as well about multi scheme authentication, but I am still confused with this pipeline configuration. ASP.NET Core WebAPI Cookie + JWT Authentication https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2 https://mitchelsellers.com/blog/article/using-multiple-authentication-authorization-providers-in-asp-net-core
I need help only to this multi-scheme authentication pipeline configuration part.