I am using Azure AD B2C to authenticate users of my mobile app. I use Microsoft.Identity.Client on the device AcquireTokenSilent
and AcquireTokenInteractive
to manage user authentication state. Everything works great.
When the user has completed authentication, my server will check their ID to see if they're registered in my user database, and if not will ask for their details and save them. At this point I have a local unique Id for the user which I would like to add to their access token so that other services can use it for authorization. So I call the AD B2C graph API to set a UserId custom attribute. I have registered the custom attribute with Azure AD B2C and my User Flows all have UserId selected under Application Claims so that it gets added to the JWT. I am basically following option 1 described here: Add claims into token Azure B2C. The configuration appears to be correct and everything works perfectly...
... except for one thing. The UserId claim only appears in the Access Token after the user logs out and logs in again.
So after the user authenticates, I register him in my DB, call the Graph API to set his UserId claim. Thereafter any time I acquire a token on the device, even if I use WithForceRefresh(true)
, I get a token without the UserId claim. If I call the Graph API I can see that the claim exists on the user's profile, but it doesn't make it to the token. As soon as the user logs out and in again, He gets a token that includes the claim.
To work around this I either need to force the user to log in again after he has registered, which would be silly. Or I need to call the Graph API and fill in the missing information if it's not present in the token, which would also be sub-optimal.
What am I missing here? What is the right way to force AD to refresh the user's access token with new claims without requiring the user to log in again?
UPDATE I used the example of a UserId for simplicity's sake, but as Jas points out below I could set static fields like that on registration using REST API claims exchanges. So to make my question more complete, let me add that I also want to be able to update claims after initial registration. For example, a user might be assigned one role on initial registration, and then be moved to a different role later. I would want to update the user's claims so that I could perform authorization on the user based on the updated claims in her access token. But if I cannot guarantee that those claims will always be up to date then I will need a fallback to my own database / service which would effectively make AD B2C an authentication provider with no authorization utility.
You should move the logic into the B2C user flow, and this would all be resolved rather than performing it after authentication. B2C doesn’t refresh token claims on refresh token flows (yet).
https://docs.microsoft.com/en-gb/azure/active-directory-b2c/rest-api-claims-exchange-dotnet
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With