I am learning / experimenting with Azure Active Directory B2C (AADB2C). I have created a web application that can sign-in or sign-up users (not using custom user flows) with OpenID Connect.
Once a user has signed in, I would like to make a call to Microsoft Graph to get information about the signed in user.
According to the docs, I initialize a client credential auth provider as follows:
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientSecretCredential = new ClientSecretCredential(config.TenantId, config.AppId, config.ClientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
I then try to make a request, as follows:
var user = await graphClient.Me.Request().GetAsync();
The above results in the exception:
Code: BadRequest
Message: /me request is only valid with delegated authentication flow.
When I try the following:
var user = await graphClient.Users[ '' ].Request().GetAsync();
The above results in the exception:
Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.
Many of the examples in the MS documentation state that the "User.Read" permission must be granted, but when using the Azure Portal the "User.Read" permission is not found, below is a screen snapshot of the Request API Permissions blade within the Azure portal - I am still not clear on the Note (highlighted in the image below).

When I do try to enter the "User.Read" permission, the following is displayed:

I also found this tutorial regarding how to Register a Microsoft Graph application, but it seems to be geared to administrators who want to access the graph, not "regular" signed-in users per se.
My question - Is there any working example that illustrates how (after a user is signed in) to read the users information from Microsoft Graph?
In order to make calls to Microsoft Graph with an application registered with the option "Accounts in any identity provider or organizational directory (for authenticating users with user flows)", the following must be done (additional reference at: https://learn.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-get-started?tabs=app-reg-ga):
Add the "User.ReadWrite.All" or "User.Read.All" application permission (depending on the application needs).
Note: When you add any of the above permissions via the Azure Portal, the status will initially be shown as "Not granted". Click on the line containing the permission, and then click on the "Grant admin consent for ..." button - (it is not intuitive at all), as shown below:

a popup window will appear to confirm, as shown below (click Yes to confirm):

Once confirmed, the permissions should appear as follows:

A few more gotcha's to be aware of:
The .Me method will not work, for example, using the following code:
var user = await graphClient.Me.Request().GetAsync();
... will still result in the exception:
Code: BadRequest
Message: /me request is only valid with delegated authentication flow.
however, you can make a request using the user ID; which may be obtained from the authenticated users claim(s), for example:
var user = await graphClient.Users[ "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ].Request().GetAsync();
The above call will work, however, be aware that some Graph properties are only returned if .Select() is used, for example, the "companyName" property is only returned if .Select is used, i.e.:
var user = await graphClient.Users[ "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ]
.Request()
.Select( u => new {
u.CompanyName
} )
.GetAsync();
The above threw me for a loop as some properties seemed to be missing after the call when .Select() was not used, see the following for more information:
https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http
https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0#properties
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