List privilegedRoles using Azure app/service principal - microsoft-graph-api

I'm trying to request the "List privilegedRoles" resource using an app created in Azure's Active Directory.
I've given it all the Application permissions AND Delegated permissions in the Graph API app, to no avail.
The response is always:
"error": {
"code": "UnknownError",
"message": "{\"message\":\"An error has occurred.\"}",
"innerError": {
"request-id": "3e1bb5cf-2d2e-402f-8648-27193b28510a",
"date": "2018-06-06T14:26:02"
}
}
Any help would be much appreciated
UPDATE 1:
A full reproduction of the issue -
A V2 app with delegated permission "Directory.AccessAsUser.All" (and no application permissions), redirect url of http://localhost/myapp/permissions
step 1: admin consent
open browser at:
https://login.microsoftonline.com/MY-TENANT-ID/adminconsent?client_id=MY_APP_ID&state=12345&redirect_uri=http://localhost/myapp/permissions
and grant consent by an admin to the requested permission(s)
see successful redirect to:
http://localhost/myapp/permissions?admin_consent=True&tenant=MY_TENANT_ID&state=12345
step 2: get token
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=MY_APP_ID&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=MY-APP-SECRET&grant_type=client_credentials' 'https://login.microsoftonline.com/MY_TENANT_ID/oauth2/v2.0/token'
get reply like:
{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 0,
"access_token": "SOME-VERY-LONG-TOKEN"
}
step 3: attempt to get the resource
curl -X GET -H "Authorization: Bearer SOME-VERY-LONG-TOKEN" 'https://graph.microsoft.com/beta/privilegedRoles'
ERROR:
{
"error": {
"code": "UnknownError",
"message": "{\"message\":\"An error has occurred.\"}",
"innerError": {
"request-id": "cc9c950c-369c-4fb5-8ec4-eb4048e32a5d",
"date": "2018-06-10T09:09:57"
}
}
}

You can only use delegated permission for calling MSGraph PIM Api's.
Basically, you will need to do the following setup:
Create a native AAD application
Grant it Read and write privileged access to Azure AD permission and make sure the admin consents to it
Call MSGraph PIM Api's using this app with delegated token.
For more details, see https://blogs.msdn.microsoft.com/anujchaudhary/2018/06/07/powershell-sample-for-privileged-identity-management-pim-for-azure-ad-roles/

Related

Return 401 Unauthorized when use Graph API to read calendar and mailbox setting

I have setup a work account on Azure and add permissions "User.ReadBasic.All", "MailboxSettings.Read", "Calendars.ReadBasic.All" with application type
I can use client credential flow to get the access token successfully
https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
the token can be parsed by https://jwt.ms with proper role
"roles": [
"User.ReadBasic.All",
"MailboxSettings.Read",
"Calendars.ReadBasic.All" ]
I can query user information successfully using the token
https://graph.microsoft.com/v1.0/users/{userid}
But it returns error 401 when query calendar or mailboxSettings
https://graph.microsoft.com/v1.0/users/{userid}/calendar/calendarView?startdatetime=2021-12-23T08%3A00%3A00.000Z&enddatetime=2022-12-23T18%3A00%3A00.000Z
https://graph.microsoft.com/v1.0/users/{userid}/mailboxSettings
Both return error below
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"date": "2023-01-05T11:06:14",
"request-id": "xxx",
"client-request-id": "xxxx"
}
} }
Is "MailboxSettings.Read" and "Calendars.ReadBasic.All" enough for the above query, or need more permissions like Calendars.Read / Calendars.ReadWrite / MailboxSettings.ReadWrite ?
Also for permission of calendar, which one is a higher permission, is the below correct?
Calendars.Read < Calendars.ReadBasic.All
Could you please try by providing user.ReadAll permission instead of User.ReadBasic.All

How to update user's hireDate attribute in Azure AD using Graph REST API?

