While building my ASP.NET Core identity, Dapper Custom storage provider I found there wasn’t a lot of discussion of the ASPNETUserClaims functionality for fine “grained permissions”.
ASP.NET Core identity Roles can also have individual claims but with the authorisation model of the legacy application I work on this functionality hasn’t been useful. We use role based authentication with a few user claims to minimise the size of our Java Web Tokens(JWT)
The first step was to create a “bare-bones” ASP.NET Core Razor pages Web Application with Individual Accounts Authentication project
I tried to minimise the modifications to the application. I added EnableRetryOnFailure, some changes to names spaces etc. I also added support for email address confirmation with SendGrid and “authentication” link to the navabar in _Layout.cshtml.
@page
@model RolesModel
@{
<table class="table">
<thead>
<tr>
<th>Role</th>
</tr>
</thead>
<tbody>
@foreach (var role in Model.Roles)
{
<tr>
<td>
@Html.DisplayFor(modelItem => role.Value)
</td>
</tr>
}
</tbody>
</table>
<br/>
<table class="table">
<thead>
<tr>
<th>Claim Subject</th>
<th>Value</th>
</tr>
</thead>
<tbody>
@foreach (var claim in Model.Claims)
{
<tr>
<td>
@Html.DisplayFor(modelItem => claim.Type)
</td>
<td>
@Html.DisplayFor(modelItem => claim.Value)
</td>
</tr>
}
</tbody>
</table>
}
The “Authentication” page displays the logged in User’s Role and Claims.
namespace devMobile.AspNetCore.Identity.WebApp.EFCore.Pages
{
[Authorize()]
public class RolesModel : PageModel
{
private readonly ILogger<RolesModel> _logger;
public List<Claim> Roles { get; set; }
public List<Claim> Claims { get; set; }
public RolesModel(ILogger<RolesModel> logger)
{
_logger = logger;
}
public void OnGet()
{
Roles = User.Claims.Where(c => c.Type == ClaimTypes.Role).ToList();
Claims = User.Claims.Where(c => c.Type != ClaimTypes.Role).ToList();
}
}
}
Each user can have role(s), with optional claims, and some optional individual claims.
The WebApp.EFCore project is intended to be the starting point for a series of posts about ASP.NET Core identity so I have not included Cross-Origin Resource Sharing (CORS), Cross Site Request Forgery (CSRF) etc. functionality.