Now that ASP.NET Core has been out for a few years, I decided to start dabbling with it. Since I'm writing this for a personal app (to be running on my home machine) I decided I needed authentication, but wanted to make it simple. After some research I settled on this as the simplest approach to adding custom authentication to an ASP.NET Core webpage.
BTW, this has been testing against ASP.NET Core 2.2 & 3.1
Begin
Create a new ASP.NET Core project without any authentication.
Configure authentication
First , tell ASP.NET Core that we need authentication (via cookie authentication). In ConfigureServices() method of Startup class and enable authentication:
using Microsoft.AspNetCore.Authentication.Cookies;
…
public void ConfigureServices(IServiceCollection services)
{
    // …
 
    // Enable cookie authentication
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
}
In Configure() method of Startup class, add authentication to request processing pipeline:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ...
 
    // Add authentication to request pipeline
    app.UseAuthentication();
}
Create a simple user model
First, for this application I created a simple CustomUser class:
public class CustomUser
{
    public string Username { get; set; }
    public string Pwd { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<string> Roles = new List<string>();
}
Adding the Controller
Add a controller called AccountController with the following minimum functionality.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
...
public class AccountController : Controller
{
    public AccountController()
    {
    }
    private CustomUser GetUserByUsername(string username)
    {
        // TODO: Replace this:
        CustomUser retValue = null;
        if (username == "Me")
        {
            retValue = new CustomUser()
            {
                Username = "Me",
                Pwd = "1",
                FirstName = "Myself",
                LastName = "AndI"
            };
            retValue.Roles.Add("Admin");
        }
        return retValue;
    }
    [HttpGet]
    public IActionResult Login()
    {
        return View();
    }
    [HttpPost]
    public async Task<IActionResult> Login(string username, string password)
    {
        // Find and validate the user:
        CustomUser user =  GetUserByUsername(username);
        if (user == null || user.Pwd != password)
        {
            ModelState.AddModelError("", "Incorrect username or password.");
            return View();
        }
        // Create the identity
        var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
        identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
        identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName));
        identity.AddClaim(new Claim(ClaimTypes.Surname, user.LastName));
        // Add roles
        foreach (var role in user.Roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role));
        }
        // Sign in
        var principal = new ClaimsPrincipal(identity);
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
        return RedirectToAction("Index", "Home");
    }
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync();
        return RedirectToAction("Index", "Home");
    }
}
Create the Login view
Create the Login.cshtml view, located under "Views/Account" with the following content:
@{
    ViewData["Title"] = "Login";
}
<h1>Login</h1>
<form asp-action="Login" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    Username: <input name="username" /><br />
    Password: <input type="password" name="password" /><br />
    <input type="submit" />
</form>
Display either the username or login link
On either the Index.cshmtl or the layout page, add the following code:
@if (User.Identity.IsAuthenticated)
{
    <div >
        Hello @User.Identity.Name
    </div>
    <div>
        <a href="http://bushconsulting.com/Account/Logout">Logout</a>
    </div>
}
else
{
    <a href="http://bushconsulting.com/Account/Login">Login</a>
}
Notice that the “User” instance (ClaimsPrincipal) is available within the page. It’s also available in the Controller.
And that’s all. Happy coding...
Next up: Hosting ASP.NET Core