I'm getting this error when attempting to update the business or mobile phone attribute of a user using Microsoft's Graph API using Client Credentials (registered app). I'm able to update other attributes (city, country, department, displayName, givenName, jobTitle, officeLocation, postalCode, state, streetAddress and surName) just fine and if I send the same request via Microsoft's Graph Explorer using user credentials, it works.
I have tried this with both beta and v1.0 versions of Graph API, with the same error
I have the proper application permissions (User ReadWrite and Directory ReadWrite) as per https://learn.microsoft.com/en-us/graph/api/user-update?view=graph-rest-1.0
Our code uses an http client to send raw http requests (like Postman)
PATCH /v1.0/users/{user-GUID} HTTP/1.1
Authorization: Bearer {bearer token}
Content-type: application/json
Content-Length: 38
{
"mobilePhone": "+16122229876"
}
Business and mobile phones are "special" because they are used in MFA Authentication and therefore require higher permissions to update.
Your application needs to be granted at a minimum Helpdesk Administrator role, or if you want to update an administrators account you will need Company Administrator.
Unfortunately doing this is not simple and powershell is required as detailed here:
How to Add an Azure AD Role to a Enterprise Application (Service Principal)
I am not aware of this being documented anywhere, we also found this out the hard way when the permissions were changed some time back without warning or notice.
I'm going to write this off as an anomoly. The user for which I'm getting this error, happens to be the admin user in AD. If I try to update any other user, or at least the few I've tried, it works perfectly.
To make it even stranger, if I put a space in the phone number after the +1, it works for the user (admin) that normally gives me an error.
Even though Graph API accepts phone numbers without a space after the +1, if you attempt to edit the phone number in Azure Admin Center, it warns you that the phone number is an invalid format.
Related
I've been tasked with a project to get attendance information from specific types of Teams. I have a service account that is already a member of these Teams, however it is unable to access an endpoint needed to resolve JoinWebUrls to meetingIDs (See example #3, 'Retrieve an online meeting by JoinWebUrl').
I have done the following thus far:
Create a new App Registration and assigning it 'OnlineMeetings.Read.All' as an Application permission (this process needs to run as a script, meaning that Delegate permissions won't work here)
Create a new Application Access Policy, assigned the aforementioned App Registration's App ID to it, and granted it to the service account.
Signed into MS Graph as the service account (using the 'password' grant_type) and retrieved the 'events' within the Team (via /v1.0/groups/$GroupID/events)
Extracted the JoinWebURL parameter from each of those events.
Step 5 would be to resolve the meetingID from the JoinWebURL, however when I all of the following requests fail:
GET /v1.0/me/onlineMeetings?$filter=JoinWebUrl eq '$JoinWebURL' (as the service account, which should be able to interact with the meeting)
GET /v1.0/users/$ServiceAccountObjectID/onlineMeetings?$filter=JoinWebUrl eq '$JoinWebURL' (as the service account to access it's own object's meetings, however this does seem to be the endpoint for Application permissions rather than Delegate permissions)
GET /v1.0/users/$ServiceAccountObjectID/onlineMeetings?$filter=JoinWebUrl eq '$JoinWebURL' (using the App Registration mentioned earlier, signing in with the 'client_credentials' grant_type)
GET /v1.0/me/onlineMeetings?$filter=JoinWebUrl eq '$JoinWebURL' (as the App Registration trying to access any meeting, however this does seem to be the endpoint for Delegate permissions rather than Application permissions)
Basically, I'm stuck. Is there something obvious that I'm missing? I'm also considering raising a support call with Microsoft, to see if the behaviour I'm experiencing is merely a bug.
Thanks in advance.
Events and online meetings are two different API's, you have created an event and trying to get online meeting details. That's the reason you are getting those errors. If you want to get event details please try this document.
I'm trying to leverage the beta api for assigning azure users to applications.
I looked at the documentation and tried a variety of attempts in a C# console app using HttpClient and WebClient and couldn't succeed. I then went to the Microsoft graph explorer https://developer.microsoft.com/en-us/graph/graph-explorer . I couldn't get it to work.
I looked at the documentation
https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/approleassignment_get
The document's actual documentation of the HTTP request which doesn't match the Example. The Graph Explorer seems to hint that the example is correct, but through various attempts, I can only get a response of
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Direct queries to this resource type are not supported.",
...
}
}
My essential url is
https://graph.microsoft.com/beta/appRoleAssignments/
The example says {id} but I have no idea what to put in. I put in several guids, user ids, object ids, resource ids, and none worked.
It isn't saying any access denied messages so I assume it has nothing to do with Scopes (all though the documentation is a little empty regarding that as well).
Ideally, I'd be able to see if for a given Guest Azure User has access to a particular App, then I'd be able to go and Update the assignment. I'll probably also need to delete the assignment as well.
[Edit (2021-07-06): Use Microsoft Graph v1.0 for all of this.]
It looks like the Microsoft Graph API's beta endpoint doesn't currently allow you to list AppRoleAssignments.
[Edit (2018-10-11): The Microsoft Graph beta endpoint now supports the ability to list AppRoleAssignments, though you should still use Azure AD Graph for any production application, until it gets to v1.0.] Fortunately, the Azure AD Graph API does work for this (plus, it's not a beta endpoint, so it's more likely to be stable).
To list all app roles a user is assigned with Microsoft Graph:
https://graph.microsoft.com/v1.0/users/{id}/appRoleAssignments
To list all app roles a group is assigned:
https://graph.microsoft.com/v1.0/groups/{id}/appRoleAssignments
To do the reverse, and list all users or groups assigned to an app:
https://graph.microsoft.com/v1.0/servicePrincipals/{id}/appRoleAssignedTo
Azure AD Graph is deprecated and all support for it will cease in June 2022. The equivalent requests were (in the same order as above):
https://graph.windows.net/{tenant-id}/users/{id}/appRoleAssignments?api-version=1.6
https://graph.windows.net/{tenant-id}/groups/{id}/appRoleAssignments?api-version=1.6
https://graph.windows.net/{tenant-id}/servicePrincipals/{id}/appRoleAssignedTo?api-version=1.6
In the new Azure portal, under "Enterprise applications" > (your app) > "Users and groups", you'll see the list of users who are assigned to the application, as well as the app role they are assigned to. After testing , you could do the equivalent thing using Microsoft Graph API request :
https://graph.microsoft.com/beta/servicePrincipals/d0790296-0a14-4ab1-8f6c-4e4d3eb03036/appRoleAssignments
Your could get the service principal under "Enterprise applications" > (your app) >Properties>Object ID .Here is sample of the response :
id is the role id , In your scenario ,you could check whether record exists when the principalId matches the object id of the specific user , and principalType is user .
I am using the Microsoft Graph SDK as downloaded from NuGet (1.2). I authenticate to Azure AD (using ADAL).
I am using Client Credentials flow (not authenticated as any particular user) and am using Application Permission roles to access resources.
We are going to set up one service mailbox with a bunch of aliases. The aliases are given to the clients. This is so they are emailing an address that has a meaningful name to them.
My app will run as a service, and routinely scan new emails in this inbox. It should find the To address, and depending on what alias was used, file the email in a location relevant to that client.
The resource I want is: GET /users/<id | userPrincipalName>/messages
However, there doesn't appear to be a method in the SDK for it.
I can get users with this:
IGraphServiceUsersCollectionPage filteredUsers =
graphApi.Users.Request()
.Filter("userPrincipalName eq 'user#domain.com'")
.GetAsync().Result;
When I loop through the collection, I can see that the User has a 'Messages' property, but it is always null.
If I manually build a request message with HttpClient I can get the messages.
The second problem is that the Recipient property is always the userPrincipalName of the mailbox. How can I get the alias that was used by the sender?
While you are able to get your collection of users successfully, you have to make another request to receive the messages. This would look something like:
IUserMessagesCollectionPage userMessages =
graphApi.Users["user_id"].Messages.Request()
.GetAsync().Result;
To answer your second question, at this time you cannot access the original recipient through the Graph API, but you can do this through EWS. This is due to the fact that you can only retrieve the SMTP message headers through EWS. You can read more about how to do this here.
If this is something you believe is valuable to you in the Graph, I would encourage you to post it in our UserVoice.
If you want to get the email as a file, you can simply get the body as bytes through the SDK:
byte[] asBytes = Encoding.Unicode.GetBytes(message.Body.ToString());
I'm trying to use the Email Settings API from within a google marketplace app. Because I need all the logic to happen offline (in a cron job). I'm using an app engine Service Account, but when I'm trying to actually change the email settings for the users of the domain that installed it I'm getting this error:
You are not authorized to access this API.
Error 403
this is the scope: https://apps-apis.google.com/a/feeds/emailsettings/2.0/
I'm probably missing something, but I couldn't find the right docs to show me the way. How would I go about implementing an app that accesses the email settings even when the admin is offline?
You need to set the prn attribute to address of an admin account.
Examples for the directory API are at:
https://developers.google.com/admin-sdk/directory/v1/guides/delegation#instantiate_an_admin_sdk_directory_service_object
In terms of accessing the Email Settings API, you're really unlikely to get people to give you Service Account access to their domain.
On the other hand, if it's your domain (and thus you can add Service Account access), couple of pointers below:
What is important is that you add the following to the header:
"Authorization" = "Bearer <your_token>"
(note the very specific syntax - "Bearer+<1 space>+", as per https://www.rfc-editor.org/rfc/rfc6750 section 2.1)
"Content-Type" = "application/atom+xml"
(important for POST/PUT/DELETE requests, doesn't matter for GET)
that should get you up and running.
I'm just getting started with D2L and am running into problems.
On the "Getting Started" page, I have completed the first three steps:
1) Acquire an App Key/ID pair from D2L - I have received the App ID and App Key
2) Create a test account in your host LMS - I have created a new user account with the administrator role for testing
3) Choose a client library to work with - I am using the PHP SDK
4) Authenticate with your LMS - This is where I'm running into trouble.
When I use the Getting Started sample:
http://samples.valence.desire2learn.com/samples/GettingStartedSample/
And enter my host, app ID and app key and hit on the "Authenticate" button, I get a "This application is not authorized on this LMS instance. Ask your administrator to authorize this application" error.
I am an administrator on my D2L host and I'm not sure how to authorize my own app.
I have tried the following:
Navigating to the "Manage Extensibility" page because that's where D2L says my app should be located, but it isn't there.
Enabling the API (d2l.Security.Api.EnableApi) under the "DOME" page to no avail.
What am I doing wrong?
Based on your question and comments, there were two issues here:
First is that the list of App ID/Key pairs appropriate for your LMS get regularly fetched by your LMS from the D2L KeyTool service. The schedule for this fetching is once a day; accordingly, if the scheduled task isn't set up, or if your LMS isn't identifying itself properly to the KeyTool service, or if time hasn't yet elapsed after key granting to the next scheduled run of the task, the App won't yet be in your LMS' Manage Extensibility list. It sounds like you no longer have that issue.
Second is that the Valence Learning Framework APIs' authentication process (requesting and retrieving a set of user tokens for an LMS user) requires several LMS features to be properly set up: (a) the LMS must be configured to support Deep Linking, (b) the LMS must be set up to handle the ?target= parameter on incoming client URL requests, and curate that parameter throughout the user authentication process.
In cases where your LMS is not doing the user authentication but depending upon another, third-party IDP (like Shibboleth), any ?target= parameter passed into the login process must be taken care of by the IDP and properly handed back to the LMS after user authentication. In a situation where you have multiple redirections occurring during user authentication, this can involve successive generation of a target parameter, and each generation must re-URL-encode the previous request URL in its entirety (like sticking an envelope inside another envelope, inside yet another envelope).
If your LMS is not properly configured to support these two points, which you might not notice during other operations, then client calls to the Learning Framework APIs won't work because the calling client won't be able to fetch back a set of user tokens.
To solve the second of these issues, you may have to contact D2L's Customer Support desk -- they can verify, and adjust as necessary, the LMS configuration part of this authentication chain. If you're integrating your LMS with other third-party IDP components not administered or deployed by D2L, then you might also need to adjust their configurations: D2L can likely advise on what needs to be done there (curate the target parameter on URls), but cannot adjust the configuration for you in those cases.