John John - 1 month ago 6
ASP.NET (C#) Question

MVC 6 Cookie Authentication - Getting User Details From the Cookie

I'm working on an MVC 6 application that does not use Entity or Identity. Instead, I'm using Dapper. I have a controller that accepts a POST request and uses Dapper to check the database to see if the users name / password match. All I'd like to do is store the users name and whether they're logged in or not so I can make that check on subsequent pages.

I looked around and it seems like using Cookie based authentication should allow me to do what I want. Here's the relevant code in my

Startup.cs
file:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = "/account/login",
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
AutomaticChallenge = true
});


Here's what the relevant code in my controllers login action looks like:


var user = _repo.FindByLogin(model.VendorId, model.Password);
if (user != null) {
var claims = new List < Claim > {
new Claim("VendorId", user.VendorId),
new Claim("Name", "john")
};

var id = new ClaimsIdentity(claims, "local", "name", "role");
await HttpContext.Authentication.SignInAsync("Cookies", new ClaimsPrincipal(id));
var l = ClaimsIdentity.DefaultNameClaimType;
return RedirectToAction("Index", "PurchaseOrders");
}


The above code seems to work in that a cookie is being saved, but I'm not sure how I would go about getting the user information back out of the cookie (or even how to retrieve the cookie on subsequent requests in the first place).

In my mind I'm imagining being able to do something like:
var user = (User)HttpContext.Request.Cookies.Get(????)
, but I'm not sure if that's practical or not.

Answer

You can get the user data back by using the ClaimsPrincipal.FindFirstValue(xxx)

here is my example class which can be used in Controller/Views to get the current user information

public class GlobalSettings : IGlobalSettings
    {
        private IHttpContextAccessor _accessor;

        public GlobalSettings(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }    

        public string RefNo
        {
            get
            {
                return GetValue(_accessor.HttpContext.User, "employeeid");
            }
        }

        public string SAMAccount
        {
            get
            {
                return GetValue(_accessor.HttpContext.User, ClaimTypes.WindowsAccountName);
            }
        }

        public string UserName
        {
            get
            {
                return GetValue(_accessor.HttpContext.User, ClaimTypes.Name);
            }
        }

        public string Role
        {
            get
            {
                return GetValue(_accessor.HttpContext.User, ClaimTypes.Role);
            }
        }

        private string GetValue(ClaimsPrincipal principal, string key)
        {
            if (principal == null)
                return string.Empty;

            return principal.FindFirstValue(key);
        }
}

Example Usage in controller after DI:

var currentUser = GlobalSettings.SAMAccount;

Please note that you need to inject HttpContextAccessor in ConfigureServices method in Startup.cs

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Comments