.NET logo

How to get the current user in ASP.NET Core?

This post was most recently updated on August 1st, 2020.

Reading Time: 3 minutes.

This post describes how to get the currently logged in user using ASP.NET Core. This is compared with how it’s done in ASP.NET Framework.

Background

In ASP.NET Core (and .NET Core in general), a lot of things are done a bit differently than what you might be used to if you’re coming from the .NET Framework world. That’s what I’ve been learning building more and more stuff with it, instead of good old .NET Framework. The learning curve is definitely there, but it’s not that bad – most of the things work in a similar fashion, but a huge number of details are different.

In ASP.NET Framework, you’d do this by accessing HttpContext.Current.User and its properties (see below for an example), in .NET Core this is handled via dependency injection.

var username = HttpContext.Current.User.Identity.Name;

You can’t do this in (most versions of) .NET Core. How to do it there, then?

Solution

Time needed: 10 minutes.

Let’s go through the steps first on a high level, and then take a closer look below.

  1. Make sure your application has permissions to request user properties or claims

    See details here.

  2. Modify your app startup to add the required background services

    See details here.

  3. Implement the property / claim enumeration in your code

    See details here.

Now, that’s good – let’s take a closer look to these 3 steps below!

Background

Now I’ll describe how to manage user identity when developing your application – before that, you need to configure your application registration in a way that your identity provider actually supplies you with the user information in the first place. For Azure AD, see my other post, here:
https://www.koskila.net/iterating-group-memberships-using-claims-in-net-core/

When that all is done, let’s jump into the ways you can access User/Identity in your program!

Modify your Startup

First, you add this in your Startup.cs, in ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
     // omitted for clarity
 
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

Or if you’re at least on .NET Core 3.0, you can do this as well:

public void ConfigureServices(IServiceCollection services)
{
     // omitted for clarity
 
     services.AddHttpContextAccessor();
}

Accessing the User Properties in your code

Then you add these pieces of code to your Controller, database context or other class:

  1. Private variable to hold the injected reference to our HttpContextAccessor
  2. New variable with the correct type (or interface) to the class constructor (like IHttpContextAccessor httpContextAccessor below)
  3. Assignment from the injected variable (in the constructor) to the hidden private variable (to make the reference available outside the constructor)

Below, my code is shown accessing the HttpContext (and through that, Current User) in a DbContext class. It’s assigned in the constructor, after which you may use it in any other method!

private readonly IHttpContextAccessor _httpContextAccessor;
 
// omitted for clarity
 
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
            : base(options)
{
  _httpContextAccessor = httpContextAccessor;
}

For our little example call further below, you’ll need to add a reference to Claims like this:

using System.Security.Claims;

And finally, you call it like this – for example, to get the reference to the user, and grab their id:

var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

This can be injected to Controllers and Views, Custom Components and if need be, properties passed to background Threads (don’t pass the context! That’ll break.)

What about pure & classic Razor pages?

Okay, so here it’s different because Razor takes care of some of the background work for you. If you’re using Razor pages, you can just do this:

@{
    var username = HttpContext.User.Identity.Name;
}

That’s because Razor exposes HttpContext in Razor.Component.

And with this, you should be good! :)

mm
4.3 8 votes
Article Rating
Subscribe
Notify of
guest
49 Comments
Inline Feedbacks
View all comments
kintela

Hi Antti,
I’m trying this in my webAPI project hosted in web site in IIS with Windows Authentication enabled
I have this in my controller
[Route(“empleados”)]
public class EmployeeController : Controller
{
private readonly IMediator mediator;
private readonly IHttpContextAccessor httpContextAccesor;

public EmployeeController(IMediator mediator, IHttpContextAccessor httpContextAccesor)
{
this.mediator = mediator;
this.httpContextAccesor = httpContextAccesor;
}

[HttpGet]
[Route(“”)]
public IActionResult Get()
{
var userId = this.httpContextAccesor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
return Ok(userId);
}
But when I make the call I get the pop up to start session and then HTTP ERROR 500

Any idea, please?

Thanks

kintela

Hi Antti

I have referenced system.security.claims and when I test the controller with Postman in OSX, in User I have one element in the Identities array but that element has 0 Claims. It’s all null. This is the response
{
“ClassName”: “System.NullReferenceException”,
“Message”: “Object reference not set to an instance of an object.”,
“Data”: null,
“InnerException”: null,
“HelpURL”: null,
“StackTraceString”: ” at api.Controllers.EmployeeController.Get() in /Users/kintela/Repos/FysegPlanner/api/Controllers/EmployeeController.cs:line 32″,
“RemoteStackTraceString”: null,
“RemoteStackIndex”: 0,
“ExceptionMethod”: null,
“HResult”: -2147467261,
“Source”: “api”,
“WatsonBuckets”: null
}
When I try in Windows I am asked for credentials and then I get this
{“ClassName”:”System.NullReferenceException”,”Message”:”Object reference not set to an instance of an object.”,”Data”:null,”InnerException”:null,”HelpURL”:null,”StackTraceString”:” at api.Controllers.EmployeeController.Get() in C:\\Users\\rquintela\\Documents\\Repos\\FysegPlanner\\api\\Controllers\\EmployeeController.cs:line 32″,”RemoteStackTraceString”:null,”RemoteStackIndex”:0,”ExceptionMethod”:null,”HResult”:-2147467261,”Source”:”api”,”WatsonBuckets”:null}

Thanks for all

Tian

Thanks for post, but when I call var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; it return name of user. How can I found userId.
Thanks

Lars Torbjörn Linden

UserName = claimsPrincipal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.Name)?.Value,
Roles = claimsPrincipal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray(),
Email = claimsPrincipal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.Upn)?.Value,
FirstName = claimsPrincipal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value,
LastName = claimsPrincipal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.Surname)?.Value

ThisIs TheList

Just wanted to say that on an ASP NET CORE 3.1 + Identity4 + Login project, I was able to follow the directions you provided in this article and successfully retrieve the current user information from within a method in a Web API Controller. That was something I was struggling with after moving from a CORE 2 + older Identity project to the latest/greatest. Thanks for the clear explanation.

Deepthi

Hi,
I have a .net core 2.2 web application where the Signin happens using the following code

await _httpContextAccessor.HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
The values of httpContextAccessor.httpContext.user.identity.name are retained properly for further requests and works in VS2017 in devlopment environment.

But on deploying to server with IIS the same code doesn’t work and the values for httpContextAccessor.User.Identity.Name is returning empty.

Any idea what the problem is? Any help will be greatly appreciated.

Thanks

Sam B

Hello,

Thanks so much for the guide. Im currently using Dapper as my ORM to make data calls for my identity user. I referenced- https://markjohnson.io/articles/asp-net-core-identity-without-entity-framework/ and am wondering how to set up the httpcontextaccessor without a dbcontext class. Any insight is helpful :)

Thanks,
SB