Cookie Authentication In ASP.net Core

This article covers Cookie Authentication in ASP.net Core 1.X. While much is the same in subsequent versions, there are a couple of small changes that could trip you up. Take a look here for our article on Cookie Authentication in ASP.net Core 2.0.

ASP.net core comes with two ways to do authentication out of the box. The first is using ASP.net cores “identity” service that wraps a MSSQL set of tables and allows you to get every piece of functionality out of the box, but does require you to have a very rigid structure and do things the “Microsoft” way. It also requires you to use a database adapter that has been pre-built (Typically this means using Microsoft SQL). If you are using something like a NoSQL database store to your users, or you authenticate your users using something other than a username password combination, then using the full identity service can be a bit of a pain.

The alternative is to use ASP.net Core’s “Cookie Authentication” which allows you to use cookie based claims for a user, but authenticate the users yourself using your own data store, however that may work. That’s what this article is going to focus on.

Setup

If you are creating a brand new project using Visual Studio for this tutorial, ensure that when creating your project you select the “authentication type” to be none. We essentially want to start with a clean slate.

In your nuget package manager window, install the following package :

Install-Package Microsoft.AspNetCore.Authentication.Cookies

In your startup.cs file, find your configure method. You should add the following code to your pipeline but you must ensure this is before your call to “AddMvc”. This is extremely important. Your pipeline runs in the order you have added it so you need to obviously have authorization run before MVC kicks in.

app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
	AuthenticationScheme = "CookieAuthentication",
	LoginPath = new PathString("/Account/Login"),
	AccessDeniedPath = new PathString("/Account/Forbidden/"),
	AutomaticAuthenticate = true,
	AutomaticChallenge = true
});

A little bit about the options we have set here.

AuthenticationScheme is just the name we have given this instance of authentication. You can actually have multiple authentication middleware in your application. The name isn’t too important and can be anything if you are only having the single login.

LoginPath is the path to your login page

AccessDeniedPath is the path to a “denied” page

AutomaticAuthenticate means that the middleware runs automatically on every request and tries to authenticate the user

AutomaticChallenge means that a user should automatically be routed to the LoginPage if the user is not authorized.

Registering A User

Using Cookie Authentication as a simple middleware and not using the full identity service means you need to organize registering users and creating them in your data store yourself. There is nothing in the middleware to help you out there.

Logging In A User

For logging in, we will create a simple post model to accept our username and password combination.

public class LoginModel
{
	public string Username { get; set; }
	public string Password { get; set; }
}

I’ve created a controller called “AccountController”. Inside I’ve created a GET and POST endpoint for our model. The GET endpoint returns a view that has a simple form for logging in, the POST endpoint is where we do our work.

public class AccountController : Controller
{
	[HttpGet]
	public IActionResult Login()
	{
		return View();
	}

	[HttpPost]
	public async Task<IActionResult> Login(LoginModel loginModel)
	{
		if(LoginUser(loginModel.Username, loginModel.Password))
		{
			var claims = new List<Claim>
			{
				new Claim(ClaimTypes.Name, loginModel.Username)
			};

			var userIdentity = new ClaimsIdentity(claims, "login");

			ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);
			await HttpContext.Authentication.SignInAsync("CookieAuthentication", principal);

			//Just redirect to our index after logging in. 
			return Redirect("/");
		}
		return View();
	}

	private bool LoginUser(string username, string password)
	{
		//As an example. This method would go to our data store and validate that the combination is correct. 
		//For now just return true. 
		return true;
	}
}

Let’s walk through that code a little.

First we validate the user. In our example we just validate every user but obviously in real life this would go away to our data store and validate the user/password combination.

Next we create a Claims list. These are things we know about the user that we wish to store on the cookie. In this example I’ve just stored the Username as the “Name” claim. This one is slightly important as we see later as there is a shortcut to get this name, but you can actually store any key/value combination inside the claims if you don’t want to have to go back to the database each time to get info on the logged in user.

We then build an identity, a principal, and then set the cookie using the SignInAsync method. There is a bit of cruft going on here in terms of building the identity and principal, but the important part is building claims and calling signin.

Authorizing Controllers

Next we obviously need to learn how to “lockdown” certain areas of our website to force a user to have to login. We can do this simply by adding an “Authorize” attribute to any controller.

[Authorize]
public class HomeController : Controller
{
	......

And that’s all there is to it! Any user that navigates to this controller will be redirected to your “Logon” url.

Logging Our A User

Logging out a user is very simple.

[HttpGet]
public async Task<IActionResult> Logout()
{
	await HttpContext.Authentication.SignOutAsync("CookieAuthentication");
	return Redirect("/Account/Login");
}

That’s really all there is too it! Remember the Authentication Scheme you use here must match the one you set in the middleware setup.

Viewing The Logged In User

Obviously at some point we will want to view the logged in user, either to get further details about the user from the database or set onscreen elements in a view. Here we have some example code on how we can get both the username we set earlier, and any other claim we may have set.

public IActionResult Index()
{
	var loggedInUser = HttpContext.User;
	var loggedInUserName = loggedInUser.Identity.Name; // This is our username we set earlier in the claims. 
	var loggedInUserName2 = loggedInUser.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name).Value; //Another way to get the name or any other claim we set. 
	return View();
}

The Name on the Identity object is just a fancy way of getting the “Name” claim that we set earlier, but for any other claim you can work with the claims list and fetch our data. Remember this will only be set after logging in so null checks should be done along the way.

3 thoughts on “Cookie Authentication In ASP.net Core”

  1. Thanks for example.
    I’m using spatemplate with angular 4.
    How would you show something like a welcome user?
    I do not know how to access the claim in in angular…

    Reply

Leave a Comment