Abrufen von Daten von einer Website mit mehreren Authentifizierungsanbietern mithilfe des Clientobjektmodells und von Webdiensten in SharePoint 2010

Veröffentlichung des Originalartikels: 02.04.2011

Schon die Überschrift dieses Beitrags ist quasi schon ein Zungenbrecher und ein Hinweis darauf, womit wir uns heute beschäftigen wollen. In diesem Beitrag wird ein Problem angegangen, das mich und andere lange Zeit beschäftigt hat. Ich habe erst vor kurzem dazu herum gefragt und schließlich per Zufall eine E-Mail von jemand erhalten, der gerade Informationen dazu erhalten hatte, wie dieses Problem zu lösen ist.

 

Ich stelle nur die allgemeinsten Teile dieses Szenarios vor. Es gibt zahlreiche Varianten, die ihnen hinzugefügt werden können. Das Problem ist das Abrufen von Daten von einer SharePoint-Website, die mit mehreren Authentifizierungsanbietern arbeitet. Für dieses Szenario soll angenommen werden, dass zum einen die anspruchsbasierte Windows-Authentifizierung und zum anderen entweder die formularbasierte oder SAML-Authentifizierung verwendet wird. Häufig möchten Sie Daten von einer solchen Website entweder über das Clientobjektmodell oder SharePoint-Webdienste abrufen, verwenden jedoch die Windows-Authentifizierung. Das Problem bis zu dieser Stelle war, dass selbst wenn Sie Ihre Windows-Anmeldeinformationen für die Anforderung festlegen, Sie dennoch einen Zugriffsverweigerungsfehler erhalten, wenn Sie die Daten anfordern.

 

Die endgültige Lösung dieses Problems ist, dass wenn Sie auf eine SharePoint-Website mit mehreren Authentifizierungsanbietern programmgesteuert mit einem Satz von Windows-Anmeldeinformationen zugreifen möchten, Sie Ihrer Anforderung einen weiteren Header hinzufügen müssen. Der Headername muss X-FORMS_BASED_AUTH_ACCEPTED lauten, der Wert f sein. Das Hinzufügen dieses Headers ist ggf. bei diesen beiden gängigen Szenarien nicht ganz unkompliziert, weshalb im weiteren Verlauf dieses Beitrags die Erläuterung mithilfe von Beispielcode erfolgt.

 

Wenn Sie das Clientobjektmodell verwenden, müssen Sie einen Ereignishandler für das ExecutingWebRequest-Ereignis hinzufügen. Der dazugehörige Code sieht in etwa so aus:

 

//Den Clientkontext erstellen

ClientContext ctx = new ClientContext(MixedUrlTxt.Text);

//Den Handler konfigurieren, der den Header hinzufügt

ctx.ExecutingWebRequest +=

new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);

//Windows-Anmeldeinformationen festlegen

ctx.AuthenticationMode = ClientAuthenticationMode.Default;

ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;

//Die Website abrufen

Web w = ctx.Web;

//LISTEN MIT ALLEN EIGENSCHAFTEN LADEN

var lists = ctx.LoadQuery(w.Lists);

//Die Abfrage ausführen

ctx.ExecuteQuery();

//Die Ergebnisse durchzählen

foreach (List theList in lists)

{

//Für jede Liste etwas ausführen

}

 

Und hier folgt die Lösung:

 

void ctx_MixedAuthRequest(object sender, WebRequestEventArgs e)

