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 multiple 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 à ce sujet 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 pour la requête, 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 via le code à 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 requête. Le nom de l'en-tête doit être « X-FORMS_BASED_AUTH_ACCEPTED » et la valeur « 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 :
//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 :
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 :
- faites un clic droit sur le nœud Référence de service et sélectionnez Ajouter une référence de service ;
- cliquez sur le bouton Avancé au bas de la boîte de dialogue ;
- cliquez sur le bouton Ajouter une référence Web au bas de la boîte de dialogue suivante ;
- 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 ;
- 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 à la requête de votre service Web. Commencez par ajouter une nouvelle classe à votre projet et donnez-lui un nom de votre choix. Étant donner 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ée dans le proxy créé pour votre référence Web. Voici les étapes pour réaliser cela :
- cliquez sur le bouton Afficher tous les fichiers dans la fenêtre de l'Explorateur de solutions de Visual Studio ;
- cliquez sur le signe plus « + » à côté de votre référence de service Web afin de déployer le nœud ;
- cliquez sur le signe plus « + » à côté du fichier Reference.map afin de déployer nœud ;
- double-cliquez sur le fichier Reference.cs afin de l'ouvrir ;
- copiez l'espace de noms et collez-le dans votre classe ;
- 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 :
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 :
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 :
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 :
//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 :
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 h2s84 pour sa relecture technique et ses propositions.
Je remercie également zoom61 pour sa relecture orthographique et ses propositions.