I searched for similar questions but did not find answer I was looking for.
My goal is to update all users in AAD with hireDate.
At first I tried to do so using client credentials flow.
POST https://login.microsoftonline.com/espiradev.onmicrosoft.com/oauth2/token
Content-Type:application/x-www-form-urlencoded
grant_type:client_credentials
client_id:{{client_id}}
client_secret:{{client_secret}}
resource:https://graph.microsoft.com
After I got access code I called:
PATCH https://graph.microsoft.com/v1.0/users/[user1]
Authorization:bearer {{access_token}}
Content-Type:application/json
{
"hireDate": "2019-05-01T00:00:00Z"
}
Response:
"error": {
"code": "-1, Microsoft.Office.Server.Directory.DirectoryObjectUnauthorizedAccessException",
"message": "Attempted to perform an unauthorized operation.",
"innerError": {}
}
Second try was using password flow (client and user credentials). I used my global admin [user1] credentials and called same HTTP request. Response was HTTP 204 (everything OK).
POST https://login.microsoftonline.com/espiradev.onmicrosoft.com/oauth2/token
Content-Type:application/x-www-form-urlencoded
grant_type:password
client_id:{{client_id}}
client_secret:{{client_secret}}
resource:https://graph.microsoft.com
username:{{user1_upn}}
password:{{user1_password}}
Unfortunately, when I tried to update other [user2] it went like this:
PATCH https://graph.microsoft.com/v1.0/users/[user2]
Authorization:bearer {{access_token}}
Content-Type:application/json
{
"hireDate": "2019-05-01T00:00:00Z"
}
Response:
"error": {
"code": "-1, Microsoft.Office.Server.Directory.DirectoryObjectUnauthorizedAccessException",
"message": "Attempted to perform an unauthorized operation.",
"innerError": {}
}
If I am using [user2] credentials to get access token then I can update [user2] hireDate, but can not update [user1].
Application permissions:
Application permissions
UPDATED:
Decoded access token has these permissions:
"scp": "Directory.AccessAsUser.All Directory.ReadWrite.All User.ManageIdentities.All User.ReadWrite User.ReadWrite.All"
UPDATED[2]:
both [user1] and [user2] has Office 365 E1 licences assigned (including SharePoint Online (Plan 1))
Am I doing something wrong? If anyone has a solution to share, it would be much appreciated.
Apart from the office licenses, the global admin user should have Sites.ReadWrite.All scope permission in the token to update the "hireDate" property for other users.

Create subscription for OneDrive Business returns 403 forbidden

I'm using Microsoft Graph API to build and integration with OneDrive. Everything has worked well and I have been able to register my App, get a token, navigate the OneDrive items and download files.
I started creating subscriptions to receive notifications from OneDrive when user does something. This works without any problem when user signs in with their "personal account" but when they use "work or school" account I get the following error message:
{
"error": {
"code": "ExtensionError",
"message": "Operation: Create; Exception: [Status Code: Forbidden; Reason: The caller does not have permission to perform the action.]",
"innerError": {
"request-id": "ffaf7fae-e0b0-4cd8-b911-bac4c2fb290a",
"date": "2019-09-18T00:18:40"
}
}
}
And this is the call I make to create the subscription:
curl -X POST \
https://graph.microsoft.com/v1.0/subscriptions \
-H 'Authorization: Bearer [access_token]' \
-H 'Content-Type: application/json' \
-H 'Host: graph.microsoft.com' \
-d ' {
"resource": "me/drive/root",
"changeType": "updated",
"clientState": "[email_Address]",
"notificationUrl": "https://webhook_url",
"expirationDateTime": "2019-09-19T04:43:47.6099364+00:00"
}'
The user has Files.ReadWrite.All permission which based on the documentation should be enough.
I had this same problem. The only difference is I am trying to setup a driveItem subscription on a business OneDrive path /users/<id>/drive/root but getting the same error as you on the response.
So, using the same access token, I did a GET /v1.0/users/<id>/drive/root and fetched the driveId of the parent from the response. Then I attempted to create the subscription at /drives/<driveId>/root and it worked. All requests were using the same access token and the previous way used to work for months.
So you might try doing a GET for your /me/drive/root and see if you can set it up with the driveId.
As a bonus, the subscription is now sending web-hooks like I expect.

