Having trouble getting Azure AD user's groups - azure

I'm currently using node.js passport library to authenticate using the OIDC Strategy with an azure registered app using a client ID and secret.
http://login.microsoftonline.com/{org id}/v2.0/.well-known/openid-configuration
I am not having any trouble getting the user profile back of the person who logged in, but I am hitting a wall when trying to get the groups. In my app, I need to authorize the user based on their active directory groups. I am getting back this piece of json:
"_claim_names\":{\"groups\":\"src1\"},\"_claim_sources\":{\"src1\":{\"endpoint\":\"https://graph.windows.net/{org guid}/users/{user guid}/getMemberObjects\"}}
I'm not sure what I need to do using this to get the groups. I tried generating a bearer token, passing that in a header, and getting the groups but it says I am unauthorized using Postman. Do I need certain permissions in the app? Also why is it using graph.windows.net when I'm trying to use graph.microsoft.com?
Is there an easier way to do this once the user has logged in?

Overage indicator claim when user is member of many groups
The claim you're getting back as part of json shared in question is an overage indicator claim.
"_claim_names\":{\"groups\":\"src1\"},\"_claim_sources\":{\"src1\":{\"endpoint\":\"https://graph.windows.net/{org guid}/users/{user guid}/getMemberObjects\"}}
It means that the user is member of many groups and instead of including information about all the groups as part of token (which would make the token too big), you will need to query that information separately.
Read more about it here: Access Tokens Reference
How to get groups information?
Your application needs to make a separate call to Microsoft Graph API to get the groups information for user.
Relevant Microsoft Graph APIs
user: getMemberObjects
user: getMemberGroups
Check member groups
Permissions Required by your application
Each of the API links above mention the required delegated or application permissions that are required as part of documentation.
You will need to update your app registration in Azure AD to require the relevant permissions (and also go through Admin consent, in case the permission required needs admin consent)
Token to call Microsoft Graph API
You mention that you've tried generating a bearer token, passing that in a header, but you got Unauthorized error.
Once you're done with the permission changes for your application, acquire a token specifically for Microsoft Graph API from your application. The bearer token used to access your application may not directly work with Microsoft Graph API.
Also make sure you go through Admin consent in case any of the permissions require Admin consent. If it's a single tenant application, "grant permissions" directly from azure portal by an administrator should work, in case of multi-tenant app you can use the Admin consent endpoint.
Code Sample: Here is a quick tutorial for calling Microsoft Graph using Node.js.. you may find other good ones as well.
Azure AD Graph API (graph.windows.net) vs Microsoft Graph API (graph.microsoft.com)
You have a valid question about the endpoint.. "Also why is it using graph.windows.net when I'm trying to use graph.microsoft.com?"
General recommendation is to use the newer Microsoft Graph API, unless the functionality/information you're looking for isn't available with Microsoft Graph and only Azure AD Graph API can help. Read more about recommendation and comparison here: Microsoft Graph or Azure AD Graph
Since information about groups is available in v1 endpoint for Microsoft Graph already (not beta), you should make use of Microsoft Graph API.
Here are a couple of related SO posts: SO Post 1 and SO Post 2

Related

Best way to authorize with AzureAD app registration: roles or group claims when only one AD group is required for access

I have an AzureAD application registration for my front end SPA. I am using Angular with Microsoft’s #azure/msal-angular v2 authentication library. My app registration has all the necessary redirect URIs and configured for proper OAuth2 OpenID Connect using authorization code flow with PKCE. My app is using the Microsoft Graph API with only the User.Read scope. I can authenticate just fine. If my app, however, is only available for one group of people, defined by an AD group and assigned to the Users and Groups section in Azure, what is the best way to validate the logged in user is authorized? I’ve tried enabling optional group claims for the access token, but those don’t come through for some reason. I then tried adding roles-I have an “admin” role, which is the only one I need. This role is assigned to the AD group I mentioned earlier. The roles claim does come back, and I can use that, but this seems silly when I should be able to just validate if the logged in user is in my AD group. The roles approach does have the nice feature of just assigning users different roles to validate authorization for development purposes, but not sure if there’s a better way.
At some point there will be an API I need to plug in. Would it be best to get the claims from that and use that for validation?
Is there a scope or setting I’m missing? Am I achieving this all wrong? Thank you to all who reply.
At this point, you have a SPA that calls a MS 1st party API, which is MS Graph.
Since you are acquiring an accessToken to MS Graph, this accessToken can not be changed - it is meant to be decoded and validated by MS Graph itself, so you will not be able to add any extra claim on that token since you do not control the resource.
Also, your client should treat the accessToken as an opaque string, you should never rely on any claim from the accessToken on the frontend.
You can read more about it here:
https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens
If you want to do some sort of authorization on the frontend, like deciding which routes your user will have access to, you need to rely on the idToken. For the idToken, you can enable the Groups claim and get a list of groups that the user is a member of.
If, as mentioned, later down the line you need to create a custom API and call it from your SPA, then, on that scenario, you can indeed add the Groups claim to the accessToken, because it will be a resource that you control, and then authorize the requests that hit your API based on that claim
MS has a sample that shows exactly how to use security groups for access control, using an Angular frontend with a .NET Core Web API. Give it a check here:
https://github.com/Azure-Samples/ms-identity-javascript-angular-tutorial/blob/main/5-AccessControl/2-call-api-groups/README.md

