I have successfully created an application that uses a new B2C Tenant for authentication and I can login and call APIs.
I have added new Attributes for the Users (Roles one of them). In my "User Flows" I have 1 flow for SignIn that has selected the Roles claim one to login and one to edit users. In the following images you can see the setup and the returned claims, after editing with the User Flow.
Selected to return data as claim
Decoded Token with extension claims and values
However, when I query Graph PI for the users + extensions, the extensions are not returned.
I have also access to the users using Graph API and I'm able to add extensions to the users by code using the Graph API. I can Add extended attributes, update them, retrieve them... In the code below I can Add them. These created with the Graph API I can retrieve later, but not the ones that I created with the B2C User Flow.
// Add extension without the guid from b2c_extensions_app
var extension = new OpenTypeExtension()
{
ExtensionName = $"extension_Roles",
AdditionalData = new Dictionary<string, object>()
{
{ "Roles", value}
}
};
await _graphServiceUsers[userId].Extensions.Request().AddAsync(extension);
// Add extension with the guid from b2c_extensions_app
var extension2= new OpenTypeExtension()
{
ExtensionName = $"extension_00000000-e062-0000-8ec8-800000000003_Roles",
AdditionalData = new Dictionary<string, object>()
{
{ "Roles", value}
}
};
await _graphServiceUsers[userId].Extensions.Request().AddAsync(extension2);
Neither of the scenarios above are linked to the B2C User that is returned with the claims.
I can retrieve the user with the extensions with the following code. And I get the extensions created from Graph API, but not the ones that are shown in the claims of the Token in the images above.
_graphServiceUsers[userId].Request().Select(UserSelectExpression).Expand("extensions").GetAsync();
All the custom attributes seem to be disconnected. I would need to update the ones that are returned as Claims, as they are the ones that I want to modify with the Graph API.
If you see the image below, you can see how the Extended properties are coming, but not the ones that I added from B2C. In the token you can see the mapped claim having one value, different from the value I added and retrieved from Graph API.
Different values from Claims and retrieved data using Graph API
I think they just made it too difficult, when it reality should be a lot easier to achieve something as simple as adding a new attribute and retrieve the values and work with them using Graph API.
Additional Info:
I'm using the Graph API application to access using the api
I added all the permissions that had been suggested
In Graph Explorer (same results as C#):
https://graph.microsoft.com/v1.0/users/600001c5-0000-49b9-89c5-0000c80000fc?$select=displayName,identities,extension_39b4801c-5782-48d4-be6a-1cae6a8a881a_Roles
Result (Exception): Result Graph Explorer
----------- UPDATE WITH SOLUTION --------------
I just wanted to add a quick note to clarify that the real problem, just in case someone has the same problem, as it's a bit complicated to get started with Graph API.
The problem (as of today) is that you need to use the Beta version of the Nuget packages or the Beta (graph.microsoft.com/beta) graph api to retrieve all the extension attributes. The stable version doesn't work.
- The nuget package that worked for me is Microsoft.Graph.Beta 4.21.0-preview.
- The package Microsoft.Graph stable 4.11.0 published Nov 25 2021 doesn't retrieve the extension properties.
Note: Something that is important is that the extension extension_39b0000c570000d4be6a1cae7a9a000a_Roles doesn't have the - from the guid.
- Use this 39b0000c570000d4be6a1cae7a9a000a
- and not this 39b0000-c570-000d-4be6a1-cae7a9a000a (remove the dashes)
Also, an additional thing to remember is the use of the guid from the extension to load only the extension: The first one to load all the attributes for the user. The second one to load only the Custom extended attribute.
var user = await _graphServiceClient.Users[userId].Request().GetAsync();
var user2 = await _graphServiceClient.Users[userId].Request().Select("id,extension_39b0000c570000d4be6a1cae7a9a000a_Roles").GetAsync();






