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?
Related
Is there a quick and easy way to find Microsoft Graph API - Delegated / Application Permissions GUID (or even deprecated Azure AD API Permissions).
Tried to follow the official document but find it not very intuitive.
https://learn.microsoft.com/en-us/graph/permissions-reference
Since permissions names are similar, eg: group.readwrite.all between delegated vs application, is there any tool or technique to easily find these IDs.
az ad sp list --query "[?appDisplayName=='Microsoft Graph'].{permissions:oauth2Permissions}[0].permissions[?value=='Group.ReadWrite.All'].{id: id, value: value, adminConsentDisplayName: adminConsentDisplayName, adminConsentDescription: adminConsentDescription}[0]" --all
{
"adminConsentDescription": "Allows the app to create groups and read all group properties and memberships on behalf of the signed-in user. Additionally allows group owners to manage their groups and allows group members to update group content.",
"adminConsentDisplayName": "Read and write all groups",
"id": "4e46008b-f24c-477d-8fff-7bb4ec7aafe0",
"value": "Group.ReadWrite.All"
}
this seems to be incorrect as the ID that is correct is:
Group_ReadWrite_All = {
id = "62a82d76-70ea-41e2-9197-370581804d09"
type = "Role"
}
Am I missing something obvious here? especially the Role/Scope or its Delegated vs Application issue?
Query to list all the Apps
az ad sp list --query '[].{appDisplayName:appDisplayName, appId:appId}'
Query "Microsoft Graph" app, to find "oauth2" scope of "Group.ReadWrite.All" permission
az ad sp list --query "[?appDisplayName=='Microsoft Graph'].{permissions:oauth2Permissions}[0].permissions[?value=='Group.ReadWrite.All'].{id: id, value: value, adminConsentDisplayName: adminConsentDisplayName, adminConsentDescription: adminConsentDescription}[0]" --all
{
"adminConsentDescription": "Allows the app to create groups and read all group properties and memberships on behalf of the signed-in user. Additionally allows group owners to manage their groups and allows group members to update group content.",
"adminConsentDisplayName": "Read and write all groups",
"id": "4e46008b-f24c-477d-8fff-7bb4ec7aafe0",
"value": "Group.ReadWrite.All"
}
Query "Microsoft Graph" app, to find app "Role" of "Group.ReadWrite.All" permission
az ad sp list --query "[?appDisplayName=='Microsoft Graph'].{permissions:appRoles}[0].permissions[?value=='Group.ReadWrite.All'].{id: id, value: value, adminConsentDisplayName: adminConsentDisplayName, adminConsentDescription: adminConsentDescription}[0]" --all
{
"adminConsentDescription": null,
"adminConsentDisplayName": null,
"id": "62a82d76-70ea-41e2-9197-370581804d09",
"value": "Group.ReadWrite.All"
}
I try assign a contributor role of subcription to a serviceprincipal using api.
Here is the information:
subcription ID:b59c6b1b-xxxxxxxxxx
serviceprincipal ID:73eb9e1e-xxxxxxxx
contributor ID: b24988ac-6180-42a0-ab88-20f7382dd24c(Azure built-in contributor role ID,I get it use 'az role definition list --query "[].{name:name, roleType:roleType, roleName:roleName}" --output tsv' by az cli.Is it right?)
I use the api like this
POST https://graph.microsoft.com/v1.0/servicePrincipals/b59c6b1b-xxxxxxxxxx/appRoleAssignedTo
Content-Type: application/json
Content-Length: 110
{
"principalId": "73eb9e1e-xxxxxxxx",
"resourceId": "b59c6b1b-xxxxxxxxxx",
"appRoleId": "b24988ac-6180-42a0-ab88-20f7382dd24c"
}
But I got the error respone like this
{
"error": {
"code": "Request_ResourceNotFound",
"innerError": {
"client-request-id": "4fed54c4-xxxxxxxxx",
"date": "2021-01-11T12:00:08",
"request-id": "4fed54c4-xxxxxxxxx"
},
"message": "Resource \u0027b59c6b1b-xxxxxxxxxxx\u0027 does not exist or one of its queried reference-property objects are not present."
}
}
It means that subcription didn't find by ID, in this example, I use subcription ID, I think may be I should use subcription ObjectID like other example resouce .But I don't find the method to get subcription ObjectID by using portal or api. Or maybe I fix error info into resourceID.So I want to know what infomation is I need to know to assign a contributor role of subcription to a serviceprincipal
You used the wrong API, this MS Graph API is to assign AAD App role to the service principal, what you need is to assign the RBAC role to the service principal in the subscription, you need to use this API - Role Assignments - Create, you could click the Try it button in this page, login your account and try it directly.
Make sure the client/user you used to get the token has the permission Microsoft.Authorization/roleAssignments/write to create the role assignment, e.g. User Access Administrator or Owner.
Sample:
PUT https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentId}?api-version=2015-07-01
{
"properties": {
"roleDefinitionId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/roleDefinitions/de139f84-1756-47ae-9be6-808fbbe84772",
"principalId": "xxxxxxx"
}
}
For more details, follow every steps in this doc.
Besides, if you can accept to use Azure CLI, you could use this command az role assignment create.
POST https://graph.microsoft.com/v1.0/servicePrincipals/{id}/appRoleAssignedTo
Content-Type: application/json
Content-Length: 110
{
"principalId": "principalId-value",
"resourceId": "resourceId-value",
"appRoleId": "appRoleId-value"
}
Here the {id} and "resourceId" is the object id of the Service Principal.
You can get this in one of the two ways described below :
Option 1 :
From Portal :
Azure Active Directory >> App Registrations >> Select All Apps from the dropdown menu >> find your app and click on it.
Option 2 :
From Graph
Using GET /servicePrincipals
https://graph.microsoft.com/beta/serviceprincipals?$filter=startswith(displayName, 'Application-Name')
You will have to replace the Application name above.
The output of the above request will have the guid value under the id key.
I am posting an AppRoleAssignment of the following structure to Graph API
{
"id": "00000000-0000-0000-0000-000000000000",
"principalId": "db243e99-61b3-4e42-9359-91ae9bffa715",
"resourceId": "e4ea7e05-50e7-4f38-b546-bdb6e9b1d77a"
}
For resource ID, I first tried the application id, as displayed by the B2C portal. This fails with an error the resource is not found. I got the object id of the application in that tenant, posted that instead, and still got the error resource is not found.
The specific error is
"Resource 'e4ea7e05-50e7-4f38-b546-bdb6e9b1d77a' does not exist or one of its queried reference-property objects are not present."
How can I add a user to an app in B2C?
From document : https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/entity-and-complex-type-reference#approleassignment-entity
resourceId is the unique identifier (objectId) for the target resource (service principal) for which the assignment was made.
You could firstly query the service principal object ID by application ID :
Get https://graph.windows.net/myorganization/servicePrincipalsByAppId/1062a13d-f7e5-4ea7-8d24-427f6ff1e5e1/objectId?api-version=1.6
Then you could assign a user(Where the resource does not declare any permissions, a default id (zero GUID) must be specified) :
{
"id": "id-of-role",
"principalId": "objectId-of-user",
"resourceId": "objectId-of-service-principal"
}
But if you want to restrict access if user is not assigned to an application, refer to reply from #Saca , you need to implement that yourself , Azure AD B2C does not currently have first class support for application assignments .
I am trying to add required permissions to an Azure AD application. I already know how to replicate information from a downloaded manifest through a PATCH REST call, e.g.
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "7b9103a5-4610-446b-9670-80643382c1fa",
"type": "Scope"
},
{
"id": "5df07973-7d5d-46ed-9847-1271055cbd51",
"type": "Scope"
}
]
}
]
As explained by Christer Ljung on his blog http://www.redbaronofazure.com/?page_id=181.
But the mystery remains how I can "convert" human-readable scopes such as Mail.Read to these obscure guids. I have read the following blog of Sahil Malik's at http://blah.winsmarts.com/2015-1-Programmatically_register_native_apps_in_Azure_AD_or_Office_365.aspx that explains how to get a list of available guids for a particular ServicePrincipal. E.g. through an http get to https://graph.windows.net/<tenant-id>/servicePrincipals()?api-version=1.6&$filter=appId%20eq%20'00000002-0000-0ff1-ce00-000000000000'> (Exchange) but when I try to get the list of available scopes of ServicePrincipal 00000003-0000-0000-c000-000000000000 (I believe the one for Graph API) the return value is just empty.
Interestingly, with Fiddler I was able to capture an http post request which contains all the guids when adding the permissions through Azure Portal.
Anyone any clue how I can do this programmatically?
After investigation, I discover a way to get permission guid using azure-cli. Share here in case anyone is finding this:
get all permisson and their GUID of a certain service principal by display-name, app-id or object-id. (Note that display-name is not unique and can maps multiple service principal)
$ az ad sp list --filter "displayName eq 'Microsoft Graph'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
$ az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table | head
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
Run the below command to get full information of certain service principal including its oauth2Permissions and servicePrincipalNames, etc.
az ad sp show --id 00000003-0000-0000-c000-000000000000 >microsoft_graph_permission_list.json
# microsoft_graph_permission_list.json
{
...
"appDisplayName": "Microsoft Graph",
"appId": "00000003-0000-0000-c000-000000000000",
"objectId": "b19d498e-6687-4156-869a-2e8a95a9d659",
"servicePrincipalNames": [
"https://dod-graph.microsoft.us",
"https://graph.microsoft.com/",
"https://graph.microsoft.us",
"00000003-0000-0000-c000-000000000000/ags.windows.net",
"00000003-0000-0000-c000-000000000000",
"https://canary.graph.microsoft.com",
"https://graph.microsoft.com",
"https://ags.windows.net"
],
"appRoles": [...],
"oauth2Permissions": [
{
"adminConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read and write all users' full profiles",
"id": "204e0828-b5ca-4ad8-b9f3-f32a958e7cc4",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read and write all users' full profiles",
"value": "User.ReadWrite.All"
},
{
"adminConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read all users' full profiles",
"id": "a154be20-db9c-4678-8ab7-66f6cc099a59",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read all users' full profiles",
"value": "User.Read.All"
},
...
]
...
}
Few things to say about this topic.
First, it is important to note that all of the OAuth2Permission Scopes are registered on the main Application Object in the developer's tenant. Thus, in general, you would not have access to that information, since it would be in a tenant where you are not a user. So as an external developer, these permission scopes are not discoverable via our APIs.
Second, you are able to see that the Azure Portal has access to this information because it has elevated access to query the OAuth2Permissions for all resources in all tenants. This is how our UX is able to populate all the permissions for all the various external and internal resources that you want to use in your tenant. The portal will first check which service principals are in your tenant (service principals get provisioned most commonly once you consent to use the application), then it will look up the Application Object that corresponds to that service principal, and find all the permission scopes. This behavior will hopefully allow you to only see the resource applications which are relevant to you, rather than populating your screen with all possible resources.
Finally, moving forward we are looking to take a step back from having to statically register permissions that clients require to call resource applications. Instead we will be pushing a new Incremental and Dynamic Consent framework. You will note that here that we are taking a dependency on the scope names, rather than the ObjectID GUIDs of those permissions as we did in the past. But still, I agree with you in general that the discoverability of the scopes that resources expose is very heavily dependent their own public documentation. I imagine in the future there might be an endpoint which exposes all the scopes available on a particular resource, but I know of no such work to do this in the near future.
Let me know if this helps!
I'm trying to update appRoles for an Azure AD application using GraphApi but get an error stating Authorization_RequestDenied with Insufficient privileges to complete the operation error.
I'm using PostMan to call Rest endpoint https://graph.windows.net//applications/d66c96ea-56fd-41c8-884b-fc0664792f7d?api-version=1.6
This is Body for may PATCH request:
{
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Writer has the ability to create tasks",
"displayName": "Writer",
"id": "66ea9f02-31b0-40b2-94fb-67a408bc10e3",
"isEnabled": true,
"value": "Writer"
}
]
}
I have added all permissions to Microsoft Graph and Windows Azure Active Directory from my AAD application.
I have 2 applications in AAD. One is called "PostMan" for PostMan OAuth2.0 so that I can get a bearer token. Another on is called "TaskTrackerApp" on which I'm trying to set appRoles via GraphApi.
Thanks for your help!
You can try to upgrade the role of the AD application you use to a administrator permission. Run the following commands in PowerShell:
Connect-MsolService
$ClientIdWebApp = '{your_AD_application_client_id}'
$webApp = Get-MsolServicePrincipal –AppPrincipalId $ClientIdWebApp
#use Add-MsolRoleMember to add it to "Company Administrator" role).
Add-MsolRoleMember -RoleName "Company Administrator" -RoleMemberType ServicePrincipal -RoleMemberObjectId $webApp.ObjectId
What RequiredResourceAccess list you have configured on application "PostMan" and also the one who is making changes is he/she the owner of this application "TaskTrackerApp" or a global admin in the directory?
I hit this too this week. In my case trying to update the reply URLs. I cut down my request to eventually just trying to update the name of the app. Same thing, Insufficient privileges.
Eventually tracked it down to the fact that an application cannot update another app IF it is not an owner of the app. e.g. Azure Portal->App Registrations->(Select App to Update)->Settings->Owners.
In my case, in the "real world" case, the app I was trying to use to update was supposed to be the owner (because it was the app that created the updating app)
So in the OPs case the "PostMan" app would need to be listed as an owner of the "TaskTrackerApp"