Traduction

Cet article est la traduction la plus fidèle possible de l'article original de Steve Peschka, Retrieving Data from a Multi Auth Site Using the Client OM and Web Services in SharePoint 2010.

Récupération de données à partir d'un site multi-authentification en utilisant le modèle objet client et les services Web dans SharePoint 2010

Rien que l'objet de cet article est long à lire, si c'est une quelconque indication de ce que nous allons traiter aujourd'hui. Cet article va traiter d'un problème qui m'a tracassé, moi et d'autres personnes, pendant longtemps. J'ai récemment commencé à poser des questions dessus autour de moi, puis par coïncidence j'ai reçu un courriel de quelqu'un qui venait justement d'obtenir des informations sur la manière de résoudre ce problème.

Je vais couvrir uniquement les aspects les plus courants de ce scénario ; il existe de nombreuses tournures qui peuvent y être ajoutées. Le problème est de récupérer les données à partir d'un site SharePoint qui utilise plusieurs fournisseurs d'authentification ; dans ce scénario, supposez que l'un d'entre eux est les revendications Windows et que l'autre peut être n'importe quoi d'autre - cela pourrait être une authentification basée sur les formulaires ou une authentification SAML. Il peut arriver fréquemment que vous souhaitiez récupérer des données d'un tel site en utilisant soit le modèle objet client, soit des services Web SharePoint, mais que vous utilisiez l'authentification Windows pour accomplir cela. À ce stade, le problème a toujours été que même lorsque vous définissez vos informations d'identification Windows sur la demande, vous receviez toujours un message « Access Denied » lorsque vous demandez les données.

La résolution sous-jacente à ce problème est que si vous souhaitez accéder par programme à un site SharePoint qui utilise plusieurs fournisseurs d'authentification avec un jeu d'informations d'identification Windows, vous devez ajouter un en-tête supplémentaire à votre demande. Le nom de l'en-tête doit être « X-FORMS_BASED_AUTH_ACCEPTED » et la valeur doit être « f ». L'ajout de cet en-tête peut être un peu moins qu'évident pour ces deux scénarios courants, ainsi le reste de cet article servira à expliquer comment réaliser cela à l'aide d'un exemple de code.

Si vous utilisez le modèle objet client, vous devez ajouter un gestionnaire d'événement pour l'événement ExecutingWebRequest. Voici un exemple du code et à quoi cela ressemble :

 
Sélectionnez
//create the client context

ClientContext ctx = new ClientContext(MixedUrlTxt.Text);

 

//configure the handler that will add the header

ctx.ExecutingWebRequest +=

new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);

 

//set windows creds

ctx.AuthenticationMode = ClientAuthenticationMode.Default;

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

 

//get the web

Web w = ctx.Web;

 

//LOAD LISTS WITH ALL PROPERTIES

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

 

//execute the query

ctx.ExecuteQuery();

 

//enumerate the results

foreach (List theList in lists)

{

//do something with each list

}

Et c'est ici que s'opère toute la magie :

 
Sélectionnez
void ctx_MixedAuthRequest(object sender, WebRequestEventArgs e)

