Which Azure AD property (from login response) store as UserId in the database? - azure

Upon successful login with Azure AD (via MSAL 2), I get the following object:
environment:"login.windows.net"
homeAccountId:"ID_1.ID_2"
idTokenClaims:Object
aio:"xxx"
aud:"xxx"
exp:1661778482
iat:1661774582
idp:"https://sts.windows.net/ID_2"
iss:"https://login.microsoftonline.com/TENANT_ID"
name:"xxx"
nbf:1661774582
nonce:"xxx"
oid:"ID_3"
preferred_username:"xxx"
rh:"xxx"
sub:"xxx"
tid:"xxx"
uti:"xxx"
ver:"xxx"
localAccountId:"ID_3"
name:"xxx"
nativeAccountId:undefined
tenantId:"TENANT_ID"
It seems that according to the documentation, if I understand correctly, you need to take idTokenClaims.oid which is equal to localAccountId.
But I thought that if you want real permanent UserId to store in database, then you should look at the properties of the user through the Azure portal, and takes its Object ID field. I am a bit confused that Azure user's Object ID field also existed in the returned object (upon Azure AD login via MSAL). Object ID is in the homeAccountId field, namely ID_1, but for some reason it is followed by a dot and some other incomprehensible ID_2, which is present in idTokenClaims.idp.
Please tell me what is correct to store in the database as UserId in the CreatedBy field for an Azure AD user when authorizing through MSAL 2:
idTokenClaims.oid, aka localAccountId?
or ID_1 from homeAccountId (which equals to the user's Object ID) ?

Object ID i.e. oid is the primary claim that you should use as part of a system of records (plus tenant ID i.e. tid if you are serving multiple tenants).
homeAccountId and localAccountId are MSAL SDK specific terms, but they map to claims in the ID token eventually -homeAccountId is "oid.tid", while localAccountId is simply "oid" as it's only used with ADFS which doesn't have tenancy.
The idTokenClaims in the response payload is the actual decoded ID token from Azure AD, and then MSAL adds further useful metadata to the response.
See also:
Microsoft identity platform ID tokens.
Data access sample

Related

Are the MSAL claims constants available in a package somewhere?

I've moved my authentication to MSAL and I want to examine my claims on the client side to see, for example, the object ID that I have in Azure B2C (and thus, give my client an identity).
On the server, the objectId claim appears to be returned as:
{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: 63fd3d89-26ff-4934-907c-5e6c9da07c45}
The URI "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" is a known claim and can be accessed using Claims.Name and I can use a statement like this to extract the objectId from the claims:
Guid userId = new(this.User.FindFirstValue(ClaimTypes.NameIdentifier));
But on the client, the objectId claim is returned using the 'oid' URI and I can't use the same kind of pre-defined claims that I can on the server.
Obviously I can define these as constants in a shared module, but I can't be the only one trying to parse claims from the client side. Is there an analog of 'ClaimTypes' for MSAL on the client side?
I was searching for the same thing and found the ClaimConstants.ObjectId (see here) to match the oid claim type (http://schemas.microsoft.com/identity/claims/objectidentifier).
Guid userId = new(this.User.FindFirstValue(ClaimConstants.ObjectId));
It's part of the Microsoft.Identity.Web package.

Azure API Management - Customize Token

When calling the token endpoint to get an Azure API access token, I want to pass in extra information to be included in the token. Is that possible?
For example, I want to pass in a locationID to the body when calling:
https://login.microsoftonline.com/\<<tenant id>>/oauth2/v2.0/token
Then I want this locationID to be encoded in the token that I get back.
You can use optional claims in Azure AD applications to specify which claims you want in tokens sent to the application.
we can only get the claims with access tokens but we cannot send any extra information like locationID while calling the access token.
The following are few of the v2.0-only optional claims which can be requested along with access tokens:
ipaddr
onprem_sid
pwd_exp
For complete list of v2.0-specific optional claims set you can refer this link.

Azure AD: How to make tokens have the "hasgroups" claim?

Our application allows assigning permission to groups, which means for every user, we have to reliably determine group membership. The user presents a token regularly obtained with ADAL (some use .NET, others use NodeJS, others use CLI).
Some users seem to be sending a token with the following claim:
"hasgroups": true,
That claim is documented in the Azure AD token reference page.
We would like to add a test case for that, but after following steps here and here, we always end up with a token with the following claims:
"_claim_names": {
"groups": "src1"
},
"_claim_sources": {
"src1": {
"endpoint": "https://graph.windows.net/{redacted}/users/{redacted}/getMemberObjects"
}
},
What is wrong with our setup? Why can't we get the hasgroups claim?
Here are some additional information:
Application type is Native (not WebApi).
Manifest says "oauth2AllowImplicitFlow": true.
The application is given access to Azure Key Vault.
We use the following code to get the token (in C#):
var userCredential = new UserCredential( _userName, _password );
result = context.AcquireToken( _resource, _clientId, userCredential );
Where:
_userName and _password are from a user with lots of groups.
_clientId is the application id of the native application - the one with "oauth2AllowImplicitFlow": true.
_resource is https://vault.azure.net.
The token is emitted correctly. The only issue is that it shows _claim_names and _claims_sources instead of hasgroups.
Where: • _userName and _password are from a user with lots of groups.
As the user is part of lots of groups (assuming 6 or more here).. Azure AD token will come back with a groups overage indicator instead of actual group ids in “groups” claim. I guess you know that and hence doing it intentionally.
var userCredential = new UserCredential( _userName, _password );
result = context.AcquireToken( _resource, _clientId, userCredential );
Since you're acquiring the token in a .NET based application using C# code, the token response is not really limited in length (like in cases for a web SPA, where it is being returned as a URI fragment and URL length has limits)
Looking at the documentation both "hasgroups" and "groups:src1" claims have the same intention of telling that there are too many groups to return as part of the token. Although there is a subtle difference:
in cases where URL limit applies, "hasgroups" will be sent as true (like implicit grant flow for SPA)
in cases where length is not limited (like in your case), Azure AD will still not return all the groups to make sure the token doesn't get too big, but it will send a little more information on how to get to all groups by sending the information on how you can query for all your groups. In this case it's sending the "groups:src1" and "_claim_sources" with source information instead of just the "hasgroups"
Claims in id_tokens
For anyone looking more on this. Please refer Doc saml-tokens
Note
Source : Azure Sample Link

How to get user group in nodejs using passport-azure-ad

i am using nodejs passport-azure-ad for AD authentication with OIDCStrategy. Every thing is working fine but i am not able to fetch correct groups. Although i update responseType: 'code id_token', and getting groups id as well but groups are different from the azure portal showing.
I am not sure about your scenario . If you wan to get group claims by setting groupMembershipClaims property in manifest . Your choices for setting the groupMembershipClaims property are null (the default), All or SecurityGroup. If you choose SecurityGroup you will get group claims in the JWT token for just security groups the user is a member of. If you choose All you will get group claims in the JWT token for security groups and distribution lists the user is a member of. If you want to just get security groups the user is a member of , you should set value to SecurityGroup , then you will find group object IDs now provided in the claims . You could check that value with object id value in group property from azure portal .
If your question is getting group name with group object id in token claims , please provide more details about that, for example , which api you are using .
If i misunderstand your scenario , please feel free to let me know .

Is there an API to get the tenant ID for a give name?

If i have a tenant name such as "contoso.onmicrosoft.com" can i get the tenantID using an API call?
I have already checked the API for Microsoft.Azure.Management.ResourceGroup
You can simply call https://login.microsoftonline.com/tenantDomain/.well-known/openid-configuration and get the tenant id from there. Just parse the JSON it returns and get the tenant id from it - for example from issuer.
Full info can be found here.
The call doesn't have to be authenticated so it is very simple to call.
You can get the name of the tenant you are logged into by calling
https://management.azure.com/tenants?$skiptoken={skiptoken}&api-version={api-version}
see here for details
This will give you a list of all tenants that you authorized for.
This is actually listed under 'Tenants' rather than resource groups.
Te easiest way to get tenantID is to find it in Azure portal. Please click -> APPLICATION -> VIEW ENDPOINT. like the following screenshot:
If you want to use C# to get the tenant ID from the name. Please try to get the JWT token first (use the user under the "contoso.onmicrosoft.com" to sign in). The JWT token will contain tid. "tid" means tenant id. Refer to this article for more details.
Then we can use the following code to get the tenant id:
var token = new JwtSecurityToken(jwtToken);
var oid = token.Claims.FirstOrDefault(m=>m.Type == "tid").Value;

Resources