Kit de ressources CASI - Partie 2

Ceci est la deuxième partie d’une série en cinq parties consacrée au Kit CASI (Claims, Azure and SharePoint Integration).  La partie 1 était une vue d’ensemble qui présentait l’intégralité de l’infrastructure et de la solution, et qui décrivait les objectifs de la série.  Dans cet article, nous allons nous concentrer sur le modèle relatif à l’approche suivie :

1.       Utiliser une application WCF personnalisée en tant qu’application frontale pour vos données et le contenu

2.       Rendre l’application capable de prendre en charge les revendications

3.       Apporter des modifications supplémentaires pour pouvoir transférer l’application vers le nuage Windows Azure

Utilisation de WCF

L’infrastructure du Kit CASI repose sur le postulat principal selon lequel toutes les données d’application utilisent une application WCF en tant qu’application frontale.  À l’instar de toutes les applications personnalisées, il s’agit d’un élément que vous (développeur) devez créer.  Quasiment aucune connaissance spécifique à SharePoint n’est requise pour cette partie de votre projet. Cette tâche est à la portée de n’importe quel développeur .NET sachant utiliser Visual Studio pour créer une application WCF.  Si votre objectif final est d’héberger ce service WCF dans Windows Azure, je vous conseille vivement d’utiliser le kit de développement de Windows Azure pour télécharger les modèles de création d’applications Azure, puis de créer une application WCF Azure depuis le début.  En ce qui concerne la version actuelle du Kit CASI, il existe une limitation importante qu’il est nécessaire de bien comprendre.  Le Kit CASI ne prend en charge que l’envoi des types de données .NET principaux en tant que paramètres aux méthodes WCF.  Par conséquent, les types string, bool, int et date fonctionnent, mais il n’existe aucune méthode pour passer une classe personnalisée en tant que paramètre.  Toutefois, si cela s’avère nécessaire, je vous conseille de créer le paramètre en tant que chaîne et de désérialiser votre paramètre en XML avant d’appeler votre méthode WCF, puis de le resérialiser en instance d’objet dans votre code WCF.  À part cela, je ne vois pas pour l’instant de limitations significatives, mais nul doute qu’une liste de demandes ne va pas tarder à se constituer, une fois que le Kit aura été largement adopté et utilisé.  À titre indicatif, le kit que vous voyez aujourd’hui n’est rien d’autre que la version 1.0 de mes idées sur la façon dont nous pourrions exploiter l’ensemble de tous ces éléments. Il a été conçu pour répondre aux scénarios de base qui m’ont paru importants.  Je n’ai aucun doute sur le fait qu’il y aura de nombreuses possibilités d’amélioration au fil de son utilisation.

Rendre l’application capable de prendre en charge les revendications

Une fois l’application WCF créée, la prochaine étape consiste à la rendre capable de prendre en charge les revendications.  Pour cette étape, je ne peux m’attribuer aucun mérite. J’ai suivi (et vous recommande) l’excellent article de blog en quatre parties d’Eric White de l’équipe Office, qui explique comment intégrer les revendications de SharePoint dans une application WCF.  Si vous avez déjà créé votre service WCF, je vous conseille de commencer à la deuxième partie de la série d’articles du blog d’Eric à l’adresse suivante : http://blogs.msdn.com/b/ericwhite/archive/2010/05/13/determining-caller-identity-within-a-wcf-web-service.aspx.  Vous DEVEZ également continuer en effectuant les étapes décrites dans la troisième partie à l’adresse suivante : http://blogs.msdn.com/b/ericwhite/archive/2010/06/18/establishing-trust-between-a-wcf-web-service-and-the-sharepoint-2010-security-token-service.aspx en commençant à la section décrivant l’établissement d’une relation d’approbation entre le service Web et le serveur SharePoint, et qui s’intitule  Procedure: Establish Trust between the Web Service and the SharePoint Server.  Vous devez effectuer toutes les étapes à partir de ce point, à savoir copier l’empreinte numérique du certificat de signature de jetons STS SharePoint et coller cette information (ainsi que d’autres informations) dans le fichier web.config de votre application WCF.  Je préfère ne pas suivre les étapes relatives au certificat SSL dans la troisième partie, car l’utilisation d’un certificat auto-signé ne sera pas très utile lorsque votre application sera hébergée dans Windows Azure.  À priori, vous n’avez rien de plus à faire. Néanmoins, en règle générale, il est conseillé d’obtenir un certificat SSL approprié auprès d’une autorité de certification approuvée pour votre application WCF Windows Azure.  REMARQUE :  vous N’AVEZ PAS besoin de suivre les étapes de la quatrième partie du blog d’Eric.  Une fois que vous avez effectué les étapes ci-dessus, vous disposez d’une application WCF prenant en charge les revendications de SharePoint.  À la fin de cet article, je vous décrirai les étapes supplémentaires à effectuer pour transférer votre application vers Windows Azure.