{

try

{

              //Den Header hinzufügen, der SharePoint anweist, die Windows-Authentifizierung zu verwenden

              e.WebRequestExecutor.RequestHeaders.Add(

"X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

              MessageBox.Show("Error setting auth header: " + ex.Message);

       }

}

 

Mehr ist nicht zu tun. Dieser Fall ist relativ einfach und praktisch selbsterklärend. Derselbe Vorgang bei einem standardmäßigen Webdienstverweis ist ein wenig anders. Zu Anfang wollen wir das Hinzufügen eines Webverweises im Standardformat in einer SharePoint-Website zu einem Projekt in Visual Studio 2010 durchgehen:

1. Klicken Sie mit der rechten Maustaste auf den Knoten Dienstverweis, und klicken Sie dann auf Dienstverweis hinzufügen.

2. Klicken Sie unten im Dialogfeld auf die Schaltfläche Erweitert.

3. Klicken Sie unten im nächsten Dialogfeld auf die Schaltfläche Webverweis hinzufügen.

4. Geben Sie die URL des gewünschten Webdiensts in das URL-Bearbeitungsfeld ein. Um beispielsweise einen Verweis auf den Listenwebdienst in der Website unter https://foo hinzuzufügen, muss diese URL eingeben werden: https://foo/_vti_bin/lists.asmx.

5. Drücken Sie die EINGABETASTE, oder klicken Sie auf die Schaltfläche mit dem grünen Pfeil, um den Webdienstverweis zu suchen. Geben Sie einen Namen für Ihren Webdienstverweis in das Bearbeitungsfeld Webdienstname ein, und klicken Sie auf die Schaltfläche Verweis hinzufügen.

 

Ihr Verweis und die Proxyklassen für den Verweis müssen nun erstellt werden. Sie müssen jedoch eine weitere Teilklasse hinzufügen, um den Header Ihrer Webdienstanforderung hinzufügen zu können. Fügen Sie zunächst Ihrem Projekt eine neue Klasse hinzu, und geben Sie ihr einen beliebigen Namen. Da Sie nur ein zusätzliches Verhalten hinzufügen möchten (einen Header zur Anforderung), richten Sie sie als eine Teilklasse ein. Dies bedeutet, dass Sie sowohl den Namespace als auch den Klassennamen kopieren müssen, der im Proxy verwendet wird, der für Ihren Webverweis erstellt wird. Gehen Sie dazu wie folgt vor:

 

1. Klicken Sie in Visual Studio im Projektmappen-Explorer auf die Schaltfläche Alle Dateien anzeigen.

2. Klicken Sie neben dem Webdienstverweis auf das Pluszeichen, um ihn zu erweitern.

3. Klicken Sie neben der Datei Reference.map auf das Pluszeichen, um sie zu erweitern.

4. Doppelklicken Sie auf die Datei Reference.cs, um diese zu öffnen.

5. Kopieren Sie den Namespace, und fügen Sie ihn in Ihre Klasse ein.

6. Kopieren Sie den Klassennamen, einschließlich Vererbung, und fügen Sie ihn in Ihre Klasse als den Namen Ihrer Klasse ein. Die Webdienstverweis-Klasse ist bereits eine Teilklasse, weshalb hier keine weiteren Änderungen erfolgen müssen.

 

Es folgt ein Beispiel meiner Klasse Reference.cs für meinen Webdienstverweis:

namespace ClientOmAuth.listsWS {

    using System;

    using System.Web.Services;

    using System.Diagnostics;

    using System.Web.Services.Protocols;

    using System.ComponentModel;

    using System.Xml.Serialization;

   

   

    /// <remarks/>

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]

    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.ComponentModel.DesignerCategoryAttribute("code")]

    [System.Web.Services.WebServiceBindingAttribute(Name="ListsSoap", Namespace="https://schemas.microsoft.com/sharepoint/soap/")]

    public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol {

Und nun folgt, was ich in die von mir erstellte Klasse eingefügt habe:

namespace ClientOmAuth.listsWS

{

       public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol

       {

       }

}

Sie werden feststellen, dass sowohl der Namespace als auch die Klassennamen übereinstimmen und dass beide Klassen vom selben Basistyp erben.

 

Sie müssen nun die GetWebRequest-Methode überschreiben, damit Sie den Header hinzufügen können. Dazu muss lediglich dieser Code Ihrer Teilklasse hinzugefügt werden:

protected override System.Net.WebRequest GetWebRequest(Uri uri)

{

       System.Net.WebRequest wr = null;

       try

       {

              wr = base.GetWebRequest(uri);

              wr.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

              //Geringfügige Fehlerbehandlung hier

       }

                          

       return wr;

}

 

Die Codierung zum Abrufen der Daten über den Webdienst entspricht nun exakt einer beliebigen SharePoint-Website mit Windows-Authentifizierung:

 

//Den Webdienstproxy erstellen und für die Verwendung mit meinen Windows-Anmeldeinformationen konfigurieren

listsWS.Lists lws = new listsWS.Lists();

lws.UseDefaultCredentials = true;

//Die Auflistung der Listen abrufen

XmlNode xLists = lws.GetListCollection();

//Ergebnisse durchzählen

foreach (XmlNode xList in xLists.ChildNodes)

{

//Für jede Liste etwas ausführen

}

Das war's auch schon. Mithilfe der hier beschriebenen Vorgehensweisen können Sie Daten auch über REST abrufen: https://blogs.technet.com/b/speschka/archive/2010/09/25/retrieving-rest-data-in-a-claims-based-auth-site-in-sharepoint-2010.aspx.

 

Es handelt sich hierbei um einen übersetzten Blogbeitrag. Sie finden den Originalartikel unter Retrieving Data from a Multi Auth Site Using the Client OM and Web Services in SharePoint 2010.