'HttpContext.SignInAsync() doesn't authenticate the user
I have been trying to create a custom login feature in ASP.NET Core 2.1. However, it doesn't seem the work and I have no idea why.
This is run in the controller:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Email, email),
new Claim(ClaimTypes.Role, loginResult.User.RoleName)
};
ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
var timespanExpiry = new TimeSpan(0, 0, 30, 0, 0);
await httpContextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme
, principal
, new AuthenticationProperties { ExpiresUtc = new DateTimeOffset(timespanExpiry.Ticks, timespanExpiry) });
This is what I have in my Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//services
services.AddSingleton<ITableStorageService, TableStorageService>();
services.AddAuthorization(options =>
{
options.AddPolicy("ConfirmUser",
policy => policy.Requirements.Add(new AuthorizationsRequirement(AuthorizationKeyConstants.AUTH_CONFIRM_USER)));
options.AddPolicy("GetUser",
policy => policy.Requirements.Add(new AuthorizationsRequirement(AuthorizationKeyConstants.AUTH_GET_USER)));
options.AddPolicy("RemoveUser",
policy => policy.Requirements.Add(new AuthorizationsRequirement(AuthorizationKeyConstants.AUTH_DELETE_USER)));
options.AddPolicy("GetListUser",
policy => policy.Requirements.Add(new AuthorizationsRequirement(AuthorizationKeyConstants.AUTH_GETLIST_USER)));
});
services.AddAuthentication(options =>
{
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = new PathString("/User/Login");
options.AccessDeniedPath = new PathString("/error?unauth");
});
services.AddSingleton<IAuthorizationHandler, AuthorizationsHandler>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// 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();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
No errors are occurring, but when I use the code below in Razor or in my controller to check if the user is authenticated, it returns a false. I have checked other questions and answers as well, none of it helps and helped me out with this.
httpContextAccessor.HttpContext.User.Identity.IsAuthenticated
Is there another way to do this, or am I doing something wrong?
EDIT:
I have included my whole Startup.cs
but excluded some dependency injections and database related information on purpose.
Solution 1:[1]
When adding the cookie you need to pass in the AuthenticationScheme.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(
CookieAuthenticationDefaults.AuthenticationScheme,
options => {
options.LoginPath = "/Login";
}
);
Solution 2:[2]
I know this was asked a long time ago, but I recently encountered this same issue. So,here I am sharing my finding.
app.UseHttpsRedirection();
app.UseStaticFiles();
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
Secure = CookieSecurePolicy.None,
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
For some reason when I use the above code in startup.cs ,It always redirecting to /login
But the below code is working fine.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
Secure = CookieSecurePolicy.None,
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseAuthentication();
app.UseAuthorization();
It seems position of UseRouting()
impacts cookie authentication, any comments on this will be appreciated.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | José Yánez |
Solution 2 | Pronoy Chowdhury |