Utiliser les spécifications des protocoles Open Protocol Specifications

 

Par Julien Chable, développeur/consultant chez Wygwam France sur les technologies Office, Open XML et SharePoint.

Blog de Julien.

L’annonce réalisée par Microsoft sur l’ouverture de ses protocoles avaient rendu sceptiques les grands du marché. Néanmoins, cette annonce avait été suivie de faits avec la mise à disposition des protocoles de Windows, d’Office, etc

Cette documentation définie les protocoles de communication dit « propriétaire » (et extension de protocoles existants) qui sont implémentées dans les systèmes client Windows (de Windows 2000 à Windows Vista) pour communiquer avec les systèmes serveur Windows (Windows NT 3.1 à Windows Server 2008). Les protocoles « inter serveur » sont aussi de la partie.

Les spécifications des protocoles sont réparties en plusieurs groupes ciblant les produits/plateforme : Windows, Office, SharePoint, Exchange et XAML. Ces documents introduisent les caractéristiques, les relations entre les différents protocoles, les structures, types de données, les codes d’erreurs, … Finalement à peu près tout ce dont vous aurez besoin pour réaliser les mêmes prouesses que Microsoft voire plus !

Malgré le statut non finalisé de certaines spécifications (statut ‘Preliminary’ lors de la rédaction de cet article), avoir accès aux spécifications des protocoles représente un réel gain quant la rapidité – et la fiabilité - d’implémentation des solutions permettant la communication avec ce produit.

Dans cet article, nous allons focaliser notre attention sur un scénario simple mais récurrent en utilisant les spécifications mis à notre disposition : envoyer des fichiers créés depuis notre application dans une librairie de documents. Et cela sans utiliser de librairies spécialisées ou artifices propriétaires autres que les spécifications fournies.

Préparation

Pour démarrer un scénario d’interopérabilité, il va tout d’abord falloir consulter les spécifications mis à notre disposition à l’adresse suivante: https://msdn.microsoft.com/en-us/library/cc203350.aspx. Nous avons besoin des spécifications suivantes :

  • [MS-AUTHWS]: Authentication Web Service Protocol Specification
  • [MS-LISTSWS]: Lists Web Service Protocol Specification

Les prochaines étapes ne sont basées que sur les connaissances fournies par les documents de spécifications des différents protocoles.

Etape 1 : Utiliser l’authentification SharePoint

Avant toute opération de ce type, il est indispensable de s’intéresser à l’authentification de SharePoint. En effet, tous les services web SharePoint doivent connaître le contexte et les droits de la « personne » distante pour pouvoir effectuer une action ou retourner un résultat.

Selon le service web utilisé, vous aurez à vous authentifier via le web – à l’aide d’un service web - ou directement via l’authentification NTML. Nous allons traiter les deux cas dans cet article, mais seulement le premier dans cette partie.

L’authentification web est décrite dans la spécification [MS-AUTHWS]: Authentication Web Service Protocol Specification qui n’est autre que la description au service web d’authentification de SharePoint. Le service web de SharePoint se situe à une URL de la forme http://{adresse du serveur :port}/{nom du site}/_vti_bin/Authentication.asmx.

A l’aide de ce service web vous êtes capable de connaître le type d’authentification d’une application web (Web Form, Windows ou Passport). Vous êtes aussi capable d’authentifier un utilisateur en utilisant son login et son nom de passe, première étape de quelques autres web service. Une demande d’authentification fonctionnera souvent de la manière suivante :

  1. Récupération du mode d’authentification,
  2. Authentification de l’utilisateur sur l’application web (authentification par Forms uniquement) en utilisant son login et mot de passe

L’authentification doit être de type web form pour fonctionner. Si l’authentification fonctionne, un ticket pour l’utilisateur est créé et il est attaché à la collection de cookie de la réponse du service.

SignIn
 

 

Remarque: vous trouverez un article permettant de mettre le système de web form en place à cette adresse* http://www.asp-php.net/tutorial/asp.net/sharepoint-double-authentication.php*.

Le service web offre deux méthodes :

