In this article, we are going to see different ways to get the currently authenticated user using claims in ASP.NET Core. The code for this article is based on the respective code from the article on Authentication with ASP.NET Core Web API. 

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

Getting the Current User With Claims in Controllers

Claims-based identity is a way to keep information about a user. A claim is a key-value pair that is assigned to a user by a trusted source. A claim defines what the user is, in contrast to what the user can do. An identity can contain multiple claims; examples are the user’s id, name, and email, to name but a few.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Inside a controller, we can directly access the User property, which is of type ClaimsPrincipal.

Let’s use this object in order to get the claims it contains:

[HttpGet, Authorize]
public IEnumerable<string> Get()
{
    Console.WriteLine("User Id: " + User.FindFirstValue(ClaimTypes.NameIdentifier));
    Console.WriteLine("Username: " + User.FindFirstValue(ClaimTypes.Name));
    Console.WriteLine("Role: " + User.FindFirstValue(ClaimTypes.Role));
    Console.WriteLine("First name: " + User.FindFirstValue("firstname"));
    Console.WriteLine("Last name: " + User.FindFirstValue("lastname"));
    
    return _service.GetCustomers();
}

Note that we can also get the custom claims that we have defined, i.e. claims that provide the first and last name of the user.

However, there is a catch. Let’s try to get the current user inside the Controller’s constructor:

public class CustomersController : ControllerBase
{
    private readonly ICustomerService _service;

    public CustomersController(ICustomerService service) 
    {
        _service = service;

        Console.WriteLine("User Id: " + User.FindFirstValue(ClaimTypes.NameIdentifier)); 
        Console.WriteLine("Username: " + User.FindFirstValue(ClaimTypes.Name));     
    }
...
}

As a result, we realize that the User property inside the constructor is null. Fortunately, there is a way to get the User property here, by injecting an object that implements the IHttpContextAccessor interface:

public class CustomersController : ControllerBase
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ICustomerService _service;

    public CustomersController(IHttpContextAccessor httpContextAccessor, 
        ICustomerService service) 
    {
        _httpContextAccessor = httpContextAccessor;
        _service = service;

        Console.WriteLine("User Id: " + 
            _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier));
        Console.WriteLine("Username: " + 
            _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.Name));
    }
...
}

Through the IHttpContextAccessor interface, we can get the HttpContext object and from there we are able to access the User object and its claims.

Finally, let’s instruct the Program class to make IHttpContextAccessor available to our classes:

builder.Services.AddHttpContextAccessor();

Getting the Current User With Claims in Other Classes

Let’s consider the case of the CustomersService class, where we need to get information about the current user. Since we are not inside a controller, we do not have direct access to the User property:

public class CustomerService: ICustomerService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public CustomerService(IHttpContextAccessor httpContextAccessor) 
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public IEnumerable<string> GetCustomers()
    {
        Console.WriteLine("User Id: " +
            _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier));
        Console.WriteLine("Username: " + 
            _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.Name));
        return new string[] { "John Doe", "Jane Doe" };
    }
}

Luckily, we solve the issue inject by injecting an IHttpContextAccessor object into the service and get the claims of the current user.

Conclusion

In this article, we have seen how we may get the current user, in various parts of our web application (controllers and other classes).

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!