5

I would like to add custom claims to the tokens of some specific users that are managed by admin through graph api.

Basic scenario is as following:

User is signed up to my application. Initially all users have limited access to resources. As an admin, I will update some users by adding specific claim so that my app will authorize the user for specific resource.

There are couple of ways to include claims (extended properties) in tokens in my understanding.

  1. Create user attribute through azure portal and use it in signup policies to collect the value from user. In my case, the custom attribute will be applied only by admins so I won't let user manage this claim. So this is not a good approach for me and also it doesn't make sense to me as I will add new properties after many users already signed up so there will be no way to collect this information.

  2. The other way is to add extended property through Graph Api. To accomplish it, I need to create a new app (through app registrations) and register extended property to this app through graph api. Then update user(through graph api) by adding newly created extended property in that application. At the end, I would expect this extended property will show up in my token but no chance. It is not visible in portal, in token but only in graph api responses.

  3. Create custom polciy which I don't will as it is not recommended for non experts.

What am I missing in the second solution?

mcopurlar
  • 51
  • 3

4 Answers4

0

In your second solution, you should take into consideration the extension behaviour and limitation. Since it is mentioned in MSDN, your problem may be related with property type. Graph API and ADB2C is expecting extended field to be nullable. I don't know if this is the case for you but i hope this helps.

Also there is already asked and answer question in StackOverflow

omer faruk
  • 350
  • 4
  • 13
0

The reason that extension attributes don't show up in your token from user flows is that user flows use a different extension app.

The custom attributes are created on an app (called extension app). In user flows, AAD B2C creates that app automatically (it's named as B2C extension app, do not delete).

When you create 'a new app', that app is not registered in the user flows.

The solution for you will be to use the B2C extension app to create the attributes. Or create the attributes in the portal. Then use the graph api to patch the user with these new attributes.

Please see the documentation of using custom attributes in AAD Graph in AAD B2C tenant. Please see this question for more reference on custom /extension attributes.

Abhishek Agrawal
  • 2,183
  • 1
  • 17
  • 24
0

Let me clarify few things here as it can be confusing.

When using user flows, the easiest way to define custom attribute is using Azure portal. You have to open user flows blade in the Azure AD B2C, and select User attributes:

enter image description here

Once you add the custom attribute, it will be visible on the list. From this point you can decide whether it should be returned in the token to the application or not. To include custom attribute value in the token, you have to open Application claims tab and select your custom attribute added before:

enter image description here

Now when it comes to attribute value. You mentioned that you would like to fulfill this value as admin using Graph API. Here is the fragment of my web app to manage users with .NET Microsoft Graph Client:

    public async Task UpdateUserAsync(UserAccount userAccount, CancellationToken cancellationToken)
    {
        try
        {
            string myCustomAttributeForUserAttributeName = _adB2cCustomAttributeHelper.GetCompleteAttributeName("myCustomAttributeForUser");

            IDictionary<string, object> extensionsInstance = new Dictionary<string, object>();
            if (userAccount.myCustomAttributeForUser != null)
            {
                extensionsInstance.Add(myCustomAttributeForUserAttributeName, userAccount.myCustomAttributeForUser);
            }

            var user = new User
            {
                AdditionalData = extensionsInstance
            };

        await _graphServiceClient.Users[existingUser.Id]
                      .Request()
                      .UpdateAsync(user, cancellationToken);
        }

        catch (ServiceException ex)
        {
            if (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
            {
                var retryAfter = ex.ResponseHeaders.RetryAfter.Delta.Value;
                ...
            }

            else
            {
                _logger.LogError...
            }
        }
    }

Important

In the source code above, as you can see I am using _adB2cCustomAttributeHelper insatnce. This is because when you use Microsoft Graph API, you have to provide full name of the custom attribute which also consists of extensions application's ID registered in the Azure AD B2C:

enter image description here

enter image description here

You can read more about it here. Custom attribute is stored in this format (wthout '-'):

extension_<<extension_app_client_id>_AttributeName

This is AdB2cCustomAttributeHelper class definition:

public class AdB2cCustomAttributeHelper { internal readonly string _b2cExtensionAppClientId;

    public AdB2cCustomAttributeHelper(string b2cExtensionAppClientId)
    {
        _b2cExtensionAppClientId = b2cExtensionAppClientId.Replace("-", "");
    }

    internal string GetCompleteAttributeName(string attributeName)
    {
        if (string.IsNullOrWhiteSpace(attributeName))
        {
            throw new System.ArgumentException("Parameter cannot be null", nameof(attributeName));
        }

        return $"extension_{_b2cExtensionAppClientId}_{attributeName}";
    }
}

I register above instance as singleton and I pass extensions application ID to it as a parameter:

  services.AddSingleton(implementationFactory =>
     {
        var options = implementationFactory.GetRequiredService<IOptions<MsGraphServiceConfiguration>>();

        return new AdB2cCustomAttributeHelper(options.Value.ADB2CExtensionAppId);
        });

Under this link you can also see another example with adding extension attribute to the user's account using Microsoft Graph API.

When you sign in, you will see the extension attribute in the token:

enter image description here

Daniel Krzyczkowski
  • 2,732
  • 2
  • 20
  • 30
-1

I disagree with @Abhishek Agrawal, I created custom attributes using graph with B2C extension app, do not delete and added some value for it to some user, after that I run user flow, log in and custom attribute does not appear in token

freak_geek
  • 109
  • 8