I'd like to write a ClaimsPrincipal
extension that returns the company associated with a user has the IsLimited
flag set.
public static class ClaimsPrincipalExtensions
{
public static bool IsLimitedUser(this ClaimsPrincipal principal)
{
ArgumentNullException.ThrowIfNull(principal);
var claim = principal.FindFirst(ClaimTypes.NameIdentifier);
if (claim != null)
{
return dbContext.Users
.Where(u => u.Id == claim.Value)
.Select(u => u.Facility.Company.IsLimited)
.FirstOrDefault();
}
return false;
}
}
But how do I initialize dbContext
in the code above?
I am looking at calling this method from my _Layout.cshtml page, so it would be called on every single page request so I want it as optimized as possible. In fact, if possible, I'd like to cache the value with the ClaimsPrincipal
. Anyway, I'd still need the DbContext
the first time.
For using the dbcontext inside the static class, you need use the method injection, you should modify your method to add new parameter IServiceProvider and then pass it from the layout page.
More details, you could refer to below codes:
public static class ClaimsPrincipalExtensions
{
public static bool IsLimitedUser(this ClaimsPrincipal principal, IServiceProvider serviceProvider)
{
ArgumentNullException.ThrowIfNull(principal);
// Resolve DbContext from the service provider
using (var scope = serviceProvider.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var claim = principal.FindFirst(ClaimTypes.NameIdentifier);
if (claim != null)
{
//// Query the database
//bool isLimited = dbContext.Users
// .Where(u => u.Id == claim.Value)
// .Select(u => u.Facility.Company.IsLimited)
// .FirstOrDefault();
var test = dbContext.Users.ToList();
bool isLimited = true;
return isLimited;
}
}
return false;
}
}
Layout:
@using Microsoft.Extensions.DependencyInjection
@inject IServiceProvider ServiceProvider
...
@{
var isLimitedUser = User.IsLimitedUser(ServiceProvider);
}
@if (isLimitedUser)
{
<p>User has limited access.</p>
}
else
{
<p>User has full access.</p>
}
Result: