Answered by:
Asp.Net Core 2.2 Identity Authentication

Question
-
User-1067173060 posted
I am having a situation in my Asp.Net Core 2.2 app whereby I can successfully sign in but not authenticated. I have checked the property: User.Identity.IsAuthenticated property and its value is false. I am using the scaffolded Identity razor pages. I have added the Authorize attribute on the Index view of the default HomeController but after successfully logging in the view is not loading I am getting ERR_SPDY_PROTOCOL_ERROR instead.
My Startup class is as follows
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDbContext<SchoolIdentityContext>(options => options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection"))); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<SchoolIdentityContext>() .AddDefaultTokenProviders(); services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>)); services.AddScoped<IAssetCategoryService, AssetCategoryService>(); services.AddScoped<IAssetService, AssetService>(); services.AddHttpClient("schoolapi", c => { c.BaseAddress = new Uri("http://localhost:5100/api/v1/"); }); services.Configure<IdentityOptions>(options => { // Password settings. options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; }); 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; }); services.AddMvc().AddRazorPagesOptions(options => { options.AllowAreas = true; }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2); _services = services; } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); ListAllRegisteredServices(app); 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.UseCookiePolicy(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
Home controller
public class HomeController : Controller { [Authorize] public IActionResult Index() { return View(); } public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } }
Login.cshtml.cs
[AllowAnonymous] public class LoginModel : PageModel { private readonly SignInManager<User> _signInManager; private readonly ILogger<LoginModel> _logger; public LoginModel(SignInManager<User> signInManager, ILogger<LoginModel> logger) { _signInManager = signInManager; _logger = logger; } [BindProperty] public InputModel Input { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } public string ReturnUrl { get; set; } [TempData] public string ErrorMessage { get; set; } public class InputModel { [Required] [EmailAddress] public string Email { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } public async Task OnGetAsync(string returnUrl = null) { if (!string.IsNullOrEmpty(ErrorMessage)) { ModelState.AddModelError(string.Empty, ErrorMessage); } returnUrl = returnUrl ?? Url.Content("~/"); // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); ReturnUrl = returnUrl; } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } // If we got this far, something failed, redisplay form return Page(); } }
If put in an incorrect password I am getting 'Invalid login attempt' which shows its correctly checking with database. It seems the problem is occurring on redirect. I am failing to figure out what could be the problem.
Thursday, June 6, 2019 6:03 AM
Answers
-
User1724605321 posted
Hi Edgias,
Do you debug the OnPostAsync function to confirm that user is authenticated with `PasswordSignInAsync` function ? And where do you check the User.Identity.IsAuthenticated property , SignIn persists the given information for future requests, it does not set HttpContext.User on the current one. The value will be true in subsequent request . Do you use the default identity template to create the application or modify a existed application .
Best Regards,
Nan Yu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, June 10, 2019 1:56 AM
All replies
-
User475983607 posted
Did you move (or remove) the Identity Startup from the scaffolded code (Areas/Identity/IdentityHostingStartup.cs) to the startup file?
Thursday, June 6, 2019 1:25 PM -
User-1067173060 posted
I didn't do anything to the IdentityHostingStartup
public class IdentityHostingStartup : IHostingStartup { public void Configure(IWebHostBuilder builder) { builder.ConfigureServices((context, services) => { }); } }
Thursday, June 6, 2019 9:32 PM -
User1724605321 posted
Hi Edgias,
Do you debug the OnPostAsync function to confirm that user is authenticated with `PasswordSignInAsync` function ? And where do you check the User.Identity.IsAuthenticated property , SignIn persists the given information for future requests, it does not set HttpContext.User on the current one. The value will be true in subsequent request . Do you use the default identity template to create the application or modify a existed application .
Best Regards,
Nan Yu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, June 10, 2019 1:56 AM