Office Graph API - get items from list - sharepoint

Is there a way within the Office Graph API to access items in a specific list - and not just items that I can see, but items I may not have access to?

Microsoft Graph access to SharePoint objects is currently in the beta version of Graph. See https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/resources/sharepoint.
To access specific items, the endpoint pattern would be:
GET https: //graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item-id}
For example: https:// graph.microsoft.com/beta/sites/mytenant.sharepoint.com:/sites/mysite:/Lists/Announcements/Items/1
As for being able to access items you do not have access to: No. That would be a horrible security problem if you could use any API to access such items.

There are two kinds of permission for app registered on the Microsoft Azure platform.
One is delegated permission. In this scenario, the user delegates access to a client application. We can call the REST API to get the data owned by who sign in.
The another is Application-level. In this scenario which permits a web service (a confidential client) to use its own credentials to authenticate when calling another web service, instead of impersonating a user. For example, a service or daemon app can retrieve all the users in a tenant if it has the Read all users' full profiles permission selected in the Azure Management Portal. And we can get the specific user's drive via the API like below:
GET /users/<id | userPrincipalName>/drive
More detail about REST API for handling the files on OneDrive for business, please refer to link below:
https://graph.microsoft.io/en-us/docs/api-reference/v1.0/resources/drive
And here is the link for the authentication protocols for the Azure AD support:
https://msdn.microsoft.com/en-us/library/azure/dn151124.aspx

No, you can't retrieve SharePoint list items using Graph API, but you can use SharePoint REST API for that. It's similar to Graph API and supports OAuth.
Check the documentation for SharePoint API here: https://msdn.microsoft.com/en-us/library/office/dn531433.aspx

To get items from a list within SharePoint, you can use SharePoint Rest API. A sample code to get items using rest api is as below:
// For SharePoint 2010
var strRestUrl = _spPageContextInfo.webServerRelativeUrl + "/_vti_bin/listdata.svc/{{listname}}
// For Office 365 or SharePoint 203
var strRestUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/GetByTitle({{listname}})/Items
$.ajax({
url: strRestUrl,
method: 'GET',
headers: { "Accept": "application/json; odata=verbose" },
success: function(response){
// success callback function
},
complete: function(){
// complete callback function
},
error: function (data) {
// error callback function
console.log(data.responseJSON.error);
}
});
If you are using SharePoint 2010 then Rest URL is different and if you are using SharePoint 2013/Office 365 rest URL is different. Hope this code will help you.
More details about REST API are as available at below link:
https://msdn.microsoft.com/en-us/library/office/dn531433.aspx

Related

Not able to get findMeetingTimes using Microsoft Graph API

I am trying to get and analyze data from office 365 resource room booking data, for that I am using graph API to find meeting times,
https://graph.microsoft.com/v1.0/me/findMeetingTimes ,
this query perfectly working on Microsoft graph explorer after given permissions to calendar.ReadWrite and calendar.ReadWrite.Shared, but this is not working through api call in SharePoint page and postman test with same permissions given in azure WEB API.
it is returning below error
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "90f335e7-1955-48c2-a9e9-300ea232e181",
"date": "2018-10-26T07:47:13"
}
}
}
If any suggestion appreciated.
I'm assuming you are using the MSGraphClient inside of SPFx, it is using the delegated permissions (not app permissions as per the comment in this thread). Can you confirm you are using this? https://learn.microsoft.com/en-us/sharepoint/dev/spfx/use-msgraph
This api (https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_findmeetingtimes) requires "Calendars.Read.Shared, Calendars.ReadWrite.Shared" as you stated.
You would need to add additional permissions for this api call to work. As you only get User.Read.All for SPFx with MSGraphClient. This is documented here https://learn.microsoft.com/en-us/sharepoint/dev/spfx/use-aadhttpclient
From your provided request Id, I can see that your request had these scopes, which is missing the Calendars.Read.Shared permissions scope.
"Mail.ReadWrite","User.ReadWrite.All","Calendars.Read","People.Read.All","Group.Read.All","Directory.ReadWrite.All","MailboxSettings.Read","Contacts.ReadWrite","Group.ReadWrite.All","Sites.Manage.All","User.Invite.All","Files.ReadWrite.All","Directory.Read.All","User.Read.All","Files.Read.All","Mail.Read","Calendars.ReadWrite","Mail.Send","MailboxSettings.ReadWrite","Contacts.Read","Sites.FullControl.All","Reports.Read.All"
Look into the permissions of findMeetingTimes. You mode of authentication could be the root cause. For me I was tryint to use Application mode and this is not supported in this API.
I used and alternative api, /calendar/getSchedule to achieve this. If you login as your userid use ME option or use application mode login to login and use {id|userPrincipalName} to get calendar details for any meeting room.
Refer: https://learn.microsoft.com/en-us/graph/api/calendar-getschedule?view=graph-rest-1.0&tabs=http
Graph API Explorer link below provides the basics on how to login and got good examples for Graph to begin with.
https://developer.microsoft.com/en-us/graph/graph-explorer

