Useful ClaimsPrincipal extension methods I use in my projects

December 10, 2019
ASP.NET Core 3.1

Retrieving user information from claims

To obtain information about the current user in an ASP.NET Core application, you can look at the claims on the User property of the current HttpContext. These claims give you access to information such as the user’s ID, email address, roles, and whatever other information about the user is stored in these claims.

When using Razor Pages, you can access the current user using the User property of the base PageModel class, and for MVC projects you can use the User property of the base ControllerBase class.

If, for example, I want to retrieve the current user’s unique ID from inside a Razor Page, I can retrieve the value of the ClaimTypes.NameIdentifier claim type.

var userId = User.FindFirstValue(ClaimTypes.NameIdentifier)

Using extension methods to ensure consistency

This is a pretty straightforward thing to do, but not all developers working on the application may be familiar with the correct claims types to use. To ensure consistency, I always add a few ClaimsPrincipal extension methods to my application to ensure this consistency. I also add other convenience methods, such as the IsCurrentUser method below which checks whether a particular user ID refers to the currently logged in user.

public static class ClaimsPrincipalExtensions
{
    public static string GetUserEmail(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue(ClaimTypes.Email);
    }

    public static string GetUserId(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue(ClaimTypes.NameIdentifier);
    }

    public static string GetUserName(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue(ClaimTypes.Name);
    }

    public static bool IsCurrentUser(this ClaimsPrincipal principal, string id)
    {
        var currentUserId = GetUserId(principal);

        return string.Equals(currentUserId, id, StringComparison.OrdinalIgnoreCase);
    }
}

Other developers can then use one of these extension methods to retrieve a user’s information.

var userId = User.GetUserId();

This is especially useful once you start using non-standard claim types. For example, in a multi-tenant environment, I may define a custom claim type to store the ID of the tenant the user is associated with

public static class CloudpressClaimTypes
{
    public const string TenantId = "urn:cloudpress:tenant_id";

    // other custom claim types for my application...
}

And also define an extension method the retrieve the value for this claim type.

public static class ClaimsPrincipalExtensions
{
    public static string GetTenantId(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue(CloudpressClaimTypes.TenantId);
    }

    // other extension methods omitted...
}

Retrieving user information from elsewhere

I mentioned that you could access the ClaimsPrincipal for the current user using the User property inside a Razor Page or MVC controller class. If you want to access the current user outside of the Razor Page or controller, you can inject an instance of IHttpContextAccessor to retrieve the current HttpContext and then retrieve the user from that.

For example, I am a big fan Jimmy Bogard’s MediatR library, so when I need to access information regarding the current user inside a request handler, I typically do it as in the code sample below.

public class QueryHandler : IRequestHandler<Query, Result>
{
    private readonly CloudpressDbContext _dbContext;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public QueryHandler(CloudpressDbContext dbContext, IHttpContextAccessor httpContextAccessor)
    {
        _dbContext = dbContext;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<ValidationResult> Handle(Query request, CancellationToken cancellationToken)
    {
        var userId  = _httpContextAccessor.HttpContext.User.GetUserId();

        // do some stuff with the user, for example retrieve the orders for the current user
        var orders = _dbContext.Orders.Where(o => o.UserId == userId);
    }
}

Conclusion

In this blog post, I demonstrated a typical pattern I use in my applications to retrieve information about the current user from the ClaimsPrincipal class. It is nothing earth-shattering, but it ensures consistency across the codebase.

PS: If you need assistance on any of your ASP.NET Core projects, I am available for hire for freelance work.