Add Custom Attribute Not Used in Sign-Up nor Edit Policy - azure-ad-b2c

How do I add a Custom Attribute, when using custom policies, that is not used in a sign-up nor edit policy?
Background
I need to define custom attributes that will be set via the AD Graph API, not the user.
I found this note:
There is a known limitation of custom attributes. It is only created the first time it is used in any policy, and not when you add it to the list of User attributes.
So I'm thinking what I'm trying to do is not achievable directly. I guess a workaround would be:
Create an edit (or sign-up) policy
Perform a user edit prompting for the new custom attribute(s)
Delete the edit policy
Update
I started implementing my workaround via a sign-up policy and after uploading my custom policies, the new attribute, NewCustomAttribute, is there without creating a user.
What magic added this new attribute?
.\b2c Get-Extension-Attribute [my-ad-app-guid]
{
"odata.metadata": "https://graph.windows.net/ebenefitsdev.onmicrosoft.com/$metadata#directoryObjects/Microsoft.DirectoryServices.ExtensionProperty",
"value": [
{
"odata.type": "Microsoft.DirectoryServices.ExtensionProperty",
"objectType": "ExtensionProperty",
"objectId": "[some-guid]",
"deletionTimestamp": null,
"appDisplayName": "",
"name": "extension_[my-ad-app-guid]_NewCustomAttribute",
"dataType": "String",
"isSyncedFromOnPremises": false,
"targetObjects": [
"User"
]
}
}

The extensions app, which is added to the Azure AD B2C directory when it is created, registers the extension property when a custom attribute is created via the Azure AD B2C blade.
The extensions app ID should match the middle part of the extension property name.
After the extension property is registered by the extensions app and before it is referenced by any built-in or custom policy, it can be read from and written to via the Azure AD Graph API.

Related

How to include directory extension into access token in azure AD?

I have created directory extension and assigned data for it but when I add it in Token configuration but it still not include in access token so how to include directory extension in Azure AD ?
I tried to reproduce the same in my environment to add custom extension attribute in azure AD.
Create a new app registration like below
Azure AD Portal>Azure Active Directory>App registrations
Create custom extension attribute using Graph Explorer and login graph explorer with global admin account.
You can get the application object ID like below
Azure Portal>Azure Active Directory>App Registration>Select your App
Execute the code in graph explorer like below
GET https://graph.microsoft.com/v1.0/applications/<AppregistrationObjectID>
Modify the code to create the custom extension
POST https://graph.microsoft.com/v1.0/applications/<AppregistrationObjectID>/extensionProperties
{
"name": "CustomAttribute",
"dataType": "string",
"targetObjects": [
"User",
"Group"
]
}
Add the custom attribute to user object like below
PATCH https://graph.microsoft.com/v1.0/users/<UserObjectID>
{
"extension_47c8caba8d924ac9a0f159b0dcc8d4c7_CustomAttribute": "Demo"
}
You can get the user object ID like below
Azure Portal>Azure Active Directory>Users>Select your Global Admin user
Added custom attribute in access token
Finally added custom extension attribute like below

Add app extension attribute in user flow JWT Azure AD B2C

I am working in Azure AD B2C to add custom extensions per application. Theses extensions must be returned in the jwt when the login is requested by the application.
So I create the extension on the app using the graph api
POST https://graph.microsoft.com/v1.0/applications/{{appid}}/extensionProperties
{
"name": "name",
"dataType": "String",
"targetObjects": [
"User"
]
}
Then I associate a value for a specific user
PATCH https://graph.microsoft.com/v1.0/users/{{userid}}
{
"extension_{{appid(without dashes}}_name": "1234"
}
Now I go on the app manifest to add the optional claim.
"optionalClaims": {
"idToken": [
{
"name": "extension_{{appid(without dashes}}_name",
"source": "user",
"essential": true,
"additionalProperties": []
}
],
"accessToken": [
{
"name": "extension_{{appid(without dashes}}_name",
"source": "user",
"essential": true,
"additionalProperties": []
}
],
"saml2Token": []
},
Save but the claim never appear on the jwt token.
I also tried using the answer of this post but didn't work either.
The problem is you’ve used Optional claims setup, which works for AAD but not AAD B2C.
Follow this: https://learn.microsoft.com/en-us/azure/active-directory-b2c/user-flow-custom-attributes?pivots=b2c-user-flow
If you want to select your custom attribute through the Azure Portal - AAD B2C - User Attributes blade, and the attribute was created via Graph API, you have to recreate it in the Portal for it to reconcile.
You would also need to target the b2c-extensions-app AppId when defining the attribute with Graph API.
I tried to reproduce the same in my environment and got the claims successfully
As Jas Suri - MSFT commented, this will only work if you are adding optional claims to Azure AD application.
I created the extension attribute via Graph API like below:
I associated the above extension attribute to a specific user like below:
Please check whether that extension attribute is visible in optional claims UI or not and add like below:
When you check the manifest, it will be added automatically like below:
I generated the JWT token using auth-code flow via Postman like below:
After decoding the JWT token (ID-Token), I got the claims successfully like below:

Can we add a extra claims in Azure AD Groups when we create them via Graph API?

Is it possible to add extra properties to the Azure AD groups when we create them in azure ad b2c via graph api. Just like we do it for users (we can add claims to the user)
I am not able to find any resource for this. let me know if that is possible.
Thanks!
Yes. You could do that.
Find the "b2c-extensions-app" under Azure AD B2C - App registrations (Preview) in Azure AD B2C. It's the app which stores the extension property in Azure AD B2C. Record its object ID.
Use the following call to register an extension in the app above. Reference here.
POST https://graph.windows.net/{your B2C tenant}/applications/<applicationObjectId>/extensionProperties
{
"name": "customAttribute",
"dataType": "String",
"targetObjects": [
"Group"
]
}
Then you will get an extension for Group in the response: extension_{client id of b2c-extensions-app}_customAttribute.
Now create a group with the extension property.
POST https://graph.windows.net/{your B2C tenant}/groups
{
"displayName": "Example Group",
"mailNickname": "ExampleGroup",
"mailEnabled": false,
"securityEnabled": true,
"extension_{client id of b2c-extensions-app}_customAttribute": "customAttribute for group"
}

B2C Custom Attributes not showing when created using Graph API directory schema API

Using the extension API documented here:
https://msdn.microsoft.com/en-us/library/azure/ad/graph/howto/azure-ad-graph-api-directory-schema-extensions
in conjuction with the B2C Graph Client sample:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet
I created a custom attribute via the AD Graph API for directory schema extensions using this API:
POST
https://graph.windows.net/contoso.onmicrosoft.com/applications/<applicationObjectId>/extensionProperties?api-version=1.6
{
name: "OrgRoleId",
dataType: "String",
targetObjects: [
"User"
]
}
(Note I changed the API version to 1.6).
The API created custom attributes appear using the B2CGraphClient sample and has the same data as those registered via the Azure portal for B2C.
However, these API created custom attributes don't appear in the Azure portal 'User attributes' blade for the tenant, while those custom attributes created via the Azure portal for the B2C tenant do.
Note that I can successfully read and write these extension values for users (via the Graph API). I just cannot put them into claims because they don't appear on the 'User attributes' blade nor the policy claims blade in the Azure portal, and therefore they are not added as claims to the token.
What I am missing/doing wrong?
Output from B2C.exe Get-extension-attribute <b2c-extensions-app objectId>. *_Test1 appears (portal created), while *_UserRoleId does not (API created):
{
"odata.metadata": "https://graph.windows.net/<tenant_id>/$metadata#directoryObjects/Microsoft.DirectoryServices.ExtensionProperty",
"value": [
{
"odata.type": "Microsoft.DirectoryServices.ExtensionProperty",
"objectType": "ExtensionProperty",
"objectId": "f58bc813-632c-486b-bff1-61695eeab691",
"deletionTimestamp": null,
"appDisplayName": "",
"name": "extension_<object_id>_Test1",
"dataType": "String",
"isSyncedFromOnPremises": false,
"targetObjects": [
"User"
]
},
{
"odata.type": "Microsoft.DirectoryServices.ExtensionProperty",
"objectType": "ExtensionProperty",
"objectId": "5e69b2d9-1ab0-463f-a231-5c188e92b4a1",
"deletionTimestamp": null,
"appDisplayName": "",
"name": "extension_<object_id>_UserRoleId",
"dataType": "String",
"isSyncedFromOnPremises": false,
"targetObjects": [
"User"
]
}
...
When you add an extension attribute through the portal, it is created in the directory and owned by the b2c-extensions-app application and it is also added to a tenant-wide policy. That is what allows you to use them in application policies as you create them.
When you create an extension attribute using Graph API, it is not added to the policy and usually created on an application other than b2c-extensions-app. You can use these properties directly in custom policies, but they will not appear in the portal and cannot be used in the policies created through the portal.
It is a best practice to just create the extension properties through the portal so they are available for all policies. This allows customers to mix and match custom policies with built-in b2c user flows.

Azure Active Directory B2C User Management

I was following this article and created a sample which works perfectly well. I can sign up, sign out and edit my profile with it but can't find out how to add a user in AAD B2C and assign it some role, so that I can differentiate them on the basis of roles, i.e. when I get to the Claims Page and get a user object, I can check the user by writing something like this:
User.IsInRole("client")
I added a custom attribute in "User Attributes" with the name of "Role" but that didn't solve my problem. I can only see that when I write:
foreach (Claim claim in ClaimsPrincipal.Current.Claims)
...claim.Type .... claim.Value
But I want it as I explained above
Thanks in advance.
Ok by now, I have found out the roles by clicking on the directory name -- users, but the available roles are User, Global Admin, Billing Admin, Service Admin, User Admin and Password Admin, but User.IsInRole("User") didn't work for me. So,
1. can I add any customized roles
2. how can I check if my user belongs to a particular role programmatically?
Thanks.
You can add custom roles by modifying application manifest file (application configured in Azure Active Directory). You just have to download manifest json file, add your custom roles and upload file again. You can do it here:
Then open the file and add custom role like that:
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "some text",
"displayName": "Super role",
"id": "c530a40b-a47c-42b7-ba9a-f34d8ca7e443",
"isEnabled": true,
"origin": "Application",
"value": "Super role"
}
],
User attributes in Azure B2C are prefixed with "Extension_", so a user attribute "Role" will be called "extension_role" in your claims.
This is the reason the UserIsInRole doesn't work
Something that works for Azure AD, maybe for B2C also(not tried by me):
Try to use Groups (create a new group), add the user to the group.
Group membership isn't added to your claims by default:
http://justazure.com/azure-active-directory-part-4-group-claims/

Resources