Dynamics CRM 401 with token provided

I'm working on a dynamics crm integration for a Single-Tenant Server-to-server authentication. This is required to obtain tokens invisibly as the data will be used to create customer facing ui.
Therefore I’m getting a token back from Azure using the client_credentials grant type. However when I attempt to use this token to access any dynamics endpoint (such as those documented here: https://msdn.microsoft.com/en-us/library/mt607871.aspx)
All I get back is a 401 - access denied.
I’ve done the following:
Create an Azure application
Created and stored a key
Enabled permissions for Dynamics CRM online
I’ve seen some suggestion that I need a service user in the CRM itself to provide access, however when I try and create one the options described do not appear. (such as here: https://msdn.microsoft.com/en-us/library/mt790170.aspx#bkmk_ManuallyCreateUser )
Can you suggest any steps I might be missing here?
Heres a sample call using the token
{ method: 'GET',
url: 'https://<snip>/api/data/v8.2/accounts?$select=name&$top=3',
headers:
{ Authorization: 'Bearer <snip>',
Accept: 'application/json',
'OData-MaxVersion': '4.0',
'OData-Version': '4.0' }
}
EDIT:
Please note that I am using node.js here and C# / .net based answers are probably not going to be massively helpful
Here is a post on how to configure server to server auth. Assuming you ran through all the steps except creating the application user, you can do so by:
In CRM Navigate to Settings->Security->Users
Change the view from "Enabled Users" to "Application Users"
From the new user form change the form from "User" to "Application User".
You should now be able to create your application user.

How can I use an access token obtained from the Microsoft Graph API to access other APIs

My team and I built Web App that uses the Microsoft Graph API to recover data from a user's Office 365 environment. The application uses Azure AD to provide users with an access token.
We're now trying to add a component that can access the same user's Exchange Online informations using the EWS Api. However, it seems like trying to use the same access token as the one provided by the Graph API always returns a 401 (Unauthorized) response even if I have to proper permissions set on my Azure AD Application. Here is the code we use to try and access some user's information:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.HttpHeaders.Add("Authorization", "Bearer " + accessToken);
service.PreAuthenticate = true;
service.SendClientLatencies = true;
service.EnableScpLookup = false;
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
TasksFolder tasksfolder = TasksFolder.Bind(service, WellKnownFolderName.Tasks,
new PropertySet(BasePropertySet.IdOnly, FolderSchema.TotalCount));
The Bind method will always return a 401 error which prompts me to think that ther access token from one API is not valid for another one.
If that's the case, is it possible to get a single access token that will be valid for mutiple API calls ?
It should work okay but EWS doesn't support the constrained permissions model like REST so " EWS applications require the "Full access to user's mailbox" permission. as per the note in https://msdn.microsoft.com/en-us/library/office/dn903761(v=exchg.150).aspx

CAML-query to Sharepoint REST API results in "invalid audience URI"?

We have been successfully using the Sharepoint REST API to retrieve items from lists for a while now, but just recently decided to integrate the ADAL.JS in order to be able to access other Microsoft APIs such as Graph, Azure AD etc.
After successfully authenticating Adal.js automatically adds an
Authorization: Bearer eyJ..
header to the REST calls which works fine after fiddling with permissions a bit. The app is an Angular SPA hosted in Sharepoint so this header isn't necessary but doesn't really matter.
HOWEVER, a few of our REST calls require us to also query the taxonomy and as that isn't supported in the normal Sharepoint REST API, we have to hit the (/_api/web/lists/GetByTitle('ListName')/GetItems endpoint) with a CAML-query as request payload i.e. https://mydomain.sharepoint.com/sites/dev/_api/web/lists/GetByTitle('News')/GetItems
Unfortunatelly, this does not work as the API simply returns
Invalid audience Uri '5exx5cef-x7xx-4xxx-axxx-4xxxx2e40'.
So far my only solution is to modify the actual Adal.JS library to remove this header for this specific endpoint.
So, my questions is - has anyone done CAML-queries against Sharepoint REST APIs using Adal.JS, or ran into a similar problem and can provide any insight?
I suspect it is a configuration issue but am somewhat at loss on what to do.
In this case, you need to force setting the endpoint 'https://mydomain.sharepoint.com' to null. Else, each request to "mydomain.sharepoint.com" will add a graph authorization header which be validated by the SharePoint server. Since the app is registered on the Azure AD rather than SharePoint, it will be considered as a invalid audience.
Here is the workaround for your reference, please let me know if it works on your side.
(function () {
angular.module('app', [
'ngRoute',
'AdalAngular'
]).config(config);
// Configure the routes.
function config($routeProvider, $httpProvider, adalAuthenticationServiceProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainController',
controllerAs: 'main'
})
.otherwise({
redirectTo: '/'
});
// Initialize the ADAL provider with your clientID (found in the Azure Management Portal) and the API URL (to enable CORS requests).
adalAuthenticationServiceProvider.init(
{
clientId: clientId,
// The endpoints here are resources for ADAL to get tokens for.
endpoints: {
'https://graph.microsoft.com': 'https://graph.microsoft.com',
'https://mydomain.sharepoint.com': null
}
},
$httpProvider
);
};
})();

