I'm using Blazor webassembly with Azure ADB2C. A typical task is to retrieve only those records for the logged in user. Which field from AzureB2C is the best practice to use as the authorized user's primary key?
I assumed that using the object ID which is a guid and created by Azure ADB2C would be the correct unique field. However I also see examples on the internet using either the user's email and/or user's name.
I plan on using this field as as a unique field in database tables for the user.
Per documentation, Microsoft Graph uses userprincipalname or objectID for queries
GET /users/{id | userPrincipalName}
You can apply filters to Microsoft Graph calls but generally the objectID is immutable and is the primary identifier that I've seen with enterprise applications/services.
Related
We use Azure Active Directory(OpenId and OAuth2) for authorization and authentication needs.
We also would like to keep users' profiles in one of our microservices, let's name this service "User Preferences".
The service will store many specific fields required only for one of our products and it is why we don't want to store them in Active Directory(custom fields).
Having all of this, we are searching for the best Azure AD field we can use to connect user's profile to Active Directory account.
There're several candidates:
UPN - in some cases JWT doesn't contain it
ObjectId - always available, but not read-friendly and unique in multi tenant structure
Unique Name - should be used only to display it on UI(recommended by Azure)
Could you please recommend the best field for our case?
Compiling my comments as an answer:
Object id or name identifier (sub claim) are the only immutable fields you can choose from. Using the UPN is dangerous as it can be changed.
Object id is unique across directories, though if you support multiple tenants you should store the tenant id (tid) as well.
UPN can change when an admin changes it.
And also, if a user is invited as a guest to other AAD tenants, they'll have an object id per directory, it won't be the same.
Forgive my amateur question, however, I can't seem to find an answer on google/stackoverflow.
I created an app (Xamarin) and I want to store application data in a database, for example an Azure SQL database. I created and integrated a tenant in azure b2c for handling user accounts in the app.
I would like to somehow relate data in my "own" database to user accounts in b2c (is this strange?). All I can find is that you can create custom user attributes but this seems, in my opinion, pretty limited. So I need something unique from b2c that "cannot" change to relate to from my own database.
Seems to me like common use case, what is the preferred approach and is there some unique attribute that I can relate to? (object id maybe??)
Users in an Azure AD B2C tenant are identified by the objectId property of the user object.
This objectId property is immutable.
It is common for tokens, which are issued by policies to applications, to contain the sub and/or oid claim/s, which are mapped from the objectId property.
This enables applications to cross-reference their "own" data for users.
I have a webapi that is published as a service on Azure. It uses the integrated AD security.
In my Controller, I can get access to the ClaimsPrincipal via the User property. Which of ClaimsPrincipal's properties can be used to uniquely identify the user so that I can use that value to search a SQL table for that users data or store data to a SQL table and include the users unique identification? The identity property has a Name but I was thinking of a more unique identifier.
Or is there a different intended strategy to do this?
AFAIK, you can use either, the upn or the oid (Object Identifier) claim.
The UPN is typically your login name e. g. yourname#yourtenant.onmicrosoft.com whereas the oid is the ObjectId of that user.
Note: If you delete and recreate a user with the same email, the upn will be the same whereas the oid will change.
I'm using Azure AD B2C Graph API to create and manager users. Users have data and progression so I wanted to know, how should I go about storing information about the user in my app (such as how much gold the user has)?
I want to grab their userPrincipalName or their objectId and use that as a primary key in a separate database to keep track of app related information but before doing that I wanted to know if this was the correct way to do it with graph API, unless there's a standard graph API has for storing app data per user?
Ideally I don't want to be able to associate data with specific users for security and privacy reasons.
With Azure AD B2C you can extend your schema with custom attributes and read/write to them using Azure AD Graph API.
Please see how to create a custom attribute and this page for how to use custom attributes with the Graph API.
In my opinion, if you just need to store data, use Azure AD B2C with custom attributes, but if you also need some complex logic when reading/writing the properties, or even crate some relations between properties, then consider a custom data store.
I have 2 users in Azure AD
Microsoft Account user
Microsoft Azure Active Directory user
User 2 always works in Graph API calls but not the user 1.
https://graph.windows.net/tenantid/users/testmail#hotmail.com?api-version=2013-04-05
(Email actually is url encoded as testmail%40hotmail.com).
This gives the following error
"{\"odata.error\":{\"code\":\"Request_ResourceNotFound\",\"message\":{\"lang\":\"en\",\"value\":\"Resource 'testmail#hotmail.com' does not exist or one of its queried reference-property objects are not present.\"}}}"
Does anyone know how to fix this?
Edited:
Things I figured out trying to fix this. I am using UserPrincipal name in the query above(..users/testmail#hotmail.com?..). For built-in domain accounts userPricipal name is testmail#domain.com(this works) but for a Microsoft account userPrincipal name is testmail_hotmail.com#EXT##domain.com. This was given in the all users list (https://graph.windows.net/tenantid/users?api-version=2013-04-05). But even when I changed the query to '..users/testmail_hotmail.com#EXT##domain.com?..' ofcourse after url encoding(testmail_hotmail.com%23EXT%23%40domain.com), still it does not work. Objectid always works though for all accounts(..users/objectId?..) .
Also tried otherMails. May be the api is wrong as otherMails is an array. "https://graph.windows.net/tenantId/Users?$filter=otherMails eq 'testmail%40hotmail.com'&api-version=2013-04-05"
So the question still remains. if only email is available for an MS account(not objectid) when making the call, how to get user details?
You are missing your domain in the URL you posted. It should be
https://graph.windows.net/[your Azure AD domain]/users
To get the email address for a user you need to add the object Id of the user in the request URL. So, for example, to get an Azure AD user it would be like this:
https://graph.windows.net/[your Azure AD domain]/users/[object ID of user]/mail
For users in the directory sourced from a Microsoft Account, the mail property is null. So, you will have to look in the otherMails property like this:
https://graph.windows.net/[your Azure AD domain]/users/[object ID of user]/otherMails
If you want to access the full user account using a user's UPN, you can do that for users sourced from Azure AD. For example, for a tenant domain contoso.com and a user with a UPN johndoe#contoso.com, the query would look like this:
https://graph.windows.net/contoso.com/users/johndoe#contoso.com
This doesn't work for users sourced from Microsoft Accounts. For these accounts, the UPN contains characters (#, . for example) that break the query. You can filter by the UPN though using the naming convention that is used for users sourced from Microsoft Accounts. Suppose you have a user whose email is jayhamlin#yahoo.com in your directory. The UPN would be something like jayhamlin_yahoo.com#EXT##contoso.com. So, you could use a filter and look for the first part of the UPN like this:
https://graph.windows.net/contoso.com/users?api-version=2013-11-08&$filter=startswith(userPrincipalName, 'jayhamlin_yahoo')
You can easily explore the Graph API and object properties for your directory using https://graphexplorer.cloudapp.net.
That filter can work, but you could also filter on otherMails. Your original query didn't work because otherMails is a multi-valued property- so you need to use "any":
https://graph.windows.net/tenantId/users?api-version=1.5&$filter=otherMails/any(x:startswith(x,'testmail#hotmail.com'))
When are you using this lookup? Is it once the user has signed in or for some people picking scenario?
Cheers,