I'm experiencing some strange behavior on our AAD. After a user signed in successful, we're getting an unauthorized for some users on our API calls. Turns out that a claim in the JWT is missing. Some users are getting the "groups" claim (array of all groupIds he belongs to) and some are getting the "hasgroups" claim (a boolean if the user has groups, no Ids). As our API app is checking this "groups" claim for authorization, the users who don't have this "groups" claim are getting a 403.
Nevertheless, in the manifest of the app registration I set the “groupMembershipClaims” from “null” to "All" or "SecurityGroup", which should do both the trick. Also set the "oauth2AllowImplicitFlow" to true as we're working with an Angular app which uses OAuth2. Next to that I've compared almost all users settings and apart from some extra groups the users are identical. The affected users don't have a lot of groups, some have even around the 5 groups at max.
Do I overlook something or what's causing this difference in claims? How can I solve this so all users are getting the "groups" claim?
Got this feedback from MSFT internals:
In the implicit flow, oauth will return the Jwt directly from the
intial /authorize call through a query string param. The http spec
limits the length of a query string / url, so if AAD detects that the
resulting URI would be exceeding this length, they replace the groups
with the hasGroups claim.
And this
This is by design when using implicit grant flow, regardless the
"groupMembershipClaims" setting in the manifest. It's to avoid to go
over the URL length limit of the browser as the token is returned as a
URI fragment. So, more or less after 4 user's groups membership,
you'll get "hasgroups:true" in the token. What you can do is to make a
separate call to the Graph API to query for the user's group
membership.
So will need to do an extra roundtrip to Graph API in order to get the user groups. Hope this helps others too.
This is now documented in the Azure AD token reference at https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-token-and-claims.
For the OAuth2 implicit grant flow it uses the hasGroups
token and the documentation states for this token:
Used in place of the groups
claim for JWTs in implicit grant flows if the full groups claim would extend the URI fragment beyond the URL length limits (currently 6 or more groups).
For other flows:
if the number of groups the user is in goes over a limit (150 for SAML, 200 for JWT) then an overage claim will be added the claim sources pointing at the Graph endpoint containing the list of groups for the user.
You can use the Graph API to obtain a user's groups using https://graph.windows.net/{tenantID}/users/{userID}/getMemberObjects
.
Alternatively there is the endpoint at https://graph.windows.net/myorganization/isMemberOf?api-version
as documented at https://msdn.microsoft.com/library/azure/ad/graph/api/functions-and-actions#isMemberOf