3
votes

I am trying to develop a project in .NET Core 3.1. I am trying to implement cookie based authentication in my project. My login function is:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(UserLoginModel userModel)
{
    if (!ModelState.IsValid)
    {
        return View(userModel);
    }

    if (userModel.Email == "[email protected]" && userModel.Password == "123")
    {
        var identity = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "User Id"));
        identity.AddClaim(new Claim(ClaimTypes.Name, "User Name"));

        var principal = new ClaimsPrincipal(identity);

        await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal);

        return RedirectToAction(nameof(HomeController.Index), "Home");
    }
    else
    {
        ModelState.AddModelError("", "Invalid UserName or Password");
        return View();
    }
}

To implement cookie based authentication, I put the below code in my ConfigureService method of Startup class:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    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.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.Cookie.Name = "_auth";
            options.Cookie.HttpOnly = true;
            options.LoginPath = new PathString("/account/login");
            options.LogoutPath = new PathString("/account/logout");
            options.AccessDeniedPath = new PathString("/account/login");
            options.ExpireTimeSpan = TimeSpan.FromDays(1);
            options.SlidingExpiration = false;
        });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest);
}

And the configure method of Startup class is:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();
    app.UseRouting();

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

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

But the problem is each time I try to login, the below exception occur in below code of login action method.

await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal)

The exception occured is given below:

InvalidOperationException: No sign-in authentication handler is registered for the scheme 'Identity.Application'. The registered sign-in schemes are: Cookies. Did you forget to call AddAuthentication().AddCookies("Identity.Application",...)? Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) _01_AuthenticationDemo.Controllers.AccountController.Login(UserLoginModel userModel) in AccountController.cs + await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal);

Can anyone give me suggestion to solve the problem.

2
This question is the first question that has a feasible solution - User2012384

2 Answers

4
votes

No sign-in authentication handler is registered for the scheme 'Identity.Application'. The registered sign-in schemes are: Cookies.

Please sepcify it with CookieAuthenticationDefaults.AuthenticationScheme, like below.

if (userModel.Email == "[email protected]" && userModel.Password == "123")
{
    var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "User Id"));
    identity.AddClaim(new Claim(ClaimTypes.Name, "User Name"));

    var principal = new ClaimsPrincipal(identity);

    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);

    return RedirectToAction(nameof(HomeController.Index), "Home");
}

For more information, please check: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1#create-an-authentication-cookie

Test Result

enter image description here

0
votes

I'll leave this comment here just in case it helps anyone.

I spent 2 days trying to get cookies authentication and then just a basic session authentication login page working on my .NET Core 3.1 site.

It turned out the problem was that my advertising platform (Ezoic) was causing the issue. They basically use some sort of proxy system whereby requests go to their server then their server makes the request to my server (a reverse proxy?). Anyway, if you're using a CDN or ad server or something similar then this could be a problem.

Another clue in my case was that my site worked fine on localhost but not on the production server.

To resolve the issue the ad company said I could add an X-Forwarded-For header to my site but I've not been able to get this to work, despite following the instructions about adding the appropriate lines to Startup.cs.