I am building a webapp that uses windows authentication and supplements it with roles and claims from a local DB. I am planning to use a JWT to store this information once the user is authenticated.
Our organization has different departments and I am wondering how I could go about implementing roles/claims in this case.
For example:
Bob is an admin for both department A and B.
In Bob's principle, how could I add claims that reflect this. I.E.
bob.claims = new claim[] {
new claim() { department = "A", role = Roles.Admin },
new claim() { department = "B", role = Roles.Admin }
}
Then I could do something like:
[Authorize(IsInDepartmentRole(Department: "A", Role: Roles.Admin)]
Keep in mind this is all pseudo-code.
I realize storing this info in a JWT might not work out, so I am willing to move to an in memory cache (or similar).
How can I accomplish this?
You can add this information as claims, but since a claim consists of a type-value, the approach in the pseudo code will not work.
There are some options, but I would suggest the following:
new Claim { Type = "DepartmentRole", Value = "A;Admin" }
In any case, keep the type a constant. The value can be split into A and Admin, corresponding to department and role. You can add multiple claims of the same type.
Now you can define a policy:
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOfDeptA", policy =>
policy.RequireClaim("DepartmentRole", "A;Admin"));
}
The authorize attribute only allows strings as parameter, so again your pseudocode won't work. But you can now use this, where AdminOfDeptA is the configured policy:
[Authorize("AdminOfDeptA")]
If you don't want to define all combinations, you may want to take a look at resource-based authorization.