We are developing a multi-tenant SaaS product in Azure which has an AngularJS front-end and Web API back-end. We use Azure AD for authentication and have hooked it up with ADAL JS (using the OAuth2 implicit grant). Being a multi-tenant application, we allow customers to authenticate against their own Azure AD (which may or may not be connected to an on-premise AD).
So far this all works nicely. ADAL JS takes the user to the Azure login page and once the user has authenticated, an OAuth2 token is issued. This JWT token is then sent with all API calls as a bearer token where we have our own claims transformation process for mapping the incoming claims from Azure to our application claims.
Rather than specify individual users in the claims transformation process, we try to do it by AD groups. This allows our customers to have security groups in their AD and then our application will use that to map to the correct application claims.
The JWT token we receive does not contain a groups
property, despite having set groupMembershipClaims
to SecurityGroup
in the AAD application manifest. I have since read in this tweet from Vittorio that
The implicit grant will NOT send those claims, as it returns the token in the querystring - it's easy to blow past max length
Upon further investigation, I also found this StackOverflow answer from Vittorio that says
I verified and in the implicit grant case you will receive groups always via the overage claim. Please refer to https://github.com/AzureADSamples/WebApp-GroupClaims-DotNet/tree/master/WebApp-GroupClaims-DotNet - it will show you how to process the overage claim to retrieve groups.
I had a look at the JWT token and it does not include any overage claim (identified by _claim_names
and _claim_sources
). I'm definitely a member of two groups in my Azure AD.
I also now appear to have two conflicting statements about whether it is possible to get group information (whether directly or indirectly) in the implicit grant token.
Question 1: Should I get an overage claim that I can use to get group information? If so, do I need to do anything to ensure that claim gets sent to me?
Whether I can get an overage claim with a link to the user in the graph API or whether I have to manually craft the link to get the user's groups, I'm still a little unsure how I authenticate with the graph API.
I need to contact the graph API from the back-end after receiving a request with a bearer token (from ADAL JS).
Question 2: Can I send the same bearer token to the graph API to read that user's directory information? Or do I need to authenticate directly from my application to the graph API tenant in the context of the application rather than the user?
Enable the implicit flowIn the left menu, under Manage, select Authentication. Under Implicit grant and hybrid flows, select both the Access tokens (used for implicit flows) and ID tokens (used for implicit and hybrid flows) check boxes. Select Save.
The Implicit Grant Type is a way for a single-page JavaScript app to get an access token without an intermediate code exchange step. It was originally created for use by JavaScript apps (which don't have a way to safely store secrets) but is only recommended in specific situations.
Disable implicit grant settings Once you've updated all your production applications that use this app registration and its client ID to MSAL 2. x and the authorization code flow, you should uncheck the implicit grant settings under the Authentication menu of the app registration.
apologies for the confusion here. I will double check the statement about the overage, but in any case - for the sake of unblocking you quickly, let's assume that you need to get the groups manually without the aid of the overage claim. You cannot reuse the token you send to your Web API. That token is scoped to your app, and any other recipient will (or should) reject it. The good news is that the flow through which your backend can request a new token scoped for the Graph is easy to implement. See https://github.com/AzureADSamples/WebAPI-OnBehalfOf-DotNet - the details in your case are a be a bit different (your web API has the audience == clientid of your app) but the topology and the code/calls involved are exactly the same. HTH! V.
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