I need to add the custom claim "samAccountName" to be shown in a token (using jwt)
First, I created the powershellscript
New-AzureADPolicy -Definition #('{
"ClaimsMappingPolicy": {
"Version": 1,
"IncludeBasicClaimSet": "true",
"ClaimsSchema":[{
"Source": "user",
"ID": "onpremisessamaccountname",
"SamlClaimType": "samaccountname",
"JwtClaimType": "samAccountName"
},
]
}
}') -DisplayName "att_ext_samaccountname_even2_prod" -Type "ClaimsMappingPolicy"
I assined the new policy to my objectid and its seems to be ok
In azure manifest I put "acceptMappedClaims": true and it looks like this
but in "Token confguration -> Optional claims" it looks like this (warning sign)
And I cannot find the claim to be added when select "add optional claim"
any thoughts of what I'm doing wrong of what is missing?
thanks in advance
I tried to reproduce the same in my environment and got the below results:
I modified acceptedMappedClaims to true and added the extension in app manifest like below:
And got the same error as below:
Alternatively, I used below PowerShell commands to add samaccountname extension in token like below:
$MyApp = (New-AzureADApplication -DisplayName "AppName").ObjectId
New-AzureADServicePrincipal -AppId (Get-AzureADApplication -SearchString "AppName").AppId
New-AzureADApplicationExtensionProperty -ObjectId $MyApp -Name "samaccountname" -DataType "String" -TargetObjects "User"
Set-AzureADUserExtension -ObjectId ServicePrincipalObjectId -ExtensionName "extension_XXXX_samaccountname" -ExtensionValue "Value"
After executing the above commands, I got the response like below:
I was able to add the samaccountname as an optional claim in the Azure Portal like below:
After decoding the token (generated using auth code) flow got samaccountname successfully like below:
For more in detail, please refer below links:
Azure AD cmdlets to work with extension attributes | Microsoft Docs
Inlcude onpemise samaccount in azure ad claims by soumi-MSFT
Related
I am a little confused with the MS Graph article[Vague] related to Claim Mapping Policy. I am trying to create claims using PowerShell. used below format to create new claims map getting error
New-MgPolicyClaimMappingPolicy : Property definition has an invalid value.
Help is needed Here!!!
$policymap=[ordered]#{
definition=#(
#"
{
"claimsMappingPolicy" :
{
"claimsSchema":[
{
"source":"user"
"id":"assignedrikes"
"samlclaimtype":"https://aws.amazon.com/SAML/Attributes/Role"
},
{
"source":"user"
"id":"assignedrikes"
"samlclaimtype":"https://aws.amazon.com/SAML/Attributes/RoleSessionName"
}
]
}
}
"#
)
displayname="Test"
isorganizationdefault=$false
}
New-MgPolicyClaimMappingPolicy -BodyParameter $policymap
New claims map getting error New-MgPolicyClaimMappingPolicy
This error may occur if you are using incorrect format samlclaimtype instead of using MgPolicyClaimMappingPolicy, make sure to install Azure AD Preview while running below script.
Please check below few workarounds:
I installed Azure AD Preview module and created claims using below script.
Connect-AzureAD
New-AzureADPolicy -Definition #('
{
"ClaimsMappingPolicy":
{
"Version":1,"IncludeBasicClaimSet":"true",
"ClaimsSchema": [{"Source":"user","ID":"extensionattribute1","SamlClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/vikram","JwtClaimType":"vikram"}]
}
}') -DisplayName "vikram" -Type "ClaimsMappingPolicy"
Result:
Try to add service principal and check if it is succeeded or not.
For service principal ID, Go to Azure Portal -> Enterprise Applications -> Your Web API -> object ID like below:
Add-AzureADServicePrincipalPolicy -Id <ObjectId of the Web API ServicePrincipal> -RefObjectId <ObjectId of the Policy>
Get-AzureADServicePrincipalPolicy -Id <ObjectId of the Web API ServicePrincipal>
To assign value to that claim, login to Microsoft Graph Explorer with your tenant admin account and run below script. ***This completes the development of your claims mapping successfully. ***
PATCH https://graph.microsoft.com/beta/me
{
"onPremisesExtensionAttributes":
{
"extensionAttribute1": "vedha"
}
}
Now Go to Azure Portal -> Azure Active Directory -> App registrations -> Your App -> Manifest to make your claims to accept as true like below:
Then, Go to Expose an API under manage edit your Application ID URI pattern like https://<yourTenantDomain> instead of default api://<GUID>, and save.
Generate access token and you can see that custom claim you created in the decoded token. To decode the token, you can use jwt.ms website
I'm working on a B2B service that required an Azure AD connection to setup user accounts for all members of the Azure AD domain. I need first name, last name and email for this.
At first I just used the Users.Read.All permission to read all user objects, but some of our clients use AD to store different information aswel.
I'm looking for a solution where I can only access user and groups assigned to the enterprise application by the client.
I've found the servicePrincipal api, but this service doesn't return the user's email.
When calling this api through: https://graph.microsoft.com/v1.0/servicePrincipals/{applicationId}/appRoleAssignedTo
The response looks something like this:
{
"id": "41W1zT6z1U-kJxf62svfp1HFE8pMZhxDun-ThPczmJE",
"deletedDateTime": null,
"appRoleId": "00000000-0000-0000-0000-000000000000",
"createdDateTime": "2021-02-02T04:22:45.9480566Z",
"principalDisplayName": "Alex Wilber",
"principalId": "cdb555e3-b33e-4fd5-a427-17fadacbdfa7",
"principalType": "User",
"resourceDisplayName": "dxprovisioning-graphapi-client",
"resourceId": "8e881353-1735-45af-af21-ee1344582a4d"
}
I've read here that I can use the principalId to request the user object with like so:
https://graph.microsoft.com/v1.0/users/{prinicipalId} . But this results in an error explaining I don't have permission.
After countless hours of googling I cannot find a solution to this problem. Is this just not possible?
To get all the user account (User display name, principle display name and email address) for an Azure enterprise app through PowerShell
$app_name = "[app display name]"
$sp = Get-AzureADServicePrincipal -Filter "displayName eq '$app_name'"
$assignments = Get-AzureADServiceAppRoleAssignment -ObjectId $sp.ObjectId -All $true
$assignments # this will show all the users associated to the principal
Reference So Thread: Azure: Get users assigned to enterprise application in Node JS/Power shell script?
I'm using New-AzureADApplication -DisplayName MyApp -PasswordCredentials $PasswordCreds (Password creds are defined elsewhere), which successfully creates the app registration (not enterprise app) alongside passkey without issue.
Where I'm failing is that I also have 5 graph application based permissions I want to add to this app including User.Read.All
I've tried to follow several answers on StackOverflow and read countless blogs, but, I'm simply failing at this. Some guides/answers seem to be out of date or when I run some examples, I'm getting about 6-8 different GUIDs for User.Read.All, and other answers just include the permission that the question answer was asking without explaining why/how.
I don't want an answer for User.Read.All, I really want to learn and understand how I can ultimately provide '-RequiredResourceAccess` the correct parameters when all I know is the permission name as above.
Here's the best example of doing this: https://github.com/mjisaak/azure-active-directory/blob/master/README.md#well-known-appids
because the graph app has a unique object id in your tenant, you need to get that ID first.
Get-AzureADServicePrincipal | Where-Object AppId -Match '\w{8}-\w{4}-\w{4}-c000'
this just matches a few to show you a bunch of system apps. You'll note that Microsoft Graph has a well known app id of 00000003-blabla. but you'll also see the Object ID, you take that object id. and you then query it for either all the oauth2permissions (Delegated) or the AppRoles (Application Permissions)
Delegated Permissions :
Get-AzureAdServicePrincipal -ObjectId ObjectIDyouFoundAbove |
Select-Object -expand Oauth2Permissions |
Select-Object Id, Value, AdminConsentDisplayName |
Sort-Object Id
Application Permissions :
Get-AzureAdServicePrincipal -ObjectId AgainObjectIDYouFoundAbove |
Select-Object -expand AppRoles |
Select-Object Id, Value, DisplayName |
Sort-Object Id
This will List the guids for the permissions. Value is basically the read.user text. where as displayname is the description. ID is your Guid.
From looking through the web, you should be able to do the whole thing via Powershell, but it felt fairy convoluted and it did not work for me immediately. It might not be worth it unless you need to resolve these guids dynamically.
This did NOT work for me, but if you want to investigate, look at $sp = Get-AzureADServicePrincipal -SearchString "Microsoft Graph" and $sp.Oauth2Permissions (https://gcits.com/knowledge-base/automate-creation-azure-ad-applications-access-microsoft-graph-customer-tenants/).
This is what does work for me:
I usually just set up one app manually in the portal, and then have a look at the application manifest.
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "5b567255-7703-4780-807c-7be8301ae99b",
"type": "Role"
}
]
},
{
"resourceAppId": "00000002-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
"type": "Scope"
},
{
"id": "6234d376-f627-4f0f-90e0-dff25c5211a3",
"type": "Scope"
}
]
}
],
For actually setting the permissions, you probably already have the code. I will just include it for completeness' sake.
How to configure a new Azure AD application through Powershell?
$req = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$acc1 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "e1fe6dd8-ba31-4d61-89e7-88639da4683d","Scope"
$acc2 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "798ee544-9d2d-430c-a058-570e29e34338","Role"
$req.ResourceAccess = $acc1,$acc2
$req.ResourceAppId = "00000003-0000-0000-c000-000000000000"
Set-AzureADApplication -ObjectId 1048db5f-f5ff-419b-8103-1ce26f15db31 -RequiredResourceAccess $req
I am running the following command
$sp = az ad sp show --id $env:ARM_CLIENT_ID --query '{objectId: objectId, displayName: displayName}'
az sql server ad-admin create --resource-group data-eastus2 `
--server-name data-eastus2-sqlsvr `
--display-name $sp.name `
--object-id $sp.id
which works perflecty fine without providing any Graph API permissions to service principal.
Trying to mimick this functionality using Az Powershell module, by running the following
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName 'data-eastus2' -ServerName 'data-eastus2-sqlsvr' -DisplayName $sp.name -ObjectId $sp.id
yields an exception
Set-AzSqlServerActiveDirectoryAdministrator : Cannot find the Azure Active Directory object
'service_principal_name'. Please make sure that the user or group you are authorizing is registered in the
current subscription's Azure Active directory. To get a list of Azure Active Directory groups use Get-AzADGroup, or
to get a list of Azure Active Directory users use Get-AzADUser.
At line:1 char:1
+ Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName 'data ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzSqlServer...ryAdministrator], ArgumentException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Sql.ServerActiveDirectoryAdministrator.Cmdlet.SetAzureSqlServerActiveDirectoryAdministrator
Providing Azure Active Directory Graph - Directory.Read.All and Microsoft Graph - Directory.Read.All
API Permissions didn't help.
The Azure CLI az sql server ad-admin create will not call Azure AD Graph to validate the parameters you passed, it just calls the REST API Server Azure AD Administrators - Create Or Update to set the admin. Even if you pass wrong --display-name and --object-id(also need to be Guid format), the command will also work fine. You could check the details with --debug parameter.
The Azure powershell Set-AzSqlServerActiveDirectoryAdministrator will call Azure AD Graph getObjectsByObjectIds: Get objects from a list of object IDs to validate if the object is correct or not. And if the result's type is not an Azure AD security group, it will further call Get a user. So if the result's type is a service principal, it will also call Get a user, then it will cause the issue. You could use fiddler tool to catch the reuqest like below.
So if you want to use the Set-AzSqlServerActiveDirectoryAdministrator, you could create a security group(not office group) in Azure AD, add the service principal to the group, then add the group to the sql server admin, as mentioned in #alphaz18's reply.
$sp = Get-AzADServicePrincipal -ObjectId "<object-id>"
$group = Get-AzADGroup -DisplayName "joysec"
Add-AzADGroupMember -TargetGroupObjectId $group.Id -MemberObjectId $sp.Id
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName "<groupname>" -ServerName "<servername>" -DisplayName $group.DisplayName -ObjectId $group.Id
Note: To run the script above, you need to give a
Directory.ReadWrite.All Application permission of Azure Active Directory Graph(not Microsoft Graph) for your AD App, and there is some delay, wait for a while and test.
Most likely though i can't confirm this as i'm not 100% sure, but I think the set-azsqlserveractivedirectoryadministrator, only filters by azaduser or azadgroup. it probably won't search for service principals.
as a workaround though, if you want to accomplish this. you could create an azure ad group something called dbas or something. and add the service principal to that group. then add the group to the sql server using that set-azsqlcommand.
so something like this:
$sp = Get-AzADServicePrincipal -DisplayName "theserviceprincipalname"
Add-AzADGroupMember -MemberObjectId $($sp.id) -TargetGroupDisplayName "AAD Group Name"
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName 'data-eastus2' -ServerName 'data-eastus2-sqlsvr' -DisplayName "AAD Group Name"
Hope that works for you, not 100% directly answer what you were asking, but I believe it is a viable workaround per your requirements hopefully.
I have an Azure AD app and I am trying to add custom claims to a JWT. I'm using the claims mapping feature in Azure for my specific app, and updated the app manifest in the Azure Portal to include the optional claims. However, when I log in and view the decoded access token, the claim is not present in the token. I haven't found much documentation relating to using extension attributes as claims, but from what I've found it should follow the same patterns, but it is not working as expected.
How do I add a custom claim, sourced from a custom property in the user object in AD, to a JWT when the user logs in?
Thanks in advance!
Steps to re-create
Use the Azure AD Graph API to register a directory extension
Request:
POST https://graph.windows.net/mytenant.onmicrosoft.com/applications/<application-object-id>/extensionProperties?api-version=1.5
Body:
{
"name": "customUserRoles",
"dataType": "String",
"targetObjects": ["User"]
}
Write a value to the extension for a specific AD user
Request:
PATCH https://graph.windows.net/mytenant.onmicrosoft.com/users/user123#mytenant.onmicrosoft.com?api-version=1.5
Body:
{
"extension_<appId>_customUserRoles": "My Custom Role 1, Another Role 2"
}
In PowerShell, I installed the Azure AD module: Install-Module -Name AzureADPreview
Create an Azure AD policy
New-AzureADPolicy -Definition #('{"ClaimsMappingPolicy":{"Version": 1, "IncludeBasicClaimSet": "true", "
ClaimsSchema": [ { "Source": "user", "ID": "extension_<appId>_customUserRoles", "JwtClaimType": "customUserRoles" } ] } }') -DisplayName "customUserRoles" -Type "ClaimsMappingPolicy"
Add the policy to the service principal
Add-AzureADServicePrincipalPolicy -Id <service-principla-id> -RefObjectId <azure-ad-policy-id>
In the Azure Portal, navigate to Azure AD -> App Registrations -> My App -> Manifest
Update the following properties
{
...
"acceptMappedClaims: true,
"optionalClaims": {
"idToken": [
{
"name": "extension_<appId>_customUserRoles",
"source": "user",
"essential": false,
}
],
"accessToken": [
{
"name": "extension_<appId>_customUserRoles",
"source": "user",
"essential": false,
}
],
"samlToken": []
}
}
Save the file
Navigate to https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/authorize?client_id=<appId>&response_type=token&resource=https://mytenant.sharepoint.com and login with Azure AD user account user123#mytenant.onmicrosoft.com
In the URL, copy the value of the access_token parameter
Navigate to https://jwt.ms and paste the access token in the text area
In the decoded token section, the custom claim customUserRoles is not present
My expectation is I should see a new claim called customUserRoles or extn.customUserRoles in the decoded token.
What steps am I missing? I haven't gotten any errors throughout this process, but it doesn't appear to be working as the documentation suggests.
Reference Material
I have read through Microsoft's documentation on these topics:
Optional Claims: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims
Claims Mapping: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-claims-mapping
I have also read through various forum posts and blog articles relating to this:
https://devonblog.com/cloud/azure-ad-adding-employeeid-claims-in-azure-ad-jwt-token/
http://www.redbaronofazure.com/?p=7566
https://social.msdn.microsoft.com/Forums/en-US/3e5114b6-24d6-4c60-b72b-b4c90baeecac/access-token-missing-optional-claims-that-are-schema-extensions-implicit-grant-flow
https://social.msdn.microsoft.com/Forums/en-US/dbeeed63-8d3f-4c27-b416-431f9fe6c729/providing-directory-extension-optional-claims-and-returning-value-within-token?forum=WindowsAzureAD
Based on this official doc :
Access tokens are always generated using the manifest of the resource,
not the client. So in the request
...scope=https://graph.microsoft.com/user.read... the resource is
Graph. Thus, the access token is created using the Graph manifest, not
the client's manifest. Changing the manifest for your application will
never cause tokens for Graph to look different. In order to validate
that your accessToken changes are in effect, request a token for your
application, not another app.
And based on your requirement , it is impossible if you want to make some change on an access token which resource is sharepoint online which is a multi-tenant app created and managed by MSFT.
For this doc , I also did some research for you . And the same , you should have control of the service side app so that you can make that happen.
This is my policy role assignment command :
$nsp = New-AzureADPolicy -Definition #('{"ClaimsMappingPolicy":{"Version":1,"IncludeBasicClaimSet":"true", "ClaimsSchema": [{"Source":"user","ID":"mailnickname","JwtClaimType":"testclaim"}]}}') -DisplayName "StanCustomCliamDemo_surname" -Type "ClaimsMappingPolicy"
Add-AzureADServicePrincipalPolicy -RefObjectId $nsp.Id -Id '<obj id of service side app>'
Token result :
What's more , pls note that extension_<appId>_customUserRoles is not a valid user source ID . For all valid user source ID , pls refer to here .
Hope it helps .