API '500' Error when delegating admin access on MySite (OneDrive / Office365)

I would value some advice as we are facing an issue with the Office 365 API where it returns 500 errors, when we request delegated administrative access to the Office 365 MySites Site Collection.
The use case scenario is the following:
We have independent organizations, 'A' and 'B' , which both own their respectives Azure Active Directroy accounts and O365/Azure subscriptions.
Organiation B wishes to utilise an application provide Organisation A which requires delegated administrative access to it's Office365 MySites Site Collection.
Organisation B successfully adds the app to their Active Directory Account by using the OAuth2 authorization process, granting the permissions that the application requires over their company active directory.
The final part is delegating access of an admin account in Organisation B to the Mysites site collection in Organisation B's Office 365 account. If we utilise the manual process via the administrative panel all works well, although programatically via the API we receive a '500' error.
We are using the following call to programmatically add the user as site collection administrator: (please note: I have used [ dummmy id's] below )
Endpoint URL:
https://<..org_a..>.my.sharepoint.com/personal/[[user_OrganisationA_com]]/_api/web/siteUsers/getByEmail(#u)?#u='[[info#_OrganisationA.com']]
Method: POST
Body: {'__metadata':{ 'type': 'SP.User' }, 'IsSiteAdmin':'true'}
HTTP Headers:
• "Content-Type": "application/json; odata=verbose"
• "X-HTTP-Method": "MERGE"
• "Authorization": "Bearer <OAuth2 token>"
• "Accept": "application/json"
On the request above we are trying to add info#_organisationB.com as site collection administrator to UserC's personal site in One Drive for Business service (UserC is identified by the email UserC#_organisationB.com). The user info#_organisationB.com has Global Administrator privileges in Organisation B's Office365 domain and UserC#_organisationB.com) is a basic user with no admin rights.
The call returns a 500 HTTP Status code (Internal Server Error) and the following message:
object(stdClass)[18]
public 'odata.error' =>
object(stdClass)[19]
public 'code' => string '-2146232832, Microsoft.SharePoint.SPException' (length=45)
public 'message' =>
object(stdClass)[20]
public 'lang' => string 'en-US' (length=5)
public 'value' => string 'You need to be a site collection administrator to set this property.' (length=68)
To our knowledge an API call should never return a 500 HTTP Status Code (Internal Server Error), if we are not allowed to do what we intend it should provide an Insufficiente permissions message or similar, however, the fact that we can manually apply this through the SharePoint Online management portal makes us believe we are hitting a bug that is stopping us from achieving what we intend.
Any advise would be appreciated!
Are you using SSL from the website you execute the request?

Resources