I am coding a .Net core
API that serves administrators
and employees
. These people see the same interface.
The only difference is that the manager
can view the profile
of other employees. The employee can only view his own profile. I am using JWT
. I have completed the development for the administrator section.
I want to use the same APIs in the employee section as well. But in this section, I need to get employeeId
from JWT
, not from the request.
I created an attribute for the fields representing the employeeId. Example:
public async Task<ActionResult<AddressDto>> Get(long deciderType, [EmployeeId] long deciderId)
I want to have an action filter, in that action filter
if it has the desired role, I want to give the employeeId
in JWT
to the request variable that has this attribute. In this case to deciderId. Is this possible? I could not find a way to filter the request parameters by attribute.
Or is there a better way to do this? I can do these operations in different APIs with the same business but I am not sure if this is the right way
It's better to separate your Get APIs and set Authrozie Attribute with Role Admin for your administrator, and also one another Get for employees.
If you have created your JWT like this
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
};
Now in your Get method which belongs to the employee, you do not need to send EmployeeId and you can get it from the JWT token
var claimsIdentity = this.User.Identity as ClaimsIdentity;
var userId = claimsIdentity.FindFirst(ClaimTypes.Name)?.Value;
In conclusion, you would have two Get endpoints.
For Administrator
[Authorize(Role=RolesEnumeration.Admin)]
public async Task<IActionResult<AddressDto>> Get()
{
//get all addresses from the DB by pagination
}
And for employees
public async Task<IActionResult<AddressDto>> Get()
{
var claimsIdentity = this.User.Identity as ClaimsIdentity;
var userId = claimsIdentity.FindFirst(ClaimTypes.Name)?.Value;
//get employee address from the DB by userId
}