How to work with Claims in Identity Membership System

How to work with Claims in Identity Membership System

So far you have seen that I did the authentication of a User based on his email and password stored in the database. I also authorizes only users of a particular role to access an action method. Here I am trusting my application, which is providing all the information that I needed, to manage the user authentication and authorization.

In my previous tutorial on Custom User Properties in Identity Membership System I explained how to add new properties to the user class. If you haven’t seen it then check it now.

Identity offers claims for doing authentication and authorization. In this, the 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 are a name value pair issued by a third party. For example, a person driving licence is issued by a driving license authority. Suppose the driving license has the date of birth specified as 21st December, 1990 on it.

In this case the claim name would be ‘DOB’, the claim value would be ‘as 21st December,1990’, and the issuer would be the driving license authority.

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 its 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;
using System.Security.Claims;
using Identity.Models;
using Microsoft.AspNetCore.Identity;

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. Then I am getting all the claims of the User (as an IEnumerable object) using the Claims property of the ClaimsPrincipal object, which I am returning to the View as a Model.

Now create the View called ‘Create.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 a table format.

Now run your application and go to the Login URL – ‘/Account/Login’, and login with tom’s credentials:

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

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

user tom's claims

Notice the second column, which shows the role to which tom belongs, which is of manager. That means Claims contain Roles too.

Creating & Deleting Claims for a User

To make the functionality to Create & Delete claims for a User, 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>

It contains 2 input controls that will allow adding claim type and claiming value for a user.

I also update my 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 given below:

@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 add the Create and Delete Action methods on my ‘ClaimsController’. I also add a dependency of UserManager on the constructor.

The updated code of the Claims Controller is:

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

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

Inside the Create action, 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 its parameter. Then using the split method I extract the claim type, claim value and claim issuer values.

I fetch the selected claim by using LINQ query:

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

Then using the userManager.RemoveClaimAsync method, I delete the claim from the User.

Testing

To test these features, run your project and go to the ‘Create’ Claim page, whose URL is – ‘/Claims/Create’.

Then fill the claim type and value fields and click the ‘Create’ button, see the below image:

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 – ‘/Account/Login’.

Next, go to the URL – ‘/Claims’, where 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 URL – ‘/Claims’ where you can see your claim got deleted, see the below image:

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.

Share this article -

yogihosting

ABOUT THE AUTHOR

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