Faire fonctionner l’application dans Windows Azure

Maintenant que vous disposez d’une application WCF Azure fonctionnelle, vous devez effectuer quelques tâches supplémentaires pour permettre à l’application de continuer à prendre en charge l’authentification basée sur les revendications et les jetons via Windows Identity Framework (WIF), et rendre son hébergement possible dans le nuage Windows Azure.  Examinons la liste ci-dessous :

1.       Configurez votre projet WebRole (c’est-à-dire votre projet WCF) de sorte qu’il utilise un répertoire virtuel local pour le débogage.  Je trouve que c’est plus facile à utiliser que le serveur de développement VS.NET pour les éléments basés sur des certificats (ce qui est votre objectif).  Pour ce faire, double-cliquez sur les propriétés du projet WebRole, puis cliquez sur l’onglet Web.  Sélectionnez la case d’option Utiliser le serveur Web IIS local, puis cliquez sur le bouton Créer un répertoire virtuel.  Une fois le répertoire virtuel créé, vous pouvez fermer les propriétés de projet.

2.       Ajoutez une référence à Microsoft.Identity dans votre projet WebRole.  Vous DEVEZ changer la référence en Copy Local = true et Specific Version = false.  Cela s’avère nécessaire pour copier l’assembly WIF dans le nuage avec votre package d’application.

3.       Téléchargez ce correctif logiciel WCF :  http://code.msdn.microsoft.com/KB981002/Release/ProjectReleases.aspx?ReleaseId=4009 pour Windows Server 2008 R2, http://code.msdn.microsoft.com/KB971842/Release/ProjectReleases.aspx?ReleaseId=3228 pour Windows Server 2008.

4.       Vous DEVEZ ajouter cet attribut à votre classe WCF :  [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)].  Par exemple, la classe ressemble à ceci :

namespace CustomersWCF_WebRole

{

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

    public class Customers : ICustomers

    {

 

5.       Vous DEVEZ inclure les données de configuration suivantes dans l’élément behavior utilisé par votre service.  Cela permet de corriger les problèmes susceptibles de se produire en matière d’affectations de ports aléatoires dans l’environnement Azure.  Pour effectuer un test localement, vous devez télécharger le correctif logiciel décrit au point 3 ci-dessus :

          <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

 

Voici un exemple en contexte du fichier web.config pour mon service WCF :

    <behaviors>

      <serviceBehaviors>

        <behavior name="CustomersWCF_WebRole.CustomersBehavior">

          <federatedServiceHostConfiguration name="CustomersWCF_WebRole.Customers"/>

          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

          <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

        </behavior>

      </serviceBehaviors>

