Microsoft Azure AD Graph API to add member to a group - azure

Trying to add members to a group using Microsoft graph API, was able to add member to the group to which Application owner is the owner of but not to the group that was created by other member.
When I try to add member to the group and Application owner is not the owner of the group, I am receiving the following error
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "2c5a99ff-70XXXXXXXXXXXXXXXXX",
"date": "2X-XX-XXXX 23:42:54"
}
}
}
These are the permissions given to the App API
Can someone help me understand how the add member to group works with Azure? only group owner will be able to add member to the group? Is there any configuration that needs to be enabled for Application to let Application owner add member to any group?

If you are using Delegated permissions, the effective permissions of a token will be the combined permissions of the app and user.
If the user does not have the necessary role/ownership, then your app can't do it either.
If your app needs to act with more permissions than the user has, you'll need to use application permissions instead of delegated permissions.
To use app permissions, your app back-end must acquire tokens using the client credentials flow, which does not involve a user.
In this case only the application's app permissions matter, delegated permissions will have no effect.

Related

Unexpected 403 in Sharepoint rest api list items roleassignments call

We created a sharepoint add-in with the follow permissions:
<AppPermissionRequests AllowAppOnlyPolicy="true"><AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="Read"/></AppPermissionRequests>
My understanding is that an app with tenant scope permissions should be able to read all the site contents. In this case the call to
/_api/web/lists('<id>')/items(<id>)/roleassignments
fails with the following error:
Client error 403
{
"odata.error":
{
"code":"-2147024891, System.UnauthorizedAccessException",
"message":
{
"lang":"en-US",
"value":"Access denied. You do not have permission to perform this action or access this resource."
}
}
}
Note that a call to /_api/web/lists('<id>')/items(<id>) for the same item works fine. The roleassignments call with tenant permissions is also working for one of the SPO instances but not for a different one.
We've struggled with this issue on and off, because the solution is not obvious, nor even sensible from a least-privilege perspective. In short:
Your application requires FullControl rights in order to access RoleAssignments.
More details
If using an application created by Azure AD, you can demonstrate this by granting and consenting to SharePoint permissions such as:
AllSites.Read (delegated)
MyFiles.Read (delegated)
Sites.Selected (application)
User.Read.All (delegated)
User.Read.All (application)
If using SharePoint-created application, use appregnew.aspx and appinv.aspx to create the app and grant it Read rights at some reasonable scope; try http://sharepoint/content/tenant.
Then get a bearer token using a client_credentials workflow (use Postman, for example).
Try a query like:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl
Make sure the Authorization header value is Bearer your-access-token
It will work.
Now try the same query, but with getting role assignments:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl&$expand=ListItemAllFields/RoleAssignments/RoleDefinitionBindings/Name
It will fail as you described, with status 403 and System.UnauthorizedAccessException.
Now grant and consent to the SharePoint application permission Sites.FullControl.All, or use appinv.aspx to add FullControl rights. Get a new bearer token. (The old one encodes the old rights granted to the app in the role field of the payload.). You'll need to wait a few minutes until the permissions apparently propagate from AD to SharePoint, if you're using an Azure AD application.
Try the last query again, and it will work.
IMHO, requiring FullControl in order to resolve something like a role assignment, which is needed to capture the permissions required to access content in a SharePoint library, is unjustified. I could understand, sort of, if tenant-scope Read permission were required. However, granting AllSites.Read or tenant-scope (http://sharepoint/content/tenant in appinv.aspx XML permissions) doesn't seem to enable roleassignment lookup.

Create Azure AD group with Group.Create Permission

I am trying to create an Azure AD Group via the Graph API using a service principal. The intent is that the service principal will create the group in a Pipelines run.
The call I am using to attempt to create the group is
az rest --method post \
--uri 'https://graph.microsoft.com/v1.0/groups' \
--body '{"description": "A description", "displayName": "MyAppGroup", "mailEnabled": false, "mailNickname": "test", "securityEnabled": true, "owners#odata.bind": ["https://graph.microsoft.com/v1.0/users/oooooooo-oooo-oooo-oooo-oooooooooooo"]}' \
--headers "Content-Type=application/json"
To graph permissions, I have bound the API permission Group.Create to my service principal. To understand the permissions I am required to grant, I am following this page:
https://learn.microsoft.com/en-us/graph/api/group-post-groups?view=graph-rest-1.0&tabs=http#permissions
With the Group.Create permissions, when I run the rest call to the Graph API above, I get the following permission error
Forbidden({
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"date": "2020-11-02T13:31:35",
"request-id": "...",
"client-request-id": "..."
}
}
})
I completely understand that if I were to add the Directory.ReadWrite.All, I could make the group and would have all required permissions. However this permission is overscoped and would allow my service principal to disable users in the Active Directory tenant - something my organisation will now allow. Therefore I cannot grant my service principal this permission.
The documentation I have linked above implies to me that Group.Create is a sufficient permission to enable a service principal to create a group.
My question is what I am doing wrong, or what permissions am I missing to be able to create a group? Directory.ReadWrite.All is clearly overscoped to simply create an AD security group and so using it is not an option for me.
Hopefully this helps someone else - I realised the answer immediately after posting this.
I had added the property
"owners#odata.bind": ["https://graph.microsoft.com/v1.0/users/oooooooo-oooo-oooo-oooo-oooooooooooo"]
to the json post data.
Removing this property allowed me to create the group with just the Group.Create permission.
Adding the permission User.Read.All allows the service principal to read the user data for the owner, and so is sufficient to create the group with any necessary owners.
After adding this API permission, my service principal was able to create the group (with owners) as expected.

