I've a REST API:
@CurrentUserAccessLevel(userId = "#studentId")
@GetMapping(value = "/{course-code}/users/{student-id}")
public UserCourseDetailsDto getUserCourseDetails(@PathVariable(value = "course-code") final Long courseCode,
@PathVariable(value = "student-id") final Long studentId) {
return userCourseService.getUserCourseDetails(studentId, courseCode);
}
and custom authentication annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@PreAuthorize("@applicationUserDetailsService.hasAccessToResourceOwnedBy(#userId)")
public @interface CurrentUserAccessLevel {
String userId();
}
the annotation uses method hasAccessToResourceOwnedBy(userId):
public boolean hasAccessToResourceOwnedBy(final Long userId) {
final User currentUser = userService.resolveCurrentUser();
return isAdmin(currentUser) || Objects.equals(currentUser.getId(), userId);
}
but I'm getting null as userId. However, if I replace
@PreAuthorize("@applicationUserDetailsService.hasAccessToResourceOwnedBy(#userId)")
with
@PreAuthorize("@applicationUserDetailsService.hasAccessToResourceOwnedBy(#studentId)")
I obtain requested user id.
Basically, I need this annotation to avoid horizontal escalation of privileges, maybe there is some better solution?