Cross-Domain Probleme in SharePoint Add-Ins

Der folgende Beitrag zeigt wie in SharePoint Add-Ins Cross-Domain Abfragen verwendet werden können, ohne dabei auf Cross-Origin Resources Sharing (CORS) Probleme zu stoßen.

Möchte man auf Daten vom SharePoint zugreifen bietet sich die SharePoint REST API an. Erfolgt allerding ein Zugriff von einem SharePoint Add-In auf das Hostweb kann es zu Cross-Origin Resources Sharing Problemen kommen.

Viele Browser verbieten aus Sicherheitsgründen die Verwendung von JavaScript Funktionen, die auf Ressourcen einer anderen Domain zugreifen.

In Google Chrome wird Beispielsweise die folgende Fehlermeldung angezeigt, wenn man versucht mit JavaScript einen WebService einer anderen Domain anzusprechen:

XMLHttpRequest cannot load https://sp2013/_api/SP.UserProfiles.PeopleManager/GetMyProperties. No ‚Access-Control-Allow-Origin‘ header is present on the requested resource. Origin ‚https://myApp‘ is therefore not allowed access. The response had HTTP status code 401.

Um diesen Fehler zu vermeiden bietet Microsoft die domänenübergreifende Bibliothek (cross-domain library) an. Die JavaScript Bibliothek SP.RequestExecutor.js ermöglicht hierbei den Aufruf der SharePoint REST API mit dem Kontext von dem Add-In Web welches die Anfrage intern an das Hostweb weiterleitet.

Diese Bibliothek funktioniert nur für Add-Ins welche ein Add-In Web enthalten, z.B. SharePoint Hosted Add-Ins. Verwendet man allerdings ein Provider Hosted Add-In ohne Add-In Web ist diese Variante nicht möglich.

Cross-Domain Aufruf in Provider Hosted Add-Ins

Um in Provider Hosted Add-Ins, ohne Add-In Web, die REST API vom Hostweb verwenden zu können wird ein eigener WebService benötigt, welcher die Anfragen vom Add-In an das Hostweb weiterleitet.

Damit der WebService Aufruf im Kontext von dem aktuellen Benutzer erfolgt kann der UserAccessToken von dem SharePointContext verwendet werden. Hierfür muss der WebService mit dem Parameter SPHostUrl aufgerufen werden. Hierbei ist zu beachten, dass die entsprechenden Berechtigungen über die AppManifest.xml angefragt werden.

Das folgende Beispiel zeigt die Implementierung von dem WebService im Code-Behind einer aspx Seite:

[WebMethod]
public static string CallSpApi(string url)
{

var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext.Current);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "GET";
request.Accept = "application/json;odata=verbose";
request.ContentType = "application/json; charset=utf-8";
request.Headers.Add("Authorization", "Bearer " + spContext.UserAccessTokenForSPHost);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
return reader.ReadToEnd();
}

Das folgende Beispiel zeigt den Aufruf von dem WebService über JavaScript:

var spHostUrl = getQueryStringParameter("SPHostUrl");
var apiUrl = spHostUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
var webServiceUrl = "SharePointApi.aspx/CallSpApi?SPHostUrl=" + encodeURIComponent(spHostUrl);
var requestData = JSON.stringify({ url: apiUrl });
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: webServiceUrl,
data: requestData,
dataType: "json",
success: function (response) {
if (typeof response.d !== "undefined") {
console.log(JSON.parse(response.d));
}
},
error: function (data) {
console.log(data);
}
});

Die oben beschriebene Funktionalität ist auch mit WebAPI möglich. Da in dem ApiController der HttpContext nicht zur Verfügung steht kann der Standard SharePointContextProvider nicht verwendet werden. Eine Beschreibung für die Verwendung von dem SharePointContext befindet sich hier.

1 Comment on “Cross-Domain Probleme in SharePoint Add-Ins