I'm calling MS-Graph from Logic App and getting an "Unauthorized" error

I get an "Unauthorized" status code (401) when I call MS Graph from my Logic App.
The MS Gaph URI I'm calling has been tested separately using Graph Explorer to insure that it was a properly formed request.
I'm guessing that the issue has to do with Application Permissions needing to be granted to the AD App registration.
The Logic App is not prompting the user to grant the "Delegated" permissions I added to the App Registration. This is why I'm guessing, I need to use Application permissions instead of Delegated permissions.
Here is the error being returned
{
"error": {
"code": "NoPermissionsInAccessToken",
"message": "The token contains no permissions, or permissions can not be
understood.",
"innerError": {
"request-id": "8addc6d3-fbf1-4a61-8ed2-b4593a10dd8c",
"date": "2019-07-16T12:29:27"
}
}
}
I would of course Grant the Application permissions myself in order to test this, but I don't have rights, and I need to research this a bit before I approach our admins.
You are right. You need grant the application permissions to your app. The Active Directory OAuth in logic app uses client credentials flow which doesn't need user interaction.
Here is the difference between application permission and delegated permission.

Azure AD remove permissions for registered app

I am using Azure AD to secure my service to service calls. (Each service having an application identity in Azure AD).
Example: Application A wants to access Application B.
I noticed that when requesting an accesstoken from Application A using Client Credential Flow (with Certificate), an accesstoken is issued without having me to explicitly set the permissions to access Application B.
This seems odd to me because the token returned has its audience set to Application B even thought I haven't explicitly given it access.
If I understand correctly, all registered app have access to each other by default?
Is there a way in Azure AD to explicitly require permissions to be set in order for application to access each other?
Below is a screenshot of Application A required permissions. As you can see, Application B is not listed here.
In the following screenshot, I assigned TodoListService (aka Application B) to the required permissions of Application A
I noticed that when requesting an accesstoken from Application A using Client Credential Flow (with Certificate), an accesstoken is issued without having me to explicitly set the permissions to access Application B.
Yeah, that one can be a bit surprising and I'm not sure why that is the case either.
What you need to do is define application permissions on the API, and then assign it on the client.
Then you need to check the caller has the required app permission in the token.
I have an article on this topic: Defining permission scopes and roles offered by an app in Azure AD.
To define an app permission on the API, you'll have to edit its manifest in Azure AD, and add an app role with member type of Application, something like:
{
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"displayName": "Read all todo items",
"id": "f8d39977-e31e-460b-b92c-9bef51d14f98",
"isEnabled": true,
"description": "Allow the application to read all todo items as itself.",
"value": "Todo.Read.All"
}
]
}
IIRC you have to generate a GUID for the id.
After defining this permission on the API, go to your client app, and add the app permission in the Required permissions.
Then you should press Grant permissions to grant the app permission.
Now then when the client acquires a token with client credentials, the token will contain:
{
"roles": [
"Todo.Read.All"
]
}
So you'll have to check that that is present.

What are the EXACT perms needed to use Get-AzureRmRoleAssignment as an app via a ServicePrincipal

I've seen posts like this one where there is confusion on exactly what permission is required to allow a ServicePrincipal to call Get-AzureRmRoleAssignment when logging in using Login-AzureRmAccount.
In my case if I call Get-AzureRmRoleAssignment with the -debug flag I can capture the following error in the body of the HTTP response:
Body:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
I have set perms for the application as follows... first the Azure AD access:
And then the Microsoft Graph access:
This still gives the authZ failure error. I have even tried an experiment where I gave the app ALL perms for each API, and that still did not work.
What's missing? What perms EXACTLY are needed to allow read only programmatic access to list the role assignments with this call?
First, as I answered in that case, Get-AzureRmRoleAssignmentdoesn't only needs read access for role assignment with Azure REST API permission but also needs Read directory data permission with Azure AD Graph API. After adding permissions,
Add AAD Graph API Permission:
You also need to click Grant permissions button to do admin consent.
Add Azure REST API Persmssions:
Also, before adding AAD graph API permissions for your sp, ensure your sp has permissions with Azure REST API by assigning a role (E.g. A Contributor Role) to it from Subscriptions RBAC(IAM).
I test this and succeeded.

Resources