Azure AD Extension Property + MS Graph API PATCH = Insufficient privileges to complete the operation - azure

I've been breaking my head over this problem for the past 2 days.
My goal is to allow a user (any regular non-admin Azure AD user) to update the value of an (Azure AD) extension property for his AD 'profile'/account through the Microsoft Graph API.
Consider the following situation:
I'm in control (Global Admin) of some Azure tenant + Azure AD Directory
There's a regular Azure AD User "Joe"
I've created an App registration + Service Principal (either through PS or in the Azure Web UI)
I've created an Azure AD Extension Property using the following Azure AD PS commands:
Connect-AzureAD -TenantId xxx-xxx-xxx
$app = Get-AzureADApplication -ObjectId yyy-yyy-yyy
$app | New-AzureADApplicationExtensionProperty -Name "MyProp" -DataType "String" -TargetObjects "User"
Response:
Name TargetObjects
---- -------------
extension_b63fa5d85b9d43b8b60f982e4bf2ad11_MyProp {User}
I've Admin consented everything on Graph both on Enterprise Application "Graph Explorer" and on my own App Registration, especially Directory.ReadWriteAll and User.ReadWrite.All
I then use the Graph Explorer (or Postman using my own App Registration) logged on as regular user "Joe"
Using the following PATCH request fails:
PATCH https://graph.microsoft.com/v1.0/me/
with body (type application/JSON):
{
"extension_b63fa5d85b9d43b8b60f982e4bf2ad11_MyProp": "test"
}
It fails with the following response:
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "d0ef63c0-f944-44c4-b90d-413b076b2bca",
"date": "2019-04-11T08:21:48"
}
}
}
I seem to be unable to find out why this happens.
Things to note:
When I log on in Graph Explorer as global admin I am able to update this property successfully
I am also able to update this property for any user using Azure AD PS, logged in as global admin
As soon as I give Joe the Global Admin or User Admin role in Azure AD he is able to update the property too
As "Joe", using the above PATCH request in Graph Explorer (or Postman), I am able to update "mobilephone"
As "Joe", using the above PATCH request in Graph Explorer (or Postman), I am unable to update "city", or "givenname"
What am I doing wrong?

Related

How can I grant consent to my own app in azure, in case I am not global admin in tenant?

Given I have created an app using this repository in Azure.
And this app is deployed using a Service Principal which was created by below command:
az ad sp create-for-rbac --name "fxpricepredictor" --role contributor --scopes "/subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/YOUR-RESOURCE-GROUP-NAME" --sdk-auth
Now, I need to get the API token to manage my created resources using REST APIs.
Based on documentation, I should be able use my tenantId, clientId and client_secret to get the token by calling the bellow endpoint:
curl: POST
https://login.microsoftonline.com/{{tenantId}}/oauth2/token
Please notice that, I am not the global admin in the tenant.
The official sample postman collection is here and here is how my request looks like in postman:
Sadly the endpoint does not provide me the token and instead it returns such error:
{
"error": "unauthorized_client",
"error_description": "AADSTS700016: Application with identifier 'MY_CLIENTID' was not found in the directory 'MY COMPANY'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.\r\nTrace ID: 5a9a2c53-c3c8-46da-a1a6-551b42082400\r\nCorrelation ID: bf7c5966-ffa4-4312-8a77-434c2560d65a\r\nTimestamp: 2022-10-05 14:54:23Z",
"error_codes": [
700016
],
"timestamp": "2022-10-05 14:54:23Z",
"trace_id": "5a9a2c53-c3c8-46da-a1a6-551b42082400",
"correlation_id": "bf7c5966-ffa4-4312-8a77-434c2560d65a",
"error_uri": "https://login.microsoftonline.com/error?code=700016"
}
please notice, I hided some sensitive values in error response by MY_CLIENTID and MY COMPANY
So, i guess, the main reason that i am facing this issue is that:
This can happen if the application has not been consented to by any user in the tenant.
Meaning that, i should consent my own app. Am I right ?
So, my question is:
How can i get the token to work with REST APIs to manage my resources ?
How can I grant consent to my own app, given that I am not a global Admin ?
Update:
As I figured out, I should be able to Grant Consent to my app using "Microsoft Graph permissions reference". And here is what i have done:
Login to Azure portal
Navigate to "Azure Active Directory"
Navigate to "App registrations"
Click on the created APP ("fxpricepredictor")
Navigate to "API permissions"
Click "Add a permission"
Click on "Microsoft Graph"
Choose "Delegated Permissions"
Search for "authentication" ---> (Sadly this option also requiereds Admin Consent)
I tried to reproduce the same in my environment and got the below results:
When I ran the same command as you, one Azure AD application named fxpricepredictor is automatically created with details like below:
az ad sp create-for-rbac --name "fxpricepredictor" --role contributor --scopes "/subscriptions/<subscriptionID>/resourceGroups/<resourcegroupName>" --sdk-auth
By including above details as parameters, I am able to generate access token successfully via Postman like below:
Please note that, I don't have global administrator role and granting admin_consent is not really required.
With the above access token, I am able to fetch and manage the Azure resources in that resource group like below:
GET https://management.azure.com/subscriptions/<subscriptionID>/resourceGroups/SriTest/resources?api-version=2021-04-01
Response:
The error AADSTS700016 may also occur if there is no application in your tenant with provided ClientID.
I tried including random ClientID which does not exist in Azure AD tenant and got same error as below:
So, make sure to check whether the application is existing or not with the given ClientID in Azure AD tenant.