    </behaviors>

 

6.       En premier lieu, téléchargez le certificat SSL utilisé pour l’application WCF vers le portail des développeurs Azure.  REMARQUE :  la classe de base du Kit CASI dépend impérativement de l’utilisation du protocole SSL ; par conséquent, vous DEVEZ implémenter la prise en charge du protocole SSL dans votre application WCF Windows Azure.  Heureusement, ceci est un préalable indispensable au passage de données potentiellement sensibles entre un service nuage et la batterie de serveurs SharePoint. Ajoutez ensuite le certificat aux propriétés du rôle Azure dans Visual Studio, en double-cliquant sur le nom de projet WebRole (dans le dossier Rôles).  J’ai constaté qu’il était possible d’utiliser un certificat générique.  Toutefois, vous avez besoin d’un certificat PFX. En outre, veillez à exporter l’ensemble des certificats de la chaîne lorsque vous créez le fichier PFX.  Azure les développe tous lorsque vous téléchargez le fichier vers le portail des développeurs.

7.       Votre certificat SSL doit être pour Nom.votreNomDns.com, bien que toutes les applications Azure soient hébergées sur cloudapp.net.  Par exemple, mon certificat SSL était un certificat générique pour *.vbtoys.com.  Dans le DNS, j’ai créé un enregistrement CNAME appelé azurewcf.vbtoys.com, qui faisait référence à myAzureApp.cloudapp.net.  Par conséquent, lorsque j’établis une connexion vers https://azurewcf.vbtoys.com, mon certificat fonctionne, car ma requête et mon certificat SSL sont pour *.vbtoys.com, mais le DNS redirige ma requête en fonction de l’enregistrement CNAME, qui est myAzureApp.cloudapp.net.

8.       Dans votre projet Azure, double-cliquez sur le nom de projet WebRole (dans le dossier Rôles) et définissez les propriétés ci-après comme suit :

a.       Onglet Configuration :  désactivez la case à cocher Lancer le navigateur pour :  le point de terminaison HTTP et le point de terminaison HTTPS.

b.      Onglet Certificats :  ajoutez le certificat à utiliser pour SSL avec votre service.  Par exemple, dans mon labo, j’utilise un certificat générique émis par mon domaine pour l’ensemble de mes serveurs Web ; par conséquent, j’y ai ajouté mon certificat générique.

c.       Onglet Points de terminaison :  activez les cases à cocher pour les protocoles HTTP et HTTPS (les noms doivent être HttpIn et HttpsIn respectivement).  Dans la section HTTPS, la zone de liste déroulante correspondant au nom du certificat SSL doit maintenant contenir le certificat SSL que vous avez ajouté à l’étape b.

9.       Si vous disposez d’une méthode WCF qui renvoie un script, la balise script doit inclure l’attribut DEFER pour fonctionner correctement lors de l’utilisation du composant WebPart inclus dans le Kit CASI, ou lorsque votre propre fonction JavaScript l’assigne à la propriété innerHTML d’une balise.  Par exemple, votre balise script doit ressembler à ceci : <script defer language='javascript'>

10.   Si vous disposez d’une méthode WCF qui renvoie un contenu incluant d’autres balises de mise en forme, par exemple <style>, vous devez les inclure dans une balise <pre>. Sinon, elles ne seront pas traitées correctement lors de l’utilisation du composant WebPart inclus dans le Kit CASI, ou lorsque votre propre fonction JavaScript l’assigne à la propriété innerHTML d’une balise.  Par exemple, le contenu renvoyé avec une balise style doit ressembler à ceci : <pre><style>.foo {font-size:8pt;}</style></pre>

Ce sont les étapes nécessaires pour configurer l’application WCF qui doit être hébergée dans Azure ; voici quelques conseils supplémentaires qui peuvent s’avérer utiles, et dans certains cas indispensables, en fonction de votre implémentation :

1.       Utilisez le nom complet lors de la création de l’adresse du point de terminaison qui consomme le service, c’est-à-dire nomOrdinateur.foo.com au lieu de nomOrdinateur.  Cela permet d’établir une transition plus nette vers le format final hébergé sur Windows Azure et d’éviter les erreurs qui se produisent lorsque votre certificat SSL est conçu pour utiliser un nom de domaine complet.

2.       Vous POUVEZ ajouter cet attribut : httpsGetEnabled="true" à cet élément : <serviceMetadata httpGetEnabled="true" />, si vous souhaitez obtenir WSDL sur SSL.  Toutefois, il y a actuellement un bogue dans SharePoint Designer qui empêche d’utiliser SSL pour WSDL.

3.       Pour obtenir des conseils en matière de débogage et de connexion de données, voir mon article à l’adresse suivante : http://blogs.technet.com/b/speschka/archive/2010/09/19/azure-development-tips-for-debugging-and-connection-strings.aspx.

4.       Dans la plupart des cas, vous devez partir de l’hypothèse selon laquelle votre espace de noms de service WCF sera http://tempuri.org.  Pour obtenir des instructions sur la façon de le changer, lisez l’article à l’adresse suivante : http://blogs.infosupport.com/blogs/edwinw/archive/2008/07/20/WCF_3A00_-namespaces-in-WSDL.aspx.

Service WCF fini

Si vous avez suivi l’ensemble des étapes de configuration ci-dessus et si vous avez déployé votre application WCF sur Windows Azure, lorsqu’un utilisateur effectue un appel vers ce service WCF à partir d’un site SharePoint, vous obtenez l’intégralité de son jeton d’utilisateur, ainsi que toutes les revendications associées.  Notez qu’à l’issue de ces modifications, le service WCF fonctionne aussi localement, ce qui vous permet d’effectuer facilement des tests si vous souhaitez expérimenter quelques modifications incrémentielles avant de transférer l’application vers le nuage.  Le fait de disposer du jeton d’utilisateur vous permet de faire des choses très intéressantes dans votre service WCF.  Par exemple, dans votre service WCF, vous pouvez énumérer toutes les revendications d’un utilisateur afin de prendre toutes sortes de décisions en matière de permissions affinées.  Voici un exemple d’utilisation de LINQ sur l’ensemble des revendications d’un utilisateur pour déterminer si l’utilisateur actuel est un administrateur, car si tel est le cas, un niveau de détail supplémentaire est renvoyé dans la requête :

//recherche l’identité basée sur les revendications

IClaimsIdentity ci =

System.Threading.Thread.CurrentPrincipal.Identity as IClaimsIdentity;

 

if (ci != null)

{

//vérifie si des revendications sont présentes avant de continuer

       if (ci.Claims.Count > 0)

       {                       

       //recherche une revendication de groupe de type administrateur de domaine

var eClaim = from Microsoft.IdentityModel.Claims.Claim c in ci.Claims

              where c.ClaimType ==

"http://schemas.microsoft.com/ws/2008/06/identity/claims/role" &&

                     c.Value == "Domain Admins"

                     select c;

 

              //vérifie s’il existe une correspondance

              if (eClaim.Count() > 0)

                     //s’il existe une correspondance, cet utilisateur a une revendication d’administrateurs de domaine

                     //action à effectuer ici

}

}

 

Ce qu’il y a d’intéressant, c’est que vous pouvez également effectuer des demandes d’autorisation directement sur vos méthodes WCF.  Par exemple, vous disposez d’une méthode WCF qui interroge un magasin de données et renvoie la liste des PDG des sociétés clientes.  Vous souhaitez que cette information ne soit pas accessible à l’ensemble des employés mais uniquement aux responsables des ventes.  Il existe une manière habile et facile d’y parvenir en utilisant la demande PrincipalPermission sur la méthode, comme suit :

//la liste des PDG des sociétés clientes ne doit pas être partagée avec tout le monde,

//par conséquent, elle ne doit être visible que par les utilisateurs ayant un rôle de responsable des ventes

[PrincipalPermission(SecurityAction.Demand, Role = "Sales Managers")]

public string GetCustomerCEOs()

{

//votre code ici

}

 

À présent, si une personne tente d’appeler cette méthode et si elle ne possède pas de revendication associée au rôle de responsable des ventes, l’accès lui sera refusé si elle essaie d’exécuter du code visant à appeler cette méthode.  Parfait !

Il est également important de bien comprendre que ce mécanisme ne peut pas être déjoué par une usurpation d’identité.  Par exemple, vous ne pouvez pas simplement créer votre propre domaine dans un labo, y ajouter un compte, puis créer un rôle de responsable de ventes auquel vous ajoutez ce compte.  Pour comprendre la raison pour laquelle cela ne peut pas fonctionner, revenez aux étapes du blog d’Eric White (dans la section ci-dessus intitulée Rendre l’application capable de prendre en charge les revendications).  Si vous vous rappelez bien, vous avez ajouté l’empreinte numérique du certificat de signature de jetons utilisé par le service STS SharePoint.  En d’autres termes, lorsqu’une revendication parvient à votre application WCF, elle recherche le jeton qui doit être signé par la clé publique du service STS SharePoint.  Seul le service STS SharePoint peut le signer avec cette clé publique, car il représente la seule entité possédant la clé privée pour ce certificat de signature de jetons.  Vous êtes ainsi assuré que seule une personne authentifiée auprès de la batterie de serveurs SharePoint est en mesure d’utiliser le service WCF, et que les utilisateurs disposent uniquement des revendications qui leur sont accordées au moment où ils se connectent.  Le plus intéressant, c’est que cela inclut non seulement les revendications accordées aux utilisateurs lorsqu’ils s’authentifient auprès de leur annuaire des utilisateurs, mais AUSSI les revendications supplémentaires qui leur sont accordées par les fournisseurs de revendications personnalisés via la fonctionnalité d’augmentation des revendications dans SharePoint.  Par conséquent, il s’agit d’une solution de bout en bout réellement intégrée.

Étapes suivantes

Dans le prochain article, je commencerai par décrire la classe de base personnalisée et le composant WebPart personnalisé inclus dans le Kit CASI, et qui vous permettent de vous connecter à votre nouvelle application WCF Azure très rapidement et facilement.  J’utiliserai ensuite un service WCF que j’ai écrit pour le Kit CASI afin d’illustrer la fonctionnalité.  Je joins à cet article le fichier .cs que j’ai utilisé pour ce service.  Vous ne pourrez pas l’utiliser en l’état. Toutefois, il est inclus simplement pour que vous puissiez voir les différentes méthodes, le type de données, ainsi que le mode d’implémentation de certaines fonctionnalités de ce kit.  Au cours des articles suivants, vous me verrez principalement utiliser les méthodes a) GetAllCustomersHtml, b) GetCustomerCEOs et c) GetAllCustomers.  Elles sont intéressantes, car elles a) renvoient un contenu HTML (qui est de facto le type de renvoi par défaut pour l’affichage des données dans les composants WebPart), b) utilisent une demande PrincipalPermission et c) montrent comment vous pouvez renvoyer un type de classe personnalisé à partir de votre application WCF, puis utiliser ce même type de classe enrichi après avoir renvoyé les données dans SharePoint avec le Kit CASI.

Ceci est une version localisée d’un article de blog. Vous trouverez la version originale sur The Claims, Azure and SharePoint Integration Toolkit Part 2