Authentication¶
Authentik is an identity broker and authentication server that manages integrations for all identity providers (Canvas, etc).
- In this setup:
Authentik is the primary authority for user authentication. It issues JWTs that the frontend can use to call the backend.
- Authentik manages scopes (i.e., what each user/role can do) and enforces these scopes when handing out tokens.
Authentik maps external roles (e.g., “Teacher” or “Student” in Canvas) to the internal roles (Instructor, Student)
Backend receives the JWT from the frontend and uses Authentik to validate the token and verify the user’s permissions before giving access to data or performing actions.
The above figure displays the previously mentioned authorization flow.
Admin Authentication Level¶
Manages Policies: Can create, modify, and enforce course-wide/assignment-based policies.
Instructor-level Access to All Sections: Can view and manage every section of the course.
Instructor Authentication Level¶
Course Section Management: Can manage their specific course sections, including assignments, grades, and rosters.
Handles Extension Requests: Responsible for approving or denying student requests for assignment extensions.
Manages Late Passes: Oversees the issuance and consumption of late passes.
Master Migration: Responsible for managing migrations.
Student Authentication Level¶
Extension Requests: Can submit requests for assignment extensions.
Late Passes: Can view and apply available late passes.
Server‑side Enforcement of Roles¶
All API endpoints delegate authorization to our SecurityManager (in
edu.mines.gradingadmin.managers.SecurityManager). Its job is to:
Extract the incoming user’s JWT from the servlet request (via
setPrincipalFromRequest(HttpServletRequest)).- Lookup the
Userentity (inreadUserFromRequest()), by: Looking up by
oauthId(the JWT’s sub claim).Fall back to linking an existing user by CWID.
Creating a new user if no match is found.
- Lookup the
- Simple checks that controllers or service methods call:
getIsAdmin()→ reads theis_admin`claim from the JWT and throwsAccessDeniedExceptionif false. Use it to gate any admin operations.hasCourseMembership(CourseRole, UUID)→ looks up the user’s role for a given course viaCourseMemberService.getRoleForUserAndCourse(...)and compares it to the requestedCourseRoleenum (Instructor, Student, etc).getCredential(CredentialType, UUID)→ fetches the user’s per‑user or per‑course credential (e.g. Canvas API tokens) and fails if none exist.
Throw
AccessDeniedExceptionimmediately when any check fails.
An example of using this to check a user’s privileges is within the Backend’s filters,
1...
2if (!securityManager.hasCourseMembership(CourseRole.INSTRUCTOR, UUID.fromString(courseId)) &&
3 !securityManager.hasCourseMembership(CourseRole.OWNER, UUID.fromString(courseId))){
4 log.warn("Blocked attempt by '{}' to access course '{}' as an instructor!",
5 securityManager.getUser().getEmail(),
6 courseId);
7 throw new AccessDeniedException("Not enrolled in course as an instructor!");
8}
9...