get all AAD groups in which service principal is added as member

I have a scenario, I need to write functional tests for my API(s). API uses Azure AD authentication. There are multiple roles in system and role of a user is decided on the basis of membership of different AD groups.
so for functional test I need different users with in different groups.
I created a service principals with contributor rights in subscription and added them in groups and granted following Microsoft graph Application type API permissions.
- Application.Read.All
- Directory.Read.All
Now I used these apis to complete my use case.
1- https://login.microsoftonline.com/{tenant-Id}/oauth2/token
to get the access token against service principal.
2- GET https://graph.microsoft.com/v1.0/me/memberOf
to get the list of user's groups. but i got following response with authentication token of service principal.
{
"error": {
"code": "Request_ResourceNotFound",
"message": "Resource 'xxxx471-bxxxa-45a2-b61b-18xxxxx42af88' does not exist or one of its queried reference-property objects are not present.",
"innerError": {
"request-id": "fxxxxc41-319e-xxxx-xxxx-360xxxx58077",
"date": "2020-04-13T11:41:01"
}
}
}
I also have tried this
3- https://graph.microsoft.com/v1.0/users/{princialId}/memberOf
and get the following response
"error": {
"code": "Request_ResourceNotFound",
"message": "Resource 'xxxxx-xxxx-xxxx-b61b-18421142af88' does not exist or one of its queried reference-property objects are not present.",
"innerError": {
"request-id": "fxxxxc41-319e-xxxx-xxxx-360xxxx58077",
"date": "2020-04-14T05:59:03"
}
}
}
I have used object id of app registered in azure AD. when i searched service principal using power shell using following command I found different Object_Id than which is written on AD app on azure portal
command : get-AzureADServicePrincipal
with this Object_Id I was able to get service principal's groups using beta services.
https://graph.microsoft.com/beta/servicePrincipals/{object ID}/memberOf
anybody can explain why i was not able to get the groups of service principal using v1.0 service.
Thanks
anybody can explain why i was not able to get the groups of service principal using v1.0 service.
Because the v1.0 version does not support this API GET /servicePrincipals/{id}/memberOf , it just could be availale in the Beta version currently.
You could check this doc - List servicePrincipal memberOf, select the Version with 1.0, then it will give a prompt message like below.
I have used object id of app registered in azure AD. when i searched service principal using power shell using following command I found different Object_Id than which is written on AD app on azure portal
The Object Id of the service principal is not the same with that of the App Registration, the one you got from the powershell is correct, also, you can find it in the portal in the Enterprise applications like below.
I agree that beta service was not part of V1.0 but according to V1 documentation
https://graph.microsoft.com/v1.0/users/{id | userPrincipalName}/memberOf
should work.
please visit
https://learn.microsoft.com/en-us/graph/api/user-list-memberof?view=graph-rest-1.0&tabs=http
Please find documetation image here

How do list all applications in Graph Explorer with my Azure free account?

I want to learn Azure directory services, so I created a free Microsoft Azure account to play around with Azure, and then I created a new App registration at portal.azure.com. So I have this registered application in Azure with a Client ID, Tenant ID, and even a Client Secret, because I want to learn API permissions with this app.
Now in the Microsoft Graph Explorer, I want to try using API methods like Get Application and List Applications.
However, if I log in and run the API to list my applications (GET https://graph.microsoft.com/beta/applications), the response has an empty array of applications.
Also if I try to GET the specific app that I registered in AD, I get a 404: Resource Not Found found error.
What am I doing wrong? How can I use the Graph Explorer with my test Azure account so my registered application can be retrieved and edited with Microsoft Graph APIs?
More Details Below
When I run GET https://graph.microsoft.com/beta/applications in Microsoft Graph Explorer, I expect a list of my applications, including the one app I registered in Azure. Instead, here is the response:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#applications",
"value": []
}
When I run GET https://graph.microsoft.com/beta/applications/{client-id}, with my registered app's client-id, I expect all the details of my registered app, but instead, the response is error 404:
{
"error": {
"code": "ResourceNotFound",
"message": "Resource not found.",
"innerError": {
"request-id": "*****",<--I commented this out
"date": "2019-05-28T20:17:11"
}
}
}
If this were a permissions issue, I would expect unauthorized errors instead of "resource not found". I've tried adding Microsoft Graph permissions to my registered App (Directory.Read.All, Directory.ReadWrite.All), but this hasn't helped.
This is nothing to do with Azure free account. If you login in Graph Explorer using outlook account, it will identify this account as a personal account(with tenant outlook.com). That's why you can not find the applications you created in your tenant.
It is recommended to create a new user in your tenant to do the tests.
Here are the steps.
1.Click Azure Active Directory->Users->New User. The username should be something like username#{your tenant name}(XXX.onmicrosoft.com)
2.After the creation, add the roles for this user.