Microsoft Graph API Beta: Subscribe to Event Notifications of another user

I created an app on https://apps.dev.microsoft.com
with the following Application Permissions:
Calendars.Read (Admin Only) Calendars.ReadWrite (Admin Only) User.Read.All (Admin Only)
Admin Consent
Admin consent was then successfully granted via this URL
https://login.microsoftonline.com/strixtechnology.onmicrosoft.com/adminconsent?client_id=bbb35336-faee-4c10-84b4-34136634db41&state=1234&redirect_uri=https%3A%2F%2Fdashmeetings.com%2Fmicrosoft%2Foauth
Get access token
An access token was then obtained from
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
with headers
Content-Type=application/x-www-form-urlencoded
and body with key-value pairs
grant_type=client_credentials
client_id=bbb35336-faee-4c10-84b4-34136634db41
client_secret=xxx
scope=https://graph.microsoft.com/.default
This returns an access token.
Subscribe to notifications
Using that access token, I then try to subscribe to the events on a certain resource mailbox:
POST https://graph.microsoft.com/beta/subscriptions
with headers
Content-Type=application/json
Authorization=Bearer <access_token_here>
and body
{
"changeType": "created,updated,deleted",
"notificationUrl": "https://dashmeetings.com/microsoft/notify",
"resource": "users/mahogany#strixtechnology.com/events",
"expirationDateTime":"2017-12-01T11:00:00.0000000Z",
"clientState":"1234"
}
This returns a 401 Unauthorized with
{
"error": {
"code": "ExtensionError",
"message": "Operation: Create; Exception: [Status Code: Unauthorized; Reason: Unauthorized]",
"innerError": {
"request-id": "98ce5e5e-1ce4-4417-8c35-456a3cc0e696",
"date": "2017-11-30T10:59:28"
}
}
}
This question seems similar to “Resource not found for the segment” using Graph subscription beta, but I follow the same steps without any luck
The admin consent URL had to be
https://login.microsoftonline.com/common/adminconsent?client‌​_id=bbb35336-faee-4c‌​10-84b4-34136634db41‌​&state=1234&redirect‌​_uri=https%3A%2F%2Fd‌​ashmeetings.com%2Fmi‌​crosoft%2Foauth
and the access token address:
https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/to‌​ken

Getting list of users in Google Admin SDK

I have OAuth login in my app. After that I have access_token.
I check token in google token info service:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<access_token>
And It returns:
{
"issued_to": "554651647288-tquejcu6mctplq4kin5dd9r81mtkg3vv.apps.googleusercontent.com",
"audience": "554651647288-tquejcu6mctplq4kin5dd9r81mtkg3vv.apps.googleusercontent.com",
"scope": "https://www.googleapis.com/auth/admin.directory.group https://www.googleapis.com/auth/admin.directory.orgunit https://www.googleapis.com/auth/admin.directory.user",
"expires_in": 3299,
"access_type": "online"
}
As you can see I have admin user directory permission.
Then I send GET request for getting information about user
curl -X GET https://www.googleapis.com/admin/directory/v1/users/test_user#test.com?access_token=<access_token>
And google returned me right user information. After that I decided to get list of users.
curl -X GET https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&access_token=<access_token>
And google returned me:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
But I don't understand why google returned me so error.
Could you please help me with this problem?
Thanks.
There are two solutions here.
1.This is the simple one. Put the URL params in quotes. This should do the trick - (fake access token used)
curl "https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&access_token=asdf.AHEasdfyIc9vuPQ_BGONpzEJkasdfWYXGujPw5iPI"
You don't need to pass in -X GET as that is the default.
2.In general it is bad practice to send the access_token in the URL as this URL may get logged somewhere along the way for innocuous reasons. You can also do this through HTTP Header of Authorization -
curl -H "Authorization: Bearer asdf.AHEasdfyIc9vuPQ_BGONpzEJkasdfWYXGujPw5iPI" https://www.googleapis.com/admin/directory/v1/users?customer=my_customer

Resources