How to work with Claims in ASP.NET Core Identity

How to work with Claims in ASP.NET Core Identity

So far you have seen I did the Authentication of a User based on his email and password stored in the database. I also authorized only users of a particular role to access an Controller/Action. ASP.NET Core Identity offers claims for doing authentication and authorization and this tutorial will cover Claims in details

Claims are a name-value pair issued by a third party. For example, a person driving licence is issued by a driving license authority. If DOB in the driving license is 21st December, 1990. Then in this case the claim name would be DOB, the claim value would be 21st December, 1990, and the issuer would be the driving license authority.

Users are provided Claims that are issued by a third party. These claims are then be used for doing authentication and authorization. So that means the application does not provide information about the user for authentication, the third party does.

Claims based authentication, at its simplest, checks the value of a claim and allows access to a resource based upon that value.

Understanding Claims with an Example

Create a new controller called ClaimsController and change it’s Index action to return User.Claims. The code is given below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Identity.Controllers
{
    [Authorize]
    public class ClaimsController : Controller
    {
        public ViewResult Index() => View(User?.Claims);
    }
}

The User property (also available as the HttpContext.User property) returns a ClaimsPrincipal object of the Logged in User. I am getting all the claims of the User (as an IEnumerable object) by using the Claims property of the ClaimsPrincipal object, which I am returning to the View as a Model.

Now create the view called Index.cshtml inside the Views ➤ Claims folder with the following code:

@model IEnumerable<System.Security.Claims.Claim>
<h2 class="bg-primary m-1 p-1 text-white">Claims</h2>
 
<table class="table table-sm table-bordered">
    <tr>
        <th>Subject</th>
        <th>Issuer</th>
        <th>Type</th>
        <th>Value</th>
    </tr>
 
    @foreach (var claim in Model.OrderBy(x => x.Type))
    {
        <tr>
            <td>@claim.Subject.Name</td>
            <td>@claim.Issuer</td>
            <td>@claim.Type</td>
            <td>@claim.Value</td>
        </tr>
    }
</table>

The View is showing all the Claims of the logged in User in an HTML table.

Now run your application and login with user Tom’s credentials. Login URL is https://localhost:44395/Account/Login and tom’s credentials are given below.

1. Email – [email protected]
2. Password – [email protected]

After you are logged in go to the URL – https://localhost:44395/Claims, where you will see all the Claims associated with user tom, as shown in the below image:

user tom's claims

Notice the second column, which shows the Identity Role to which the user tom belongs. It is Manager role. That means Claims contain Roles too.

Identity is very flexible and you can create role based authentication in it. See my tutorial called How to work with Roles in ASP.NET Core Identity which covers this topic.

Creating & Deleting Claims for a User

It is very easy to Create & Delete claims for a User. To understand this first create a new view called Create.cshtml inside the Views ➤ Claims folder with the following code:

<h1 class="bg-info text-white">Create Claim</h1>
<a asp-action="Index" class="btn btn-secondary">Back</a>
<div asp-validation-summary="All" class="text-danger"></div>
 
<form method="post">
    <div class="form-group">
        <label for="ClaimType">Claim Type:</label>
        <input name="ClaimType" class="form-control" />
    </div>
    <div class="form-group">
        <label for="ClaimValue">Claim Value:</label>
        <input name="ClaimValue" class="form-control" />
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
</form>

There 2 input controls that will allow adding Claim type and Claim value for a user.

Next, update the Index View to add a link to invoke the Create View, and a form that contains a delete button for deleting claims. The updated Index View code is shown in highlighted manner.

@model IEnumerable<System.Security.Claims.Claim>
<h2 class="bg-primary m-1 p-1 text-white">Claims</h2>
<a asp-action="Create" class="btn btn-secondary">Create a Claim</a>
 