How to get user profile info from Azure Rest Api with user_impersonation as scope

I've an Azure AD app setup, the Rest api's under scope: user_impersonation works but I also need user profile info from some GET API request (with same scope as I cannot have two scopes under one access token). I could not find a suitable API for it.So, any help in this regards will be highly appreciated.
Thanks in advance!
As you are making requests to different APIs, you will need to request separate access tokens for this information.
In the case of user profile information, you will need to request a token for the Graph API resource with the User.Read scope.
Depending on the type of application, you can either request this information on behalf of a user or as a service. When requesting as a service, you need to grant the User.Read.All permission instead (docs.
You can use Profile API in Microsoft Graph to retrieve yourself and another user profile.
Using Profile API use for retrieve the sing-in user profile information together Azure AD or account information. This information we can use in application as requirements and we can store as requirements.
when you use these API you will need to valid permissions to access profile information.
Example : https://graph.microsoft.com/beta/me/profile/
More information about Use the Profile API read these official document by Microsoft Documents.

Why is an Azure permission missing from the scopes of my JWT token?

I have a problem regarding the permission granted to my app by the user showing up as a scope in my JWT.
I want to allow the user to see a list of his tenants (Office 365) on my page. For this I need a token with the https://management.azure.com/user_impersonation scope. I added the permission to the Azure API Permissions. When the user first logs in he sees this:
From this screen I assume my setup works, since the user gets asked to grant my app permission for what I need (Access Azure Service Management as you). But when I paste the JWT on the JWT Debugger I don't see the scope user_impersonation among the scopes.
I get this:
I already tried to remove the app from the test-user's applications (in their Azure Portal) to get it to ask again for consent but it's still the same. Other test users have also the same result.
What I'd need is simply to see user_impersonation among the scopes. That would allow me to call the API endpoint that returns a list of my user's tenants.
You need to acquire the access token for the https://management.azure.com resource.
Or if using v2, request it for the https://management.azure.com/user_impersonation scope.
That looks like an MS Graph API token.
An access token is always only valid for one API, so you need to ask for a token for the Azure Management API.
It works now!
So, I tried to get scopes for both https://management.azure.com/ and https://graph.microsoft.com/ in one single token. As Juunas explained, you have to get a separate token for each API. But can ask consent for both at the same time though.
My flow is this now:
I log the user in while asking him to consent to some permissions (for both API's and on first login only)
I request a token in the background for the Graph API scopes
I request a second token for the Azure Management API scopes

Azure AD - Populate Group Information in Claims

I am trying to populate the Claims token with User Group Information that I will fetch from Graph API. This is be specifically useful to port an existing Windows auth application to Azure. All my IsInRole() functions will work as is. I tried following this post
Populate Claims Information from Graph API
but unless I update the app manifest with groupMembershipClaims, I may not be able to populate the groups information. I am trying to avoid this since I am not a Global Admin on my corporate tenant. Is there any more sample codes that I can follow to do the same?

Permission error accessing /.auth/refresh

I'm using Azure App Service with authentication using Google and Microsoft account.
I can access mysite/.auth/me, without an issue upon login in.
But to refresh token, /.auth/refresh is returning me following exception.
You do not have permission to view this directory or page.
Not sure what access to be granted here in Azure blade.
The error message is actually a bit misleading. It's not that you don't have permission to access the API, but rather there are probably no refresh tokens in your token store. The way to acquire refresh tokens during user login is a little different for each provider. More details here:
https://cgillum.tech/2016/03/07/app-service-token-store/
In order for this to work, the token store must contain refresh tokens for your provider. If you’re not familiar with how to do this, here are some hints:
Google: Append an "access_type=offline" query string parameter to your /.auth/login API call (if using the Mobile Apps SDK, you can add this to one of the LogicAsync overloads).
Microsoft Account: Select the wl.offline_access scope in the Azure management portal.
Azure AD: This is a little complex right now, but take a look at my next post on enabling Graph API access. Follow the setup steps and this will also enable you to get refresh tokens for Azure AD (you can omit the Read directory data and the resource=… parts if they don’t apply to you). The plan is to simplify this in the future.

Resources