{

try

{

              //add the header that tells SharePoint to use Windows Auth

              e.WebRequestExecutor.RequestHeaders.Add(

"X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

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

       }

}

Le tour est joué ; ce code est en réalité assez simple et se passe d'explications. Effectuer la même chose avec une référence de service Web standard est quelque peu différent. Pour commencer, examinons pas à pas la procédure d'ajout d'une référence Web de style standard dans un site SharePoint à un projet dans Visual Studio 2010 :

  1. Faites un clic droit sur le nœud Référence de service et sélectionnez Ajouter une référence de service.
  2. Cliquez sur le bouton Avancé au bas de la boîte de dialogue.
  3. Cliquez sur le bouton Ajouter une référence Web au bas de la boîte de dialogue suivante.
  4. Saisissez l'URL du service Web que vous souhaitez utiliser dans la zone d'édition URL ; par exemple, pour ajouter une référence au service Web « Lists » dans le site à l'adresse http://foo, j'aurais saisi ceci comme URL : https://foo/_vti_bin/lists.asmx.
  5. Appuyez sur la touche Entrée ou cliquez sur le bouton correspondant à la flèche verte pour rechercher la référence de service Web, puis tapez un nom pour votre référence de service Web dans la zone d'édition Nom de la référence Web et cliquez sur le bouton Ajouter une référence.

Votre référence et les classes proxy de votre référence devraient maintenant être créées, mais vous allez devoir ajouter une classe partielle supplémentaire afin d'ajouter l'en-tête à votre demande de service Web. Commencez par ajouter une nouvelle classe à votre projet et donnez-lui un nom de votre choix. Étant donné que vous souhaitez simplement ajouter un comportement supplémentaire - ajouter un en-tête à la demande - vous allez devoir faire en sorte que ce soit une classe partielle. Cela veut dire que vous devez copier à la fois l'espace de noms et le nom de la classe utilisé dans le proxy créé pour votre référence Web. Voici les étapes pour réaliser cela :

  1. Cliquez sur le bouton Afficher tous les fichiers dans la fenêtre de l'Explorateur de solutions de Visual Studio.
  2. Cliquez sur le signe plus « + » en regard de votre référence de service Web afin de la développer.
  3. Cliquez sur le signe plus « + » en regard du fichier Reference.map afin de le développer.
  4. Double-cliquez sur le fichier Reference.cs afin de l'ouvrir.
  5. Copiez l'espace de noms et collez-le dans votre classe.
  6. Copiez le nom de la classe, y compris l'héritage, et collez-le dans votre classe en tant que nom de la classe. La classe de référence de service Web est déjà une classe partielle, donc vous n'avez aucune modification à effectuer ici.

Voici un exemple de ce à quoi ressemblait ma classe Reference.cs pour ma référence de service Web :

 
Sélectionnez
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="http://schemas.microsoft.com/sharepoint/soap/")]

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

Et voici ce que j'ai collé dans ma classe que j'ai créée :

 
Sélectionnez
namespace ClientOmAuth.listsWS

{

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

       {

       }

}

Vous remarquerez, ainsi, comment à la fois l'espace de noms et les noms des classes correspondent et que les deux classes héritent du même type de base.

Vous devez maintenant substituer la méthode GetWebRequest afin de pouvoir ajouter l'en-tête. Cela est accompli simplement en ajoutant le code suivant à votre classe partielle :

 
Sélectionnez
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)

       {

              //some error handling here

       }

                          

       return wr;

}

Coder afin de récupérer les données via le service Web est à présent exactement la même chose à ce que vous feriez pour n'importe quel site SharePoint à authentification Windows :

 
Sélectionnez
//create the web service proxy and configure it use my Windows credentials

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

lws.UseDefaultCredentials = true;

 

//get the collection of lists

XmlNode xLists = lws.GetListCollection();

 

//enumerate results

foreach (XmlNode xList in xLists.ChildNodes)

{

//do something with each List

}

Le tour est joué. Vous pouvez également appliquer ces informations à la récupération de données via REST, en utilisant les techniques que j'ai décrites dans l'article à l'adresse :

http://blogs.technet.com/b/speschka/archive/2010/09/25/retrieving-rest-data-in-a-claims-based-auth-site-in-sharepoint-2010.aspx

Conclusion

Dans cet article nous avons vu comment récupérer des données à partir d'un site SharePoint utilisant plusieurs fournisseurs d'authentification, à l'aide du modèle objet client et des services Web.

Liens

Remerciements

Je tiens ici à remercier Steve Peschka de m'avoir autorisé à traduire son article.
Je remercie xyz pour sa relecture technique et ses propositions.
Je remercie également abc pour sa relecture orthographique et ses propositions.