Add AAD application as a member of a security group

I'm trying to enable service to service auth using AAD tokens. My plan is to validate "groups" claim in the token to make sure the caller is a member of a security group that we created.
For example, we will create group1 for readers and group2 for writers. Then based on "groups" claim, I will figure out the right access level.
I use AAD app to issue the tokens (not a user), so I need that app to be a member of the security group. Azure AD powershell doesn't seem to accept application ids as group members. How to solve this? are there any other recommended patterns when the caller is another AAD app?
Command used:
https://learn.microsoft.com/en-us/powershell/module/azuread/Add-AzureADGroupMember?view=azureadps-2.0
Error:
Add-AzureADGroupMember : Error occurred while executing AddGroupMember
Code: Request_BadRequest
Message: An invalid operation was included in the following modified references: 'members'.
RequestId: 0441a156-3a34-484b-83d7-a7863d14654e
DateTimeStamp: Mon, 11 Dec 2017 21:50:41 GMT
HttpStatusCode: BadRequest
HttpStatusDescription: Bad Request
HttpResponseStatus: Completed
At line:1 char:1
+ Add-AzureADGroupMember -ObjectId "9c2cdf89-b8d6-4fb9-9116-7749adec85c ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-AzureADGroupMember], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.AddGroupMember
Unfortunately, you cannot add an application as a member of Azure AD group.
Though the official document for the Powershell cmdlet Add-AzureADGroupMember doesn't make clear you cannot use Application's ObjectId as the RefObjectId, absolutely you cannot use it.
You cannot add an application as a member of Azure AD group neither.
For example, we will create group1 for readers and group2 for writers.
Then based on "groups" claim, I will figure out the right access
level.
For your scenario, I'm afraid that you couldn't achieve this for now. I understand why you need this. According to your request, my thought is assigning your application from Enterprise Application to Groups or users and manger users with different access rights. However, you cannot choose more roles for the selected group. The only one role is default access If want to define more roles for the app, you can refer to this documentation.
I also tried to use Azure AD RBAC and create new conditional access for my test app,but all don't have read only this choice.
You can also put your idea in Azure Feedback Forum, azure team will see it. Also, I will upvote your idea.
Update:
Currently, you can add a service principal to an AAD Group:
Example:
$spn = Get-AzureADServicePrincipal -SearchString "yourSpName"
$group = Get-AzureADGroup -SearchString "yourGroupName"
Add-AzureADGroupMember -ObjectId $($group.ObjectId) -RefObjectId $($spn.ObjectId)
Updated 2:
Recently, I also see lots of users want to assign roles to a service principal to let the service principal have some permissions to access to the app with a role.
I want to make clear here. Role-based authorized should be used for users, NOT applications. And it's not designed for applications. If you want to give some different permissions you may consider to assign application permissions to your service principal instead.
You can expose your Web App/API with application permissions by editing the Manifest in app registrations.
You can go to Azure portal > Azure Active Directory > App registrations > Select your App > Manifest.
In appRoles, you can insert content like this:
{
"allowedMemberTypes": [
"Application"
],
"displayName": "Access to the settings data",
"id": "c20e145e-5459-4a6c-a074-b942bbd4cfe1",
"isEnabled": true,
"description": "Administrators can access to the settings data in their tenant",
"value": "Settingsdata.ReadWrite.All"
},
Then, you can go another app registration you want to give permission > Settings > require permissions > Add > Search the application name you want to access > Choose the application permission you created before.
Therefore, your sp can obtain a token with that application permissions in token claims.
Also, for authorization from the resource, you need to add code logic to give control policy for that token with Settingsdata.ReadWrite.All claim.
Update 3
Currently, you can add the service principal to one AAD Group directly in Azure portal:
Following Update 3 in the answer of #Wayne Yang, I've successfully implemented this using C# and the MS Graph SDK.
But I think the same should be possible using Powershell and simple REST API calls.
// create new application registration
var app = new Application
{
DisplayName = principal.DisplayName,
Description = principal.Description,
};
app = await _graphClient.Applications.Request().AddAsync(app);
// create new service Principal based on newly created application
var servicePrincipal = new ServicePrincipal
{
AppId = app.AppId
};
// add service principal
servicePrincipal = await _graphClient.ServicePrincipals.Request().AddAsync(servicePrincipal);
// add service principal to existing security group
await _graphClient.Groups[groupId].Members.References.Request().AddAsync(servicePrincipal);

Update approles for an Azure ActiveDirectory application using GraphApi

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"

Resources