Authorization working now
Obligatory git/GH troubles
I’ve been making good use of git branches, though I have to say my poor foresight in not knowing authorization was going to be a big task reared its head where I now have a auth (authentication) and an authorization (authorization) branch on my fork. Me and Drew also found out that apparently commits made after a PR is made aren’t automatically added to the PR.
Authorization
Dr. Goadrich made some roles in the Azure backend, though he didn’t do them right first because the example in the textbox misled him, making a role for an admin be name: Admin and value: Everything.Update. Every tutorial I saw was written like [Authorization(Roles = "Admin"], so I was confused when I was debugging why that didn’t work and saw that my role was apparently Everything.Update. We met and he changed all the role values to be the same as the names. Thanks Microsoft?
Important discovery: if the user is logged in, in page models there’ll now be a User object which is an instance of ClaimsPrincipal. From there there’s a Claims property, which spits out a bunch of garbage as a linq key-value list of Type, Value. I say garbage because most of the entries are three letter something-acronyms and the values range from gibberish in hexadecimal to gibberish in hexadecimal with differing alpha case with regular slashes and pluses. Anyway, the entries that matter are preferred_username, name, and roles, which are the email, Last, First name of the user, and the user’s roles (how does it look with multiple roles?). I got that information because I made a /Debug page that prints the user’s claims, which I hope to add more info to as I need it. You’re a peasant if you debug with print statements! (t. peasant)
Because of the confusion before, I decided it would be better to use policies for authorization so I didn’t have to hardcode the roles in each page. Policies turned out to be more annoying, and I eventually switched to just using ClaimsPrincipal.IsInRole(). By the way, [Authorize(Roles = "Admin,Committee,Evaluator")] works as a boolean OR but IsInRole("Admin,Committee,Evaluator") doesn’t. Thanks Microsoft!
Then it was just a matter of getting that IsInRole method to actually work. The tutorial was surprisingly helpful, but still didn’t really explain what was going on. Thus sits these lines now in Program.cs:
// Roles are sent as a "roles" claim.
options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
options.TokenValidationParameters.RoleClaimType = "roles";
// I don't know what these do.
options.MapInboundClaims = false;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
Do you know what these do?
The page model of /Evaluate doesn’t hardcode the Evaluator property anymore. It selects for an evaluator whose email matches the logged in user’s one, but if it doesn’t find one it creates an evaluator instead. This really should be done whenever someone logs in (for both evaluators and students), but I made an issue for it. It’s kinda weird syncing data from the Microsoft server and our local db: having all the pages work with cookie-based authorization yet we still keep track of a local Rank property on each evaluator, and it’s never actually used anywhere, but I think removing it is probably a mistake.
End
Ultimately it’s in a state now that you can log in/log out, are only shown nav links to pages that you’re allowed to access, in actuality can only access pages you’re allowed to access, and the evaluator in the page model of /Evaluate isn’t hardcoded anymore. I realized that /Review doesn’t actually need per-evaluator authorization so I removed the Evaluator property from its page model.
The next big step is now to work on a student front end to submit packets to, but that’ll be a bit annoying until we can get student accounts for testing. I sent an email to the help desk requesting test accounts so we don’t have to rely on emulating 4 different roles with 3 accounts, 2 of which are actively working on it and need to be able to access every page lol.