Adding extra claims in ASP.NET Core web applications
The ASP.NET Core documentation explains thoroughly what a claim is and how to check for a claim. However, there is no information about how to create a new claim and attach it to the user object.
Here we are going to close this gap and provide you with step-by-step instruction on how to add a new claim and use it on views (pages) or in any other part of your ASP.NET Core application.
Problem
Let’s describe the task we are going to solve.
- We have an ASP.NET Core (2.1+) project with the default authentication/authorization functionality provided by the ASP.NET Identity library
- We have a user’s name field (e.g.
ContactName
) in our identity model class (let it beApplicationUser
). - We want to add the value of that
ContactName
column to user’s claims and then show it on our home page (instead of user’s email shown by default) when the user is logged in.
Here are the steps we are going to perform to achieve our goal.
Step 1: Adding a new claim
1.1. Create a custom “claims principle” factory
We need an implementation of IUserClaimsPrincipalFactory
which will add necessary information (ContactName
in our case) to the user’s claims. The simplest way to do it is to derive our new class from the default implementation of IUserClaimsPrincipalFactory
and to override one method — GenerateClaimsAsync
:
public class MyUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
public MyUserClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, optionsAccessor)
{
}
protected override async Task<ClaimsIdentity>GenerateClaimsAsync(ApplicationUser user)
{
var identity = await base.GenerateClaimsAsync(user);
identity.AddClaim(new Claim("ContactName", user.ContactName ?? "[Click to edit profile]"));
return identity;
}
}
1.2 Register new class in the DI container
Then we need to register our new class in the dependency injection container. The best way for that is to use theAddClaimsPrincipalFactory
extension method:
public void ConfigureServices(IServiceCollection services)
{
. . . . .
services.AddDefaultIdentity<ApplicationUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddClaimsPrincipalFactory<MyUserClaimsPrincipalFactory>(); //<---- add this line
}
That’s it. The new claim with the ID ContactName
will be added to the object which represents the current user.
Now we need to get the value of the new claim on our Razor view (page) or anywhere else in your application.
Step 2: Getting the new claim
To get the value of any claim, we only need a reference to the ClaimsPrincipal
object which represents the currently logged user. This object can be accessed via User
property of any Razor view (page) or by HttpContext.User
in the controller classes or, in general, in any place where you have access to a HttpContext
object.
ClaimsPrincipal
contains the list of all claims associated with the current user and you can call its FindFirst
method to get the necessary claim and then read the Value
property of that claim.
So, we just need to open _LoginPartical.cshtml
file in Pages/Shared/
(or Views/Shared/
) folder and replace the following line:
<a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @User.Identity.Name!</a>
with this one:
<a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @(User.FindFirst("ContactName").Value)!</a>
Done!
Now instead of something like Hello john.doe@yourcompany.com
at the top of your web-page you will see something like this:
Originally published at .NET stories blog on May 14, 2019.