I'm working on an aspnet core 1.0 project, I've recently understood what claims are and how to use them to achieve policy based authorization.
I want to get all users that are authorized with a given policy (i.e. users that have a given claim, let's say Claim {Type = "CanReceiveXReport", Value = True}
)
The code I'd expect to do this is something like:
public static IQueryable<User> WithClaim(this IQueryable<User> users, string claimName) =>
users
.Include(u=> u.Claims)
.Where(u=> u.Claims.Any(c=> c.ClaimType == claimName));
When I run the above code, for all users, user.Claims
is always empty. I've also tried to materialize the query by adding a ToList()
after the Include()
with no success.
When I realized this wasn't working I expected there to be a ClaimsManager<T>
of some sort to do this kind of operations.
All the apis and answers I've found are focused on getting claims for a single user.
I know I could do something like what this answer but I rather not do that, I want that query to be run in the database.
I imagine it's possible to create a stored procedure, but I'd rather mantain my domain logic in my app.
(That I think are relevant)
{
"Microsoft.AspNetCore.Identity": "1.0.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.EntityFrameworkCore.Relational": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
"Microsoft.NETCore.App": "1.0.0"
}
I believe you are looking for this method in UserManager:
/// <summary>
/// Returns a list of users from the user store who have the specified <paramref name="claim"/>.
/// </summary>
/// <param name="claim">The claim to look for.</param>
/// <returns>
/// A <see cref="Task{TResult}"/> that represents the result of the asynchronous query, a list of <typeparamref name="TUser"/>s who
/// have the specified claim.
/// </returns>
public virtual Task<IList<TUser>> GetUsersForClaimAsync(Claim claim)
{
ThrowIfDisposed();
var store = GetClaimStore();
if (claim == null)
{
throw new ArgumentNullException(nameof(claim));
}
return store.GetUsersForClaimAsync(claim, CancellationToken);
}