Nom de la méthode Eléments renvoyés par la réponse du service Description
Login(string user, string password) CookieName Nom du cookie possédant le ticket.
  Géré par IIS avec un jeton de sécurité. Valeurs possibles [NoError, NotInFormsAuthentificationMode, PasswordNotMatch].
Mode() Mode Valeurs possible [None, Windows, Forms, Passport]

 

Voici le détail de mode tel que définie dans la spécification :

Mode Description
None Aucune authentification ou personnalisée.
Windows Géré par IIS avec un jeton de sécurité.
Passport L’ID Windows Live est utilisé.
Forms Soumission du login et mot de passe par un formulaire HTML. Un cookie avec le ticket est émis en cas de succès pour appeler d’autres services.

 

Maintenant que le fonctionnement du service est assimilé grâce aux détails fournis par la spécification, nous allons générer le proxy pour appeler ces méthodes.

Rappel: Pour obtenir le schéma de description du service web, le fameux WSDL, il faut faudra concaténer ‘?wsdl’ à l’URL du service web ASPX. Exemple :http://{adresse du serveur :port}/{nom du site}/_vti_bin/Authentication.asmx?wsdl

Création du proxy du service web d’authentification dans Visual Studio 2005

Afin de pouvoir consommer le service web et l’utiliser nous allons nous servir de Visual Studio 2005 pour générer le client WCF en suivant ces étapes :

  1. Créez un projet de type console dans Visual Studio 2005
  2. Ajout de la référence web vers le site http://{adresse du serveur :port}/{nom du site}/_vti_bin/Authentication.asmx

 

AddRefAuthWS
 

 

AddRefAuthWS2
 

 

Une fois la référence effectué, ajoutez le code suivant dans la méthode Main du projet :

using (SPAuthentification.Authentication authClient = new SPAuthentification.Authentication())
{
    if (authClient.Mode() == SPAuthentification.AuthenticationMode.Forms)
    {
        authClient.CookieContainer = new System.Net.CookieContainer();
        SPAuthentification.LoginResult result = authClient.Login("User1", "User1");
        System.Net.Cookie cookie = new System.Net.Cookie();
        if (result.ErrorCode == SPAuthentification.LoginErrorCode.NoError)
        {
            CookieCollection cookies = authClient.CookieContainer.GetCookies(new Uri(authClient.Url));
        cookie = cookies[result.CookieName];

        ...

        }
    }
}

Etape 2 : Récupérer les informations des listes disponibles dans SharePoint

Le service web Lists.asmx fournie dans SharePoint permet de manipuler la structure d’une liste (champs, …), les types de contenu, les éléments des listes et les documents des librairies, etc. Nous allons l’utiliser conjointement avec l’authentification précédente pour pouvoir lister puis modifier la structure d’une librairie de documents.

Comme le précise la spécification [MS-LISTSWS]: Lists Web Service Protocol Specification, l’emplacement de ce service web est de la forme : https://www.contoso.com/{nom de votre site}/_vti_bin/lists.asmx :

ListAsmxWSDL
 

 

Quelques-unes des méthodes disponibles et entièrement documentées sont illustrées dans le tableau ci-dessous :

Méthode Description
AddAttachment Ajouté un attachement à un élément
AddList Ajouter une liste
ApplyContentTypeToList Appliquer un type de contenu à une liste
GetList Obtenir une liste particulière
GetListCollection Obtenir la collection de listes disponibles
GetListContentTypes Obtenir la liste des types de contenu
GetListItems Obteni les éléments d’une liste spécifique
UpdateList Utilisé pour mettre à jour les propriétés de la liste, ajouter, supprimer ou modifier des champs.

Utiliser le jeton d’authentification pour appeler le service

Le code suivant illustre de la façon de réutiliser le jeton contenu dans le cookie de la réponse à la requête d’authentification. Nous créons un conteneur de cookie que nous associons au proxy du service que l’on va consommer. Nous ajoutons ensuite le cookie d’authentification du service web d’authentification dans ce conteneur afin que le service web distant puisse le récupérer et nous renvoyer les informations en fonction de nos droits.

...
cookie = cookies[result.CookieName];

