I have an ASP-net Web api endpoint as below. It Authorizes the roles via a JWT token with via Roles:
[HttpPost, Authorize(Roles = "Admin, Teacher")]
public async Task<ActionResult<CourseParticipant>> AddCourseParticipant(Guid userID, Guid CourseID)
{
return Ok(await _calendarParticipantService.AddCalendarParticipant(userID, CourseID));
}
Now, I dont want Any Teacher to be able to change the participant. Only the teacher who "owns" the course. My idea is to simple add the GUID of the teacher to the JWT token and then compare. But how do i read the JWT token on the request? and is there a simpler or "correct" way to do this?
CodePudding user response:
At first I wanted to recommed policy based authorization. But since you need the actual data in your authorize to check the ownership, this would not be the correct way.
Ressource-Based authorization is the keyword.
With ressoure-based authorization you can write a AuthorizationHandler for your ressource (Course
) and apply this to a policy.
CodePudding user response:
You need to add teacher guid to the users
claims while creating account like this.
//create user account for teacher ommited
var teacherUser = await _userManager.CreateAsync(identityUser, userDto.Password);
_userManager.AddClaimAsync(teacherUser, new Claim
{
"user_id", $"{teacherUser.Id}"
});
Now update your api endpoint like below. Also Inject
UserManager
in controller
[HttpPost, Authorize(Roles = "Admin, Teacher")]
public async Task<ActionResult<CourseParticipant>> AddCourseParticipant(Guid userID, Guid CourseID)
{
var user = await _userManager.FindByIdAsync(userID.ToString());
if(await _userManager.IsInRoleAsync(user, "Teacher"))
{
var userClaim = User.Claims.FirstOrDefault(x => x.Type == "user_id");
if(userClaim == null || userClaim.Value != userID.ToString())
{
return Unauthorized;
}
}
return Ok(await _calendarParticipantService.AddCalendarParticipant(userID, CourseID));
}