Reputation: 3303
I'm trying to add a "Sign in with Microsoft" button to an Angular App with the MSAL library and the V2 endpoint. The app needs to work with both personal and organizational accounts which will then be cross referenced with existing users in my database. i.e. the Microsoft login is just a convenience on top of my existing login system.
The flow I've adopted so far is:
1. User requests a JWT id token via implicit flow in the browser, using the graph scope openid email profile
.
2. Browser posts the id token back to server.
3. Server verifies the token (I'm allowing multiple tenants and do NOT check the issuer field of the JWT).
4. Server first looks for email in the email
claim.
5. If no email
claim is present then check the preferred_username
.
6. If the email matches one of our registered addresses then user is signed in. If no match or no email then error is returned.
So far, so good. I've checked this with both a personal account and an organizational account and it works.
However, this whole approach relies heavily on the email address of the user being verfied.
In the token docs I've read that preferred_username
is mutable and "must not be used to make authorization decisions". I can see the logic, but in this case I'm only using the email for authentication not resource authorization.
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-tokens
So my question is. Is there any way that a spoofed (non-verified) email could be present in either the "email" or "preferred_username" fields in a V2 id token?
If yes, is there anyway I can cross check using graph API to see if it has been verified?
My potential workaround is to send my own verification email to link the MS account with our own accounts, but I would like to avoid that if possible.
Upvotes: 3
Views: 1201
Reputation: 58773
I doubt those could be spoofed. A bigger problem is if the user principal name/email changes. As you can see in the Token reference, there are 2 claims which would work much better for identifying the user:
Since the subject is "always present in the tokens that Azure AD issues", it might be the best choice. Object id is good if you need to identify the user in Microsoft Graph API for example.
Upvotes: 2