using (SPLists.Lists listClient = new SPLists.Lists())
{
    listClient.CookieContainer = new CookieContainer();
    listClient.CookieContainer.Add(cookie);
    // On demande la liste des listes disponibles dans le site
    foreach (XmlNode list in listClient.GetListCollection().ChildNodes)
    {
    ...
    }
}

Puis nous appelons la méthode GetListCollection() du service web. Nous connaissons la structure de retour puisque celle-ci est documentée dans la spécification - 3.1.4.16.2.2 GetListCollectionResponse – et savons que nous devons récupérer les nœuds fils pour avoir les informations des listes.

Chaque List est défini par un type complexe nommé ListDefinitionCT qu’il nous suffit de consulter pour connaître les propriétés à récupérer :

<s:element name="GetListCollectionResponse">
    <s:complexType>
        <s:sequence>
            <s:element name="GetListCollectionResult" minOccurs="0">
                <s:complexType mixed="true">
                    <s:sequence>
                        <s:element name="Lists">
                            <s:complexType>
                                <s:sequence>
                                    <s:element name="List" type="tns:ListDefinitionCT" minOccurs="0" maxOccurs="unbounded"/>
                                </s:sequence>
                            </s:complexType>
                        </s:element>
                    </s:sequence>
                </s:complexType>
            </s:element>
        </s:sequence>
    </s:complexType>
</s:element>

La définition du type complexe - 2.2.4.11 ListDefinitionCT dans la spécification – permet de retrouver les attributs contenant les informations. Parmi ceux-ci vous pourrez retrouver ces attributs :

  • DocTemplateUrl
  • ID
  • Title
  • Description
  • ImageUrl
  • Name
  • BaseType
  • FeatureId
  • ServerTemplate
  • Created
  • Modified
  • Author
  • WebFullUrl
  • WebId
  • WorkFlowId
  • Hidden

Nous allons récupérer toutes les librairies de documents – et seulement ce type de liste – afin d’extraire quelques unes des informations :

foreach (XmlNode list in listClient.GetListCollection().ChildNodes)
{
    // On vérifie que la liste est bien une librairie
    if (Convert.ToInt32(list.Attributes["ServerTemplate"].Value) != 101)
        continue;

    string titre = list.Attributes["Title"].Value;
    string url = list.Attributes["DefaultViewUrl"].Value.Replace("/Forms/AllItems.aspx", string.Empty);

    Console.WriteLine(String.Format("'{0}' : {1}", titre, url));
}

Remarque: les valeurs pour l’attribut ServerTemplate sont spécifiées dans la spécification. La valeur 101 correspond au type de librairie de documents.

Si vous exécutez le code en l’état sur un de vos sites

SiteLibs
 

 

Res1
 

Etape 3 : Ajouter une liste dans SharePoint

Maintenant que nous savons récupérer les informations nous allons modifier le site SharePoint en y ajoutant une libraire. Utilisons maintenant une méthode pour créer une librairie dans le site :

// On ajoute une nouvelle librairie de documents au site
listClient.AddList("Mes Documents", "Mes documents rien qu'à moi !", 101);

Si nous exécutons une autre fois le code permettant de lister les sites de type librairie de documents dans le site, nous verrons qu’un nouveau site est disponible :

Res2
 

 

Res3
 

 

Remarque: Avant d’exécuter cette méthode, vérifiez que l’utilisateur authentifié via le service web d’authentification possède bien les droits de création, sinon une erreur vous sera renvoyée et aucune action n’aura lieue.

Conclusion

Cet article s’est voulu le plus simple possible pour insister sur l’utilisation des spécifications au travers d’un cas pratique. Ce sont les informations des spécifications qui ont permis de créer cet exemple en quelques minutes sans avoir à chercher des constantes ou des comportements à tatons.

Il est évident que la publication des spécifications des protocoles, longtemps connues de Microsoft seulement, représente un atout de taille pour pouvoir interopérer avec les produits et services proposés par l’éditeur. Cet article présente l’utilisation de deux spécifications relativement simples mais qui démontre bien que l’utilisation des documents Open Protocol Specifications est relativement puissante dans l’implémentation de fonctionnalités devant communiquer avec des produits Microsoft. Un grand pas pour l’interopérabilité, les entreprises et les éditeurs de logiciels.

Référence