<table class="table table-sm table-bordered">
    <tr>
        <th>Subject</th>
        <th>Issuer</th>
        <th>Type</th>
        <th>Value</th>
        <th>Delete</th>
    </tr>
 
    @foreach (var claim in Model.OrderBy(x => x.Type))
    {
        <tr>
            <td>@claim.Subject.Name</td>
            <td>@claim.Issuer</td>
            <td>@claim.Type</td>
            <td>@claim.Value</td>
            <td>
                <form asp-action="Delete" method="post">
                    <input type="hidden" name="claimValues" value="@claim.Type;@claim.Value;@claim.Issuer" />
                    <button type="submit" class="btn btn-sm btn-danger">
                        Delete
                    </button>
                </form>
            </td>
        </tr>
    }
</table>

Now Finally I can add the Create and Delete action methods on my ClaimsController. I also need to add a dependency of UserManager<T> on the constructor of the controller.

The updated code of the Claims Controller is given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Identity.Models;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;

namespace Identity.Controllers
{
    [Authorize]
    public class ClaimsController : Controller
    {
        private UserManager<AppUser> userManager;

        public ClaimsController(UserManager<AppUser> userMgr)
        {
            userManager = userMgr;
        }

        public ViewResult Index() => View(User?.Claims);

        public ViewResult Create() => View();

        [HttpPost]
        [ActionName("Create")]
        public async Task<IActionResult> Create_Post(string claimType, string claimValue)
        {
            AppUser user = await userManager.GetUserAsync(HttpContext.User);
            Claim claim = new Claim(claimType, claimValue, ClaimValueTypes.String);
            IdentityResult result = await userManager.AddClaimAsync(user, claim);

            if (result.Succeeded)
                return RedirectToAction("Index");
            else
                Errors(result);
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Delete(string claimValues)
        {
            AppUser user = await userManager.GetUserAsync(HttpContext.User);

            string[] claimValuesArray = claimValues.Split(";");
            string claimType = claimValuesArray[0], claimValue = claimValuesArray[1], claimIssuer = claimValuesArray[2];

            Claim claim = User.Claims.Where(x => x.Type == claimType && x.Value == claimValue && x.Issuer == claimIssuer).FirstOrDefault();

            IdentityResult result = await userManager.RemoveClaimAsync(user, claim);

            if (result.Succeeded)
                return RedirectToAction("Index");
            else
                Errors(result);

            return View("Index");
        }

        void Errors(IdentityResult result)
        {
            foreach (IdentityError error in result.Errors)
                ModelState.AddModelError("", error.Description);
        }
    }
}
Create Action

In the Create action method, I first get my current logged in user from the userManager.GetUserAsync() method. Then I add a new claim object, and finally I add this claim object, to create a new claim for my user.

The claim is created for a user by using the method – userManager.AddClaimAsync().

Delete Action

The Delete action method gets the claim values, which are separated with semicolon (;), in it’s parameter. Then with the split method extract the claim type, claim value and claim issuer values.

The selected claims are fetched by using the LINQ query:

Claim claim = User.Claims.Where(x => x.Type == claimType && x.Value == claimValue && x.Issuer == claimIssuer).FirstOrDefault();

The claim of a user is deleted using the userManager.RemoveClaimAsync() method.

I have written lot’s of ASP.NET Core tutorials which undoubtedly will make you an excellent developer. So make sure you check them out.
Testing

To test these features, run your app and login with user tom’s credentials. Then go to the Create Claims page, whose URL is – https://localhost:44395/Claims.

Here fill the Claim type and Clam value fields like show in the below image. Then click the Create button.

creating claims

Remember that once the Claim is created, you need to login once more, in order to see your created claim. So, login to the tom’s account once more by going to the URL – https://localhost:44395/Account/Login.

Next, go to the claims url once again and you will see your newly created claim, as shown in the below image:

claims added to user tom

Now delete your newly added claim by clicking on the Delete button next to it.

Once the claim is deleted, you need to login once again, and then go to the claims url to see your claim got deleted. See the below image which shown the claim deleted from user’s toms account.

claim deleted from user tom

You can download the full codes of this tutorial from the below link:

Download

Conclusion

This completes the tutorial on Claims in Identity. Now you can easily create or delete claims for a user. For authenticating users with Identity Claims you will also need Identity Policies. We will look into this in the next tutorial whose link is given below.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "ASP.NET Core, jQuery, EF Core, SEO, jQuery, HTML" and more.