ms-identity-javascript-angular-tutorial: When using the MSALGuard and RoleGuard on a route, the Role guard will allow access even if the user does not have the correct role
Issue
When using the MSALGuard and RoleGuard on a route, the Role guard will allow access even if the user does not have the correct role! This is due to the fact that there is no guard sequence in Angular.
This issue is for the sample
- [ ] 1-1) Sign-in with Azure AD
- [ ] 1-2) Sign-in with Azure AD B2C
- [ ] 2-1) Acquire a Token and call Microsoft Graph
- [ ] 3-1) Protect and call a web API on Azure AD
- [ ] 3-2) Protect and call a web API on Azure AD B2C
- [ ] 4) Deploy to Azure Storage and App Service
- [x] 5-1) Call a web API using App Roles
- [ ] 5-2) Call a web API using Security Groups
- [ ] 6-1) Call a multi-tenant web API
- [ ] 7-1) Call Microsoft Graph using on-behalf-of flow
- [ ] 7-2) Call a web API using Proof of Possession tokens
This issue is for a
- [ ] bug report -> please search issues before submitting
- [x] question
- [ ] feature request
- [ ] documentation issue or request
Minimal steps to reproduce
Change the sample so that the root of the app also needs the MSALGuard, this will trigger the login sequence as soon as someone uses the website. In other words no need for the LOGIN button. Open a new InPrivate windows and navigate straight to an URL that has both guards active. If there was no previous login, the user is redirected to the Azure AD login flow, BUT the RoleGuard already finished it’s check and returned TRUE ( https://github.com/Azure-Samples/ms-identity-javascript-angular-tutorial/blob/main/5-AccessControl/1-call-api-roles/SPA/src/app/role-guard.service.ts#L34 ). Due to the fact that there were no accounts available yet.
After the login flow of Azure AD the Role guard is no longer checked and the user is presented with the URL he typed in, although he should not be able to see it.
Expected/desired behavior
Role checks can only be done after an account has been acquired AND should be done each time!
Library version
msal-angular: ^2.1.2 angular 13 & 14
Browser and version
Edge
Mention any other details that might be useful
I know this is a limitation of Angular ( there is no guard replay or guard order ), but this Role check example should compensate for this somehow. Because if we want to use role guarding, it should always be checked when we have the user roles available.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 22 (10 by maintainers)
Sounds great! Still working on making this extensible by default, hopefully will get this in to msal-angular
@derisen just wanted to circle back that this works great! But true, now having that baseGuard directly in our code would be nice to get rid off once the base lib has a guard that is extendable.
Thanks! Will take a look as soon as I find some time!
@Depechie of course, my bad. Right now the updated sample is using a custom guard based on MsalGuard (pretty much copy/paste), and then extending it in a role guard. Ideally the MsalGuard itself should be extensible, and I’m separately working on a PR to msal-angular for doing just that. That could take a while so for the moment, I think this is the way forward, but I’m open to suggestions.
That’s fair enough. What I’m thinking is that it might be better to use a single custom guard that combines
MsalGuard
andRoleGuard
, though I can also see the merit of getting multiple guards to work in tandem. There’s an understanding thatMsalGuard
will not only be able to cover all use cases, so this repo should have at least one example of a custom guard to replace it. Let me look into these. I’ll keep this issue open until then -and thank you for all the feedback!@Depechie apologies for the late response, we’ve been unusually busy these days. I can reproduce this with the repo you shared. It seems this is simply not a scenario we’ve considered i.e. enabling
RoleGuard
for the main route where the user signs into.My understanding is that, in the sample from this repo, when a user hits a component route that has
MsalGuard
andRoleGuard
enabled (likehttp://localhost:4200/dashboard
), she will prompted for sign-in viaMsalGuard
, and then after sign-in will be redirected to the main route firsthttp://localhost:4200/
(which doesn’t haveRoleGuard
), and then will be redirected back tohttp://localhost:4200/dashboard
, which at that point account info will be available toRoleGuard
.I don’t have a solution right now but I will put this to backlog and pick it up first when we start updating the samples in this repo. I’m also not entirely sure if this is a legitimate use case, or rather, the best approach to handle this use case. If the user is simply needed to be in a particular role to sign-in to the application, perhaps requiring user assignment would be a better way to handle it?
Nevertheless, if you come up with a solution please feel free to make a PR.
Hey @derisen I will try to create a sample app and put it up on GitHub and list steps I did.
Maybe I did something wrong and that way you can spot it.
I will get back later this week!
Thx for the info by the way!
@Depechie thank you so much for catching this. Let me try to reproduce it and get back to you.