[SharePoint 2013] Configurer une application web SharePoint 2013 en SSL avec HNSC et SharePoint apps (updated)

sharepoint-2013-logo

Dans ce post, nous allons voir comment configurer une application web SharePoint 2013 afin qu’elle puisse héberger des collections de sites ainsi que des apps SharePoint, en SSL. Nous verrons aussi, et surtout, comment générer un certificat SSL correspondant grâce à Active Directory Certificate Services.

Update : la première version de ce post contenait certaines erreurs qui ont été corrigées (collection de sites racine de la web app, certificat, mysite en HNSC). Les modifications structurantes sont en gras.

Introduction

Dans SharePoint 2013, les collections de sites et les apps peuvent être hébergées sur une même application web (un seul site IIS), et par défaut les apps ne fonctionnent qu’en SSL. Toutefois, les sites SharePoint et les apps ne seront pas accessibles avec le même nom de domaine car il est conseillé, pour des raisons de sécurité, d’utiliser un nom de domaine distinct pour les apps. Il nous faudra donc configurer cette web application avec un certificat capable de gérer les host names de toutes les collections de sites HNSC, les hosts names des apps SharePoint (auto générées), et le nom du serveur afin que le moteur de recherche puisse indexer le tout correctement.

Si on travaille avec des Host Named Site Collections (acronyme HNSC) sur une application web SharePoint, on retrouvera par exemple les collections de sites suivantes :

  • https://intranet.office15.dev
  • https://apps.office15.dev
  • https://dev.office15.dev
  • https://my.office15.dev
  • etc..

En parallèle, cette web app hébergera aussi les app webs des apps installées sur ces collections de sites.
Ces app webs seront accessible via un host name autogénéré par SharePoint, sur un domaine DNS distinct (ici office15apps.demo) :

  • https://app-12345678ABCDEF.office15apps.dev
  • https://app-3456789BCDEFG.office15apps.dev
  • etc.

Enfin, lorsque le moteur de recherche puisse indexer correctement cette web app, il cherchera à accéder à son url sans host name, et donc avec le nom du serveur. Dans mon cas, https://srv15.

Il nous faudra donc un certificat valide pour tous les host names *.office15.dev,  *.office15-apps.dev, et srv15.

Pré-requis

Il y a 2 pré-requis avant de suivre ce tutoriel :

  • Il faut configurer son environnement pour gérer les apps. Les diverses étapes sont très bien détaillées sur ce post TechNet : http://technet.microsoft.com/en-us/library/fp161236(v=office.15)
    Note : dans le cadre de ce tutoriel, contrairement à l’article TechNet, les collections de sites sont sur la zone DNS *.office15.dev, et les app webs sur *.office15apps.dev.
  • Pour générer le certificat SSL, le rôle Active Directory Certificate Services doit être installé sur l’un des serveurs de l’infrastructure. Dans le cadre de ce tutoriel, il est installé sur le contrôleur de domaine.

Avant de poursuivre, Il pourrait être intéressant de lire ce post afin de bien comprendre la notion d’app web et comment fonctionnent les apps pour SharePoint, ainsi que ce post qui explique la notion de HNSC.

Création de l’application web

La création de l’application web se fait de manière traditionnelle, via l’administration centrale. 
On prendra soin de sélectionner le port 443 (port associé au https), de laisser le host header vide (impératif pour gérer les HNSC), et d’activer le SSL.

image

Une fois créée, l’application apparait avec l’url https://NOM_SERVEUR/

webapps

Note : l’url affichée correspondra en théorie au nom du serveur sur laquelle est hébergée l’administration centrale. Nous aurons besoin de cette information pour créer la collection de sites racine et le certificat. En effet, c’est ce nom de serveur qu’il faudra utiliser.

Création des collections de sites

Pour créer les collections de sites en HNSC, il faudra utiliser PowerShell. Ce script permet de créer quelques collections de sites sur notre nouvelle web app :

Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue

 

New-SPSite https://SRV15 -Language 1036 -Template "STS#0"  -Name "HNSC ROOT" -OwnerEmail administrator@office15.dev -OwnerAlias OFFICE15\Administrator

New-SPSite https://team.office15.dev -HostHeaderWebApplication https://srv15 -Language 1036 -Template "STS#0"  -Name "Site d'équipe" -OwnerEmail administrator@office15.dev -OwnerAlias OFFICE15\Administrator

New-SPSite https://apps.office15.dev -HostHeaderWebApplication https://srv15 -Language 1036 -Template "APPCATALOG#0"  -Name "Catalogue des Apps" -OwnerEmail administrator@office15.dev -OwnerAlias OFFICE15\Administrator

New-SPSite https://dev.office15.dev -HostHeaderWebApplication https://srv15 -Language 1036 -Template "DEV#0"  -Name "Site du développeur" -OwnerEmail administrator@office15.dev -OwnerAlias OFFICE15\Administrator

New-SPSite https://search.office15.dev -HostHeaderWebApplication https://srv15 -Language 1036 -Template "SRCHCEN#0"  -Name "Centre de recherche" -OwnerEmail administrator@office15.dev -OwnerAlias OFFICE15\Administrator

 

#Pensez à créer un managed path wildcard /personal/ sur votre web app HNSC si vous souhaitez y héberger les my sites

New-SPSite https://my.office15.dev -HostHeaderWebApplication https://srv15 -Language 1036 -Template "SPSMSITEHOST#0"  -Name "Hôte des my sites" -OwnerEmail administrator@office15.dev -OwnerAlias OFFICE15\Administrator

Notez que l’on crée aussi une collection de sites avec le nom du serveur principal (sans l’argument –HostHeaderWebApplication), celle-ci servira de collection de sites racine pour le moteur de recherche, qui indexera alors toutes les collections de sites HNSC de la web app automatiquement.

Notez aussi qu’il est possible d’héberger les my sites sur une web app HNSC à condition d’y ajouter le managed path wildcard /personal/

Après exécution de ce script, les collections de sites seront crées mais inaccessibles, car puisque notre application web est configurée en SSL, il nous faut lui assigner un certificat au niveau de IIS.

A ce stade, on pensera à créer les entrées DNS correspondantes à ces collections de sites dans le gestionnaire DNS pour les faire pointer vers le serveur frontal SharePoint (ou le load balancer s’il y a plusieurs serveurs frontaux).

Passons maintenant à l’étape la plus intéressante.

Création du certificat

Le certificat SSL dont nous avons besoin pour notre application web doit être capable de gérer les 3 entrées DNS différentes :

  • SRV15 pour accéder à la collection de sites racine
  • *.office15.dev pour les collections de sites
  • *.office15apps.dev pour les app webs.

Contrairement aux certificats SSL à host name unique ou à wildcard unique, IIS ne nous fournit pas d’assistant permettant de créer facilement ce type de certificat. Nous allons devoir travailler avec la console mmc.

Génération de la demande de certificat

Connectons nous sur le serveur sur lequel est hébergé le rôle Active Directory Certificate Services, et exécutons (touche Windows + R) mmc.exe.

image

La consôle MMC devrait alors apparaitre. Dans le menu file, cliquer sur “Add/Remove snap-in…”

image

Sélectionner Certificates (avec l’option “Computer account”), et valider.

De retour dans la fenêtre principale, effectuer un clic-droit sur le magasin “Personal”, All Tasks, Advanced Operations, Create Custom Request…

image

Sélectionner “Active Directory Enrollment Policy”, et valider

image

Sélectionner le template “Web Server”, et cliquer sur Next

image

Déplier ensuite le template “Web Server” afin de voir apparaitre le détail, puis cliquer sur Properties.

image

Cette fenêtre devrait apparaitre :

image

C’est ici que nous devons spécifier les informations spécifiques à notre certificat :

  • Pour lui définir un nom, sélectionner le type “Common Name” et la valeur (par exemple “SharePoint HNSC”)
  • Pour lui assigner les host headers wildcards, dans la section Alternative name, créer une entrée de type DNS avec pour valeur *.office15.dev, une autre entrée de type DNS avec pour valeur *.office15apps.dev, et enfin une avec le nom du serveur (correspondant à l’url de la web app qui apparait dans l’administration centrale, dans mon cas SRV15).

La fenêtre devrait alors ressembler à ceci :

cert-dns

Si le certificat doit être pouvoir être exporté puis installé sur un serveur autre que celui sur lequel il est généré, allez dans l’onglet “Private Key”, section “”, et cochez “Mark this key as exportable” :

cert-keyexport

Note : il peut être intéressant de naviguer sur les autres onglets de cette fenêtre pour modifier certaines propriétés, comme la durée de validité du certificat qui est de 2 ans par défaut.

Dérouler alors la fin de l’assistant, et enregistrer le fichier de demande de certificat en spécifiant bien l’extension .req (pour ce tutoriel, on saisira sharepoint-hnsc.req).

Génération du certificat

Dans la console MMC, ajouter maintenant le snap-in “Certification Authority”, qui nous permettra de créer le certificat correspondant à la demande générée précédemment.

image

Sur le noeud correspondant à l’instance AD CS, effectuer un click droit, all tasks, submit new request…

image

Sélectionner le fichier de demande de certificat (sharepoint-hnsc.req) précédemment généré, et valider.

Le certificat final est alors créé, et une fenêtre apparait pour nous laisser choisir l’emplacement auquel le sauvegarder. Entrer un nom de fichier en précisant l’extension .cer, et valider.

image

Installation du certificat sur les frontaux de la ferme SharePoint

Les opérations décrites ci-dessous devront être répétées sur serveur frontal de la ferme SharePoint.

Copier le fichier sharepoint-hnsc.cer sur un emplacement accessible depuis le serveur SharePoint.

Se connecter ensuite au serveur SharePoint, et effectuer un clic-droit + install certificate sur le fichier sharepoint-hnsc.cer

image

Le wizard d’importation se lance alors, sur la page d’accueil il faut sélectionner “local machine” (afin que le certificat puisse être utilisé par IIS) et cliquer sur Next

image

Sur le 2ème écran, on peut laisser l’option par défaut et cliquer sur Next.

image

Le certificat devrait alors être disponible dans IIS.

Ouvrir la console IIS, puis effectuer un clic-droit sur notre web app, edit bindings :

image

Editer le binding par défaut :

image

Sélectionner le certificat que nous venons d’importer, et valider.

image

A ce stade, il devrait être possible de se connecter à nos collections de sites (https://team.office15.dev par exemple) :

image

Les SharePoint apps devraient aussi fonctionner. Pour le vérifier, vous pouvez installer une app (il y en a des toutes faites sur codeplex : http://apps.codeplex.com) dans le site du développeur (https://dev.office15.dev) et tenter d’y accéder :

image

image

Conclusion

Nous avons vu dans ce post comment créer un certificat SSL spécifique à un usage SharePoint 2013 afin de permettre des connexions sécurisées à la fois aux collections de sites SharePoint et aux app webs des apps SharePoint.

D’autre part, si la ferme est exposée sur internet, on devra obtenir le certificat via un fournisseur de certificat public. Malheureusement , ces derniers ne fournissent pas, en général, de certificat avec des alternate names wildcards. Pour contourner ce problème, une solution peut être d’acquérir 2 certificats wildcards distincts (un pour *.office15.dev, et un autre pour *.office15apps.dev), et de déclarer 2 bindings sur l’application web IIS en associant chaque certificat à une IP différente. Il faudra alors que le serveur aie 2 adresses IP minimum.


Arnault Nouvel

[SharePoint] Unification des fichiers de ressources multilingues

sharepoint-server

L’objet de ce post est de proposer une méthode permettant de stocker les resources multilingues uniquement dans le répertoire 14\Resources, afin d’éliminer les problématiques liées aux ressources stockées dans webapp\App_GlobalResources.

Lorsque l’on doit gérer des libellés applicatifs traduisibles dans un projet SharePoint, on les définit dans des fichiers resx que l’on inclue dans les sources de notre projet. Toutefois, selon le contexte et la manière que l’on utilise pour faire référence à ce libellé, on devra déployer le fichier resx dans le répertoire 14\Resources (pour les libellés SharePoint) ou 14\CONFIG\Resources (pour les libellés ASP.NET utilisés dans les aspx et ascx exclusivement, le fichier étant copié par SharePoint dans le dossier App_GlobalResources de l’application web).

Bien que le principe soit facile à comprendre (cet article résume tout de manière très claire) et à mettre en oeuvre, je trouve dommage de devoir gérer 2 fois plus de fichiers resx que nécessaire, et de toujours avoir à se demander dans quel fichier mettre un libellé. Certains développeurs ont trouvé des moyens de déployer le même fichier resx aux 2 endroits via des tâches planifiées ou en bidouillant des fichiers cachés du projet Visual Studio, mais cela ne résout pas le problème fichiers stockés dans App_GlobalResources : ces derniers doivent être traités spécialement via ligne de commande ou timer job afin d’être copiés du répertoire 14\CONFIG\Resources vers le répertoire App_GlobalResources de l’application web qui l’exploite. Cela ralentie notamment le développeur au quotidien lorsqu’il doit ajouter de nouveaux libellés, car il doit soit lancer des lignes de commandes soit déclencher des timer jobs pour permettre la propagation des fichiers.

J’ai mis au point une solution qui permet de n’utiliser que les fichiers resx du répertoire 14\CONFIG. Ceci est rendu possible par le développement d’un ExpressionBuilder custom qui ira chercher les ressources avec l’API SharePoint. Restera à enregistrer la classe correspondante dans le web.config, puis à utiliser l’expression builder (que je nomme ici Resources14) dans nos pages aspx et controles ascx avec <% $Resources14:monfichier:maresource; %>  plutot que le traditionnel <% $Resources:monfichier:maresource; %>

Code de l’ExpressionBuilder

[ExpressionPrefix("Resources14")]

public class Resources14ExpressionBuilder : ExpressionBuilder

{

 

        public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)

        {

            CodeMethodInvokeExpression codeMethodInvokeExpression = new CodeMethodInvokeExpression();

            codeMethodInvokeExpression.Method.TargetObject = new CodeTypeReferenceExpression(typeof(Resources14ExpressionBuilder)); ;

            codeMethodInvokeExpression.Method.MethodName = "GetLocalizedResource";

            codeMethodInvokeExpression.Parameters.Add(new CodePrimitiveExpression(entry.Expression));

            return codeMethodInvokeExpression;

        }

 

        public override bool SupportsEvaluate

        {

            get { return true; }

        }

 

        public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)

        {

            return GetLocalizedResource(entry.Expression);

        }

 

        public static String GetLocalizedResource(String key)

        {

            return SPUtility.GetLocalizedString("$Resources:" + key, null, SPContext.Current.Web.Language);

        }

 

 

}

 

La méthode GetCodeExpression est appelée lorsque ASP.NET parse l’expression builder. Une chose importante à savoir est que cette méthode renvoie une expression (au sens CodeDom) qui sera récupérée et mise en cache pour chaque entrée (ce qui est après le caractère ‘:’) différente. L’expression mise en cache sera par contre évaluée à chaque fois que l’expressionbuilder sera parsé sur une page.. Il est donc important que GetCodeExpression soit “language agnostic”, et retourne une référence à une méthode qui elle, tiendra compte de la langue. Ici, GetCodeExpression renvoie une sorte de pointeur vers la méthode GetLocalizedResource.

 

Modification du web.config

 

Afin de pouvoir consommer l’expression builder dans nos développements, il est nécessaire qu’il soit enregistré dans le web.Config.

Pour ce faire, on doit ajouter un noeud dans la section expressionBuilders comme ci-dessous :

 

image

Pour bien faire, il faudra faire cet enregistrement par code en utilisant la classe SPWebConfigModification afin d’être certain que la modification soit effectuée de la même manière sur tous les frontaux de la ferme.

Ci dessous un exemple d’implémentation du feature receiver d’une feature de scope web app :

public class WebApp_RegisterExpressionBuilderEventReceiver : SPFeatureReceiver
{
 
        private const String OWNER = "ANO.Resources14_WebApp_RegisterExpressionBuilderEventReceiver";
 
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPWebApplication webapp = properties.Feature.Parent as SPWebApplication;
 
            //Cleanup
            RemoveWebConfigEntries(webapp, OWNER);
 
            //Adds the expressionBuilder
            SPWebConfigModification mod = new SPWebConfigModification();
            mod.Path = "configuration/system.web/compilation/expressionBuilders";
            mod.Name = "add[@ expressionPrefix='Resources14']";
            mod.Sequence = 1;
            mod.Owner = OWNER;
            mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            mod.Value = String.Format(@"<add expressionPrefix=""Resources14"" type=""{0}"" />", typeof(Resources14ExpressionBuilder).AssemblyQualifiedName);
 
            //registers the web.config modification to the web app
            webapp.WebConfigModifications.Add(mod);
            webapp.Update();
 
            //updates the web.config on each front end
            SPWebService.ContentService.ApplyWebConfigModifications();
        }
 
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWebApplication webapp = properties.Feature.Parent as SPWebApplication;
 
            //Removes the expression builder registration from the web.config
            if (RemoveWebConfigEntries(webapp, OWNER))
                SPWebService.ContentService.ApplyWebConfigModifications();
        }
 
        private static Boolean RemoveWebConfigEntries(SPWebApplication webapp, String owner)
        {
            Boolean updated = false;
 
            //Modifications to remove
            List<SPWebConfigModification> modsToRemove = new List<SPWebConfigModification>();
 
            //Identifies modifications to remove
            foreach (SPWebConfigModification mod in webapp.WebConfigModifications)
                if (mod.Owner == owner)
                    modsToRemove.Add(mod);
 
            //Removes modifications one by one
            foreach (SPWebConfigModification mod in modsToRemove)
            {
                webapp.WebConfigModifications.Remove(mod);
                updated = true;
            }
 
            //Updates if necesssary
            if (updated)
                webapp.Update();
 
            return updated;
        }

}

Une fois cette feature déployée et activée sur une web app, on peut consommer notre expression builder.

Utilisation de l’expression builder

On peut maintenant utiliser notre expression builder dans les pages aspx et les controles ascx de notre projet.

Exemple :

image

Résultat :

image

Conclusion

L’utilisation de cette méthode nécessite un développement spécifique qu’il faudra embarquer dans les sources du projet, mais il me parait intéressant de le faire pour les raisons suivantes :

  • Un seul jeu de resx à maintenir, et à faire traduire
  • Plus besoin de se demander dans quel resx doit aller un libellé
  • Plus de problématique de déploiement spécifique aux resx qui doivent aller dans le répertoire App_GlobalResources de la web app
  • Gain de temps notable durant la phase de développement, vis à vis de la problématique de déploiement 
  • Si vous souhaitez récupérer les sources du projet, elles devraient téléchargeables être en pièce jointe de ce post : ANO.Resources14.zip


    Arnault Nouvel
    MVP SharePoint Server


    Classé sous ,
    Attachment(s): ANO.Resources14.zip

    [SharePoint 2010] Image Field Upload

    Microsoft SharePoint Server 2010

    Dans un projet de publishing dans SharePoint, les utilisateurs remontent parfois un problème d’ergonomie sur les contrôles champs de type image. En effet, lorsque l’on clique sur le lien de sélection d’image, cela affiche une popup permettant la sélection d’une image existante. Il n’y a pas de moyen par défaut de télécharger directement une image à partir de l’ordinateur.

    J’ai développé un script jQuery permettant de combler ce manque. Une fois enregistré dans la master page du site, tous les champs images proposent un 2ème lien qui permet à l’utilisateur de sélectionner une image sur son disque dur. Celle-ci sera uploadée automatiquement dans la bibliothèque SharePoint de son choix, puis affichée à l’emplacement désiré.

    En images :

    3.EditPage

    4.UploadImage

    5.ResizeImage

    Très facile à mettre en place, ce script peut être installé par un administrateur de collection de sites.

    J’ai publié ce script sur CodePlex sous le nom de “SharePoint 2010 Image Field Upload”. Pour le télécharger, suivez ce lien : http://spimagefieldupload.codeplex.com


    Arnault Nouvel
    MVP SharePoint Server

    Classé sous ,

    [SharePoint 2010] Site internet et performances : poids et nombre des ressources

    Microsoft SharePoint Server 2010

    Un site internet hébergé sur SharePoint 2010, c’est bien. Si il s’affiche vite, c’est mieux!

    Introduction

    Lorsque l’on travaille sur les performances dans le cadre d’une application web, SharePoint ou non, il y a 3 phases à prendre en compte :

    • Le temps que les pages mettent à être générées côté serveur
    • Le temps mis par le navigateur pour télécharger la page (html) et les ressources qui y sont référencées (css, js, images..)
    • Le temps mis par le navigateur pour afficher la page et exécuter les éventuels scripts d’initialisation

    A l’heure où la mamie du cantal découvre les joies du surf sur son Smartphone, le développeur doit s’assurer que son site internet s’affichera avec des performances acceptables malgré d’éventuels problèmes de bande passante.

    Nous allons aujourd’hui faire un focus sur l’optimisation des performances d’un site internet SharePoint 2010 vis à vis de la 2ème phase, le téléchargement des ressources. Les 2 facteurs principaux sont le poids, mais aussi et surtout le nombre de fichiers référencés.
    Nous allons donc voir comment réduire le poids et le nombre des fichiers ressources référencés dans nos pages.

    1. Réduire le poids des ressources

    Page et ViewState

    Dans la plupart des cas le poids de la page est négligeable comparé au poids des ressources.
    Par exemple la page d’accueil du site http://www.ca-ifcam.fr pèse 17Ko, pour un total de 660Ko si on ajoute les images, scripts et autres ressources qu’elle référence.

    Attention toutefois au ViewState ASP.NET qui est activé par défaut sur tous les contrôles de la page. Il peut faire grossir considérablement le poids des pages si on n’y prête pas attention.
    Sur un site internet, il n’y a en principe pas ou peu de raison de faire des retours serveur (PostBack), et donc pas de raison de laisser le ViewState activé.
    Pour désactiver le ViewState sur les contrôles où il n’est pas nécessaire, on utilisera l’attribut EnableViewState.

    image

    Pour plus d’information sur le ViewState, je vous redirige vers la MSDN : Understanding ASP.NET View State

    Compression des ressources CSS et JavaScript

    Une optimisation incontournable est la compression des fichiers référencés, en particulier les fichiers CSS et JavaScript.

    Dans le cadre du site internet IFCAM, nous avons utilisé la librairie YUI Compressor de Yahoo ou plutôt son portage en .NET que l’on peut télécharger librement sur CodePlex : Yahoo! UI Library: YUI Compressor for .Net.
    Cette implémentation propose notamment des tâches MSBuild permettant d’automatiser la compression des fichiers lors des builds.

    YUI Compressor réduit le poids des CSS et des fichiers JavaScript en supprimant les espaces, commentaires, en réduisant le nombre de caractère des noms de variables, et en faisant d’autres optimisations issues de l’analyse de chaque fichier.
    Le gain est significatif :

    image

    image

    Dans notre solution Visual Studio, tous les fichiers css et js existent en version originale (*.debug.css et *.debug.js) et en version compressée (*.css et *.js). On régénère les versions compressées à partir des versions originales avant chaque compilation en mode release.
    Pour travailler confortablement, nous avons développé un contrôle spécifique pour référencer les feuilles de style css. Il référence dynamiquement la version debug ou compressée d’un fichier en fonction de la variable de compilation DEBUG.

    Code source du contrôle épuré pour meilleure lisibilité :

    image

    On le positionne dans la balise head de la master page :

    image

    Cela permet de travailler normalement durant la phase de développement (fichiers originaux debug.css), et d’être sûr que c’est la version compressée qui sera référencée sur l’environnement de production, puisque nous livrons toujours des packages compilés en mode release..

    Pour le référencement des fichiers JavaScript, pas besoin de développement spécifique. Il est possible d’utiliser le contrôle ScriptLink de l’API SharePoint qui fonctionne selon le même principe.
    Je vous invite à consulter le post de Wictor Wilen qui détaille bien cette approche : http://www.wictorwilen.se/Post/Minifying-custom-JavaScript-files-in-SharePoint-2010.aspx

    2. Réduire le nombre des ressources

    D’un point de vue expérience utilisateur, l’optimisation la plus significative est de limiter le nombre de fichiers référencés. Le navigateur fera moins d’allers-retours avec le serveur, et affichera donc la page plus vite. Nous allons voir deux méthodes pour réduire le nombre de fichiers référencés : une qui est valable pour toutes les applications web puisqu’elle concerne les images, et une autre spécifique à SharePoint..

    Regroupement des images avec CSS Sprites

    Le concept de CSS Sprites consiste à mettre plusieurs images côte à côte dans un seul fichier image. On réutilise alors cette image sur tous les boutons de la page et pour chacun d’entre eux on utilise le positionnement CSS pour afficher la partie de l’image qui lui correspond. On notera que ce concept est déjà utilisé par SharePoint pour regrouper dans une seule image toutes les icônes des boutons du ruban.

    Pour l’exemple, voici une image construite en CSS Sprite qui regroupe une vingtaine d’images (cliquez pour agrandir) :

    bg-blocks

    Et la voici utilisée sur la page d’accueil du site IFCAM :

    image

    Grâce à ce système, on fait l’économie d’une vingtaine d’allers-retours serveur ce qui permet un affichage bien plus rapide de la page dans le navigateur. Cela n’économise pas de bande passante, mais permet d’éviter au navigateur d’établir une connexion par image, ce qui prendrait un temps significatif et potentiellement plus long que les téléchargements eux-mêmes. On notera d’ailleurs que les navigateurs ne doivent pas établir plus de 2 connexions simultanées avec un même serveur (RFC 2616), ce qui empêche de télécharger toutes les images d’une page en parallèle. Sans CSS sprite, les images doivent donc être téléchargées les unes après les autres ce qui ralentit l’affichage.

    Un autre avantage du CSS sprite c’est que si l’image “mouse over” d’un bouton est inclue dans la même image que l’originale, il suffit de jouer sur le positionnement en conservant la même image lors du survol de la souris, ce qui est instantané.

    A première vue, cela parait complexe à mettre en œuvre mais en utilisant un bon outil, c’est facile.
    On en trouve beaucoup sur internet, mais j’ai une préférence Sprite Me qui permet de générer les images et les css à l’aide d’un bookmarklet.
    Je vous invite à essayer la démo sur le site http://spriteme.org, l’essayer c’est l’adopter.

    Déréférencement des fichiers spécifiques SharePoint

    Voici maintenant une méthode spécifique SharePoint. Par défaut dans SharePoint 2010, un grand nombre de fichiers JavaScript et CSS sont référencés. Ceux-ci n’ont pas tous d’intérêt dans le cadre d’un site internet, comme par exemple ceux qui permettent le fonctionnement du ruban. En effet sur un site internet, on n’affiche pas le ruban. On notera aussi que ces fichiers sont particulièrement volumineux.

    Dans le cas du site IFCAM, nous souhaitions que pour les internautes, le ruban ne soient pas affiché. Dans ce cas, nous ne voulions pas non plus référencer les CSS systèmes de SharePoint ni les fichiers JavaScript du ruban.

    La solution que nous avons retenu est implémentée en 2 parties.

    Premièrement nous avons encapsulé certaines références explicites dans notre contrôle spécifique AuthenticatedUserPlaceHolder dont j’avais parlé dans le billet SharePoint 2010 : Masquer le ruban sur un site internet. Ainsi si l’utilisateur est anonyme, les CSS "système" de SharePoint ne seront pas référencées.

    image

    Lors de l’affichage de la page d’accueil du site IFCAM en anonyme, cette méthode permet d’économiser le téléchargement de controls.css (10Ko) et de corev4.css (30Ko).

    Deuxièmement, nous souhaitions nous débarrasser de certains fichiers JavaScript inutiles pour un site internet tels que cui.js, core.js, et SP.Ribbon.js. Ces fichiers ont la particularité d’être référencés dynamiquement via une technique de lazy loading.
    Malheureusement jusqu’à peu, la seule méthode connue pour empêcher leur référencement dans les pages consistait en une méthode peu esthétique et non supportée à base de System.Reflection, Celle-ci est détaillée dans le billet de Chris O’Brien : Eliminating large JS files to optimize SharePoint 2010 internet sites.

    Il y a quelques jours, les ingénieurs de l’équipe produit de SharePoint ont révélé une manière supportée de parvenir au même résultat, Il suffit d’utiliser une méthode JavaScript non documentée prévue à cet effet.
    Merci à Pierrick pour le lien : Supported way of eliminating (large) JS files for SharePoint 2010
    L’astuce consiste à enregistrer cette petite instruction JavaScript en bas de page pour que les fichiers JavaScript en question ne soient pas téléchargés :

    <script type='text/javascript'>SP.SOD.set_prefetch(0);</script>

    Simple, et tout aussi efficace. En pratique, on l’encapsulera bien sur dans un contrôle serveur pour qu’elle ne soit exécutée que dans les cas où on n’a pas besoin des fichiers JavaScript qu’elle empêche de télécharger.

    Ci-dessous les métriques pour la page d’accueil prises à l’instant dans ma machine virtuelle de développement.

    Sans l’instruction JavaScript :

    image

    Avec l’instruction JavaScript:

    image

    On observe une différence de 15 fichiers, représentant 140Ko.

    Conclusion

    Nous avons vu dans ce billet comment le développeur peut améliorer les performances d’un site internet SharePoint en réduisant le poids des fichiers référencés ainsi que leur nombre.
    Pour des performances optimales, l’administrateur aura aussi son rôle à jouer : n’oubliez pas de configurer le BlobCache et le cache de sortie.


    Arnault Nouvel
    MVP SharePoint Server

    [SharePoint 2010] Site internet et performances : le developer dashboard

    sharepoint-server

    Dans les billets précédents, nous avons vu comment optimiser les performances d’un environnement SharePoint 2010 qui héberge un site internet grâce au BlobCache et au cache de sortie, . Nous allons voir aujourd’hui comment faire apparaitre le developer dashboard dans le cadre d’un site internet pour diagnostiquer les problèmes de performances liés au code serveur.

    Apparu avec SharePoint 2010, le developer dashboard fourni une interface de monitoring des performances directement dans les pages SharePoint. Il est très utile lorsque l’on cherche à optimiser les performances du code serveur de l’application. Une API permet notamment d’y afficher des informations à propos de notre propre code, en particulier la durée d’exécution de portions de code ainsi que des détails sur d’éventuelles exceptions gérées. Je vous invite à consulter l’article de Paul Andrew pour plus de détails sur cette API.

    Dans ce billet, nous allons nous intéresser à la manière de le faire apparaitre sur un site internet, dont les particularités sont la connexion anonyme et l’absence de ruban.

    Autoriser l’affichage du developer dashboard pour les utilisateurs anonymes

    Sur un site internet, l’authentification est anonyme. Par défaut, le developer dashboard (et le bouton OnDemand associé) ne s’affiche que si l’utilisateur courant bénéficie de la permission AddAndCustomizePages, qui n’est pas attribuée aux utilisateurs anonymes. Il est toutefois possible d’afficher le developer dashboard en modifiant le niveau de permission requis.

    Voici le script PowerShell que j’utilise :

    Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue 
    
    $contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
    $dds = $contentService.DeveloperDashboardSettings
    $dds.DisplayLevel = "OnDemand"
    $dds.TraceEnabled = $true;
    
    #pour le rendre actif en mode anonyme
    $dds.RequiredPermissions = [Microsoft.SharePoint.SPBasePermissions]::EmptyMask
    
    #pour remettre le niveau de droit par défaut
    #$dds.RequiredPermissions = [Microsoft.SharePoint.SPBasePermissions]::AddAndCustomizePages
    
    $dds.Update()
    

    Affichage OnDemand sans bouton

    La plupart du temps, et c’est le cas avec le script ci-dessus, je préfère configurer le developer dashboard en mode "OnDemand" qui permet de ne l’afficher qu’en cas de besoin, en appuyant sur un bouton dédié dans le ruban. Mais sur un site internet SharePoint, en général on masque le ruban, et donc le bouton. 

    L’astuce pour afficher le developer dashboard lorsque le bouton n’est pas visible, c’est d’ajouter developerdashboard=true dans la query string de l’url.

    Par exemple : http://mon_site_internet/Pages/accueil.aspx?developerdashboard=true

    image


    Arnault Nouvel
    MVP SharePoint Server

    [SharePoint 2010] Site internet et performances : le cache de sortie

    Nous avons vu précédemment comment le BlobCache pouvait nous aider à gérer la mise en cache des fichiers de ressources (images, javascript, css, etc.). Dans ce billet, nous allons discuter de l’utilité du cache de sortie (ou Output Cache en anglais), qui permet de mettre en cache le code HTML rendu par les pages .aspx.

    Certains articles sur internet détaillent toutes les facettes de cette fonctionnalité, en particulier celui de Fabrice : SharePoint Output Caching dans un site Intranet. Je ne vais donc parler aujourd’hui que de son utilisation dans le cadre spécifique d’un site internet, tel que mis en place sur le site http://www.ca-ifcam.fr.

    Bref rappel de l’objectif de cette fonctionnalité : par exemple si 2 utilisateurs affichent la page d’accueil du site à quelques secondes d’intervalle, le cache de sortie va permettre de renvoyer le même rendu HTML au 2ème utilisateur sans avoir à tout recalculer (menus de navigation, contenu des web parts, etc.). Cela permet de soulager le serveur frontal ainsi que le serveur SQL, et d’obtenir des temps de réponse quasi instantanés sur les pages mises en cache.

    Sans cache de sortie :

    image

    Avec cache de sortie, au 2ème appel :

    image

    Le cache de sortie se configure par l’administrateur de la collection de sites si le fonctionnalité de site de publication est activée. Actions du site > Paramètres du site > Cache de sortie de la collection de sites.

    image

    Dans cet écran nous avons la possibilité d’activer le cache de sortie, et de choisir un profil de cache différent pour les utilisateurs anonymes et les utilisateurs authentifiés. Cette différenciation est utile puisque par définition les utilisateurs anonymes voient tous une page de la même manière alors que les utilisateurs authentifiés peuvent avoir un rendu différent selon leurs droits respectifs, et leur appartenance à des audiences, etc. On souhaitera donc gérer le cache d’une manière différente pour les utilisateurs authentifiés, ou pas du tout.

    Chaque profil de cache définit si le cache est actif et l’ensemble des paramètres qui permettent de déterminer si une page peut être servie à partir du cache ou non.

    Par défaut il en existe 4 :

    • Désactivé
    • Internet public
    • Intranet
    • Extranet

    Il est possible de les modifier et d’en créer de nouveaux, puisqu’en en pratique il s’agit d’une liste SharePoint cachée. Pour accéder à cette liste : Actions du site > Paramètres du site > Profils de cache de la collection de sites.

    image

    Dans le cas d’un site internet, le profil de cache anonyme le plus adapté est "Internet public (purement anonyme)".

    image

    Le profil "Internet public (purement anonyme)" propose le niveau de cache maximum. Il ne prend pas en compte les différences de droits entre les utilisateurs, ni des éventuelles modifications sur le site. Puisque tous les utilisateurs anonymes doivent voir le même contenu dans les pages, ce profil de cache est parfaitement adapté pour l’authentification anonyme.

    On notera que "Variation par paramètre personnalisé" a pour valeur "Browser", ce qui veut dire que si une page a été servie à un visiteur disposant d’un certain navigateur, puis mise en cache, cette version de la page ne sera pas resservie telle-quelle à un autre visiteur si il a un navigateur différent. Pour chaque navigateur différent (ou de version différente), une copie d’une même page sera mise en cache.

    Les paramètres intéressants à modifier dans le cadre d’un site internet :

    • Par défaut ce profil de cache a une durée de 180 secondes, il peut être utile d’augmenter cette valeur. On gardera cependant à l’esprit que chaque page mise en cache consomme de la mémoire vive.
    • Certains composants graphiques, notamment les web parts, peuvent dépendre de paramètres dans l’url (query string). C’est le cas par exemple de la web part des résultats de recherche catalogue du site http://www.ca-ifcam.fr. Si vous en disposez sur votre site, il peut être intéressant d’indiquer le nom de ces paramètres dans le champ "Variation par paramètres de chaines de requête" séparés par des point-virgules, ou tout simplement mettre la valeur * pour qu’ils soient tous pris en compte.

    Conclusion

    Tout comme le BlobCache, le cache de sortie est incontournable pour obtenir de meilleures performances sur un site internet réalisé en SharePoint 2010. Activé par un administrateur de la collection de sites, il est à la fois facile à mettre en place et très efficace : la charge serveur est diminuée et les pages mises en cache sont retournées quasi-instantanément.

    Nous verrons dans le prochain billet comment un développeur peut encore améliorer les performances d’un site internet sous SharePoint 2010.


    Arnault Nouvel
    www.winwise.com

    [SharePoint 2010] Site internet et performances : le BlobCache

    Un nouveau site internet réalisé en SharePoint 2010, et développé par Winwise, vient d’apparaitre sur la toile : http://www.ca-ifcam.fr.
    Pour introduire brièvement ce projet, ce site a pour vocation principale d’exposer un catalogue de formation aux salariés du groupe Crédit Agricole. Les plus curieux trouveront la partie la plus intéressante via la recherche catalogue. Passons maintenant au retour d’expérience !

    De bonnes performances sont essentielles au succès d’un site internet. Pour les obtenir, nous verrons dans une série de billets qu’il est possible d’intervenir à plusieurs niveaux. L’administrateur, le développeur, et même les auteurs de contenu ont un rôle à jouer. Commençons par le BlobCache, qui peut être activé par l’administrateur.

    Disponible nativement dans SharePoint, le BlobCache est un mécanisme de cache de ressources qui s’avère particulièrement efficace dans le cadre d'un site internet. Il permet de mettre en place à la fois du cache serveur et du cache client. Dans ce billet nous allons voir en quoi consiste le BlobCache, puis comment le configurer.

    Le cache serveur

    Par défaut (sans BlobCache) lorsqu'un fichier de ressource stocké dans une bibliothèque SharePoint est demandé, le serveur frontal récupère systématiquement le fichier en base de données et le renvoie au client. Prenons par exemple le cas d’un logo affiché sur plusieurs les pages d’un site, ou d’une feuille de style CSS référencée dans toutes les pages. Ces ressources étant demandées très fréquemment et n’étant pas amenées à changer souvent, il est dommage de solliciter le serveur SQL pour les récupérer à chaque fois qu’un utilisateur les demande.

    Une fois activé, le BlobCache permet de résoudre ce problème : après avoir récupéré une ressource en base de données, le serveur frontal conserve le fichier sur son disque dur. Ce fichier est ensuite servi aux utilisateurs lors des requêtes suivantes directement depuis le disque dur, sans avoir à refaire un aller-retour avec le serveur SQL. Cela permet de limiter considérablement le nombre de connexions entre les serveurs frontaux et le serveur SQL. En terme de performances, on gagne donc en charge sur le serveur SQL, et en temps de réponse pour récupérer les ressources si elles sont déjà en cache.

    Le cache client

    L'activation du BlobCache a un 2ème intérêt, moins connu mais tout aussi important en terme de gain de performances puisqu'il permet de limiter les aller-retours entre le navigateur client et le serveur frontal.

    Nous allons mettre en évidence le gain de performances avec un de mes outils préférés, HTTP Watch Professionnal. Pour ce faire, nous allons requêter 2 fois de suite une image située dans une bibliothèque SharePoint, et analyser les entêtes HTTP des requêtes et des réponses. Sur chaque capture d’écran on peut voir à gauche la requête, et à droite la réponse.

    Sans BlobCache

    clip_image001

    Lors du premier appel, la réponse indique Cache-Control : private,max-age=0. Cela indique au navigateur qu’il ne peut pas mettre cette image en cache. L’image sera toutefois conservée dans les fichiers internet temporaires.

    sans-blob-cache-2

    Lors du 2ème appel, le navigateur demande l'image en précisant qu'il en dispose déjà d’une version dans ses fichiers temporaires, en passant la date de celle-ci (champ if-modified-since) dans le header de la requête HTTP. Le serveur constatant que l'image n’a pas été modifiée depuis cette date, il renvoie une réponse 304 qui indique au navigateur que l’image n’a pas besoin d’être re téléchargée. L’image stockée dans les fichiers temporaires va donc être réutilisée.

    L’image n’est pas re-téléchargée lors du 2ème appel, mais il y a tout de même eu un aller-retour serveur qui a un cout en terme de performances.

    Avec BlobCache

    clip_image003

    Lors du premier appel, la réponse indique Cache-Control : public,max-age=86400. Cela indique au navigateur qu’il peut conserver la ressource en cache et la réutiliser pendant 86400 secondes (24 heures).

    clip_image004

    Lors du 2ème appel, aucune requête n'est effectuée vers le serveur. En effet puisqu’elle a été mise en cache il y a moins de 24 heures, le navigateur sait qu'il peut réutiliser l'image sans se poser de question, et surtout sans en poser au serveur Sourire

    Le BlobCache nous permet donc d’économiser un aller-retour serveur à chaque fois qu’une ressource est redemandée !

    Voyons maintenant comment l’activer. 

    Activation du BlobCache

    Le BlobCache peut être activé par un administrateur de la ferme en modifiant le web.config de l'application sur chaque serveur frontal de la ferme.

    Il se configure au niveau de l'élément <BlobCache /> qui est présent par défaut :

    <BlobCache location="C:\BlobCache\14" path="\.(gif|jpg|jpeg|jpe|jfif|bmp|dib|tif|tiff|ico|png|wdp|hdp|css|js|asf|avi|flv|m4v|mov|mp3|mp4|mpeg|mpg|rm|rmvb|wma|wmv)$" maxSize="10" enabled="false" />

    Les attributs sont les suivants :

    • L'attribut Location permet de définir le répertoire dans lequel seront conservés les fichiers sur le serveur.
    • L'attribut maxSize permet de définir, en Go, l'espace disque que peut occuper le BlobCache.
    • L'attribut path permet de définir les extensions des fichiers que doit prendre en charge le BlobCache. On peut ici ajouter d’autres extensions.
    • L'attribut enabled permet d'activer ou de désactiver le BlobCache.
    • Enfin, on peut ajouter un attribut max-age qui n'est pas présent par défaut. On y donne une valeur en seconde de la durée de mise en cache.

    Pour activer le BlobCache sur une application web, il faut donc de modifier la valeur de l'attribut enabled dans les web.config de chaque frontal de la ferme.

    Exemple :

    <BlobCache location="C:\BlobCache\14" path="\.(gif|jpg|jpeg|jpe|jfif|bmp|dib|tif|tiff|ico|png|wdp|hdp|css|js|asf|avi|flv|m4v|mov|mp3|mp4|mpeg|mpg|rm|rmvb|wma|wmv)$" maxSize="10" enabled="true" max-age="592200" />

    Conclusion

    Dans ce billet nous avons vu comment améliorer les performances d'une application SharePoint en mettant en place le BlobCache.

    Celui-ci permet de réduire la charge sur le serveur SQL et sur le serveur Frontal, tout en limitant le nombre de requête effectuée par le navigateur, améliorant donc l'expérience utilisateur. Dans le cadre d'un site internet hébergé sous SharePoint 2010, le BlobCache est incontournable.

    Nous verrons dans le prochain billet comment améliorer encore les performances grâce au cache de sortie.

    Arnault Nouvel – Winwise

    SharePoint 2010 : Performances d’un serveur SharePoint sans accès internet

    Sur un serveur SharePoint, l’absence d’accès à internet peut avoir un lourd impact sur les performances.  En effet pour diverses raisons, ASP.NET et SharePoint vérifient la validité de certaines informations et certificats sur les serveurs de Microsoft. Cela se traduit par des tentatives de connexion à crl.microsoft.com (modes classic et claims) et www.download.windowsupdate.com (claims uniquement) pendant l’exécution de l’application.

    Après avoir mis en évidence la problématique, nous allons voir comment désactiver les mécanismes qui provoquent des connexions vers internet. Nous retrouveront alors des performances optimales.

    Mise en évidence du problème

    Les tests qui vont suivre ont été réalisés sur une machine virtuelle de développement Windows 2008 R2 embarquant à la fois un Active Directory, un serveur SQL, et un SharePoint Server 2010. Un IISRESET est effectué avant chaque mesure, une mesure correspondant au temps d’affichage de la page d’accueil d’un site d’équipe.  Pour bien mettre en évidence les problématiques liées au mode claims, chaque test est effectué dans les 2 modes. Les mesures des temps de réponses ont été prises avec HttpWatch Professional.

    Afin d’établir un référentiel, je commence par prendre des mesures en conservant un accès internet sur le serveur :

    image
    Web App en mode classic avec accès internet : 10.6 secondes

    image
    Web App en mode claims avec accès internet : 15.2 secondes

    Après avoir coupé l’accès internet, je ré effectue le même test :

    image
    Web App en mode classic sans accès internet : 42.3 secondes

    image
    Web App en mode claims sans accès internet : 57.8 secondes

    Le temps de chargement est donc multiplié environ par  4. Edifiant n’est-ce pas ?

    Ces latences sont dues au fait que le serveur tente de se connecter à divers services sur internet. En l’absence d’accès à internet, ces tentatives de connexions génèrent des timeout qui ralentissent l’exécution des applications.

    Dans un scénario de développement, la baisse de productivité est significative puisque le développeur attend inutilement 30 à 45 secondes à chaque fois qu’il appuie sur F5 pour déployer de son projet.

    Dans un scénario de production, on ne recycle pas les application pool aussi fréquemment, le problème parait donc moins gênant. Toutefois en cas d’authentification par formulaire (mode claims), une demande d’authentification peut prendre plusieurs secondes. Sur un portail extranet que j’ai étudié récemment, un utilisateur attendait systématiquement 15 secondes après avoir validé la saisie de son login et de son mot de passe, sans raison apparente, avant d’être authentifié par le serveur.

    Nous allons voir que les connexions initiées par un serveur SharePoint ont 2 origines : la vérification des signatures des assemblii (en modes classic et claims), et la récupération d’une mise à jour des certificats racines (en mode claims uniquement).

    Vérification des signatures des assemblii (modes classic et claims)

    La vérification des signatures d’assemblii concerne Code Access Security (CAS) et est propre aux applications ASP.NET. Il s’agit d’un comportement bien connu qui existe aussi sur les environnements SharePoint 2007. Lors du chargement d’assemblii signées (celles du Framework.NET par exemple), des requêtes vers crl.microsoft.com sont faites par IIS pour en vérifier les signatures.

    En cas d’absence d’accès internet, il est légitime de désactiver cette vérification en effectuant une modification dans le fichier machine.config situé dans le répertoire C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG. Une fois le fichier ouvert, localiser le noeud <runtime /> et le modifier comme ceci :

    <runtime>

       <generatePublisherEvidence enabled="false" />

    </runtime>

    Après enregistrement, reprenons les mesures :

    image
    Web app en mode classic : 9.4 sec

    image
    Web app en mode claims : 25.4 sec

    On remarque qu’en mode classic, on a d’encore meilleures performances qu’avec un accès internet. C’est logique puisque le mécanisme de vérification des signatures d’assemblii est entièrement désactivé. On économise un peu de temps CPU et surtout des connexions réseau.

    Mais en mode claims, il y a toujours une latence qui semble injustifiée.

    Mise à jour des certificats racines (mode claims)

    Le Developer Dashboard permet d’identifier l’origine du problème. Pour la mesure prise précédemment (25.4s), il affiche ceci :

    image

    On constate que les 11.5 secondes "injustifiées" sont consommées au niveau de la méthode SPCertificateValidator.Validate(). Le rôle de cette méthode est de vérifier la validité du certificat utilisé pour chiffrer les communications avec le Security Token Service (STS). 

    On trouve le certificat du STS dans le magasin "Local Computer\SharePoint".

    image

    On remarque que ce certificat est généré par une autorité de certification "SharePoint Root Authority". Malheureusement, cette autorité de certification ne fait pas partie des certificats racines trustés nativement par Windows (les Trusted Root Certificates). SharePoint étant une application, il serait injustifié qu’il en fasse partie.

    image

    Puisqu’il ne fait pas partie des Trusted Root Certificates, Windows cherche à récupérer une liste à jour des certificats racines afin de vérifier la validité du certificat avec des informations à jour. 
    Analysé avec Network Monitor, une tentative de connexion vers http://download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab est effectuée pour essayer de récupérer cette mise à jour.

    En l’absence d’accès à internet sur le serveur, c’est ici qu’apparait le timeout.

    Il est toutefois possible de désactiver cette mise à jour automatique, en suivant cette procédure :

    • Sur le serveur, executer gpedit.msc
    • Aller à Computer Configuration –> Windows Settings –> Security Settings –> Public Key Policies
    • Afficher les propriétés de "Certificate Path Validation Settings"
    • Dans l’onglet "Network Retrieval", cocher "Define this policy" et décocher "Automatically update certificates in the Microsoft Root Certificate Program"
    • Valider, puis exécuter "gpupdate /force" en ligne de commande pour appliquer les modifications

    image

    Après avoir effectué cette modification, on retrouve des mesures optimales, meilleures que celle prises initialement avec un accès internet.

    image
    Web app en mode claims : 13.9 sec

    On notera aussi que le Developer Dashboard ne signale plus de latence au niveau de la méthode de vérification du certificat :

    image

    A ce stade, le serveur n’effectue plus de connexion vers internet en rapport avec l’exécution de SharePoint.


    Arnault Nouvel
    www.winwise.com

    SharePoint 2010 : Masquer le ruban sur un site internet

    sharepoint-server

    Lorsque l’on utilise SharePoint 2010 pour héberger un site internet, une des premières tâches est l’intégration de la charte graphique. Dans la plupart des cas, le ruban ne devra pas apparaitre pour les internautes. Voyons une implémentation possible pour le masquer proprement.

    Une particularité d’un site SharePoint par défaut est qu’en cas de scroll vertical, ce n’est pas la scrollbar du navigateur qui apparait, mais celle d’une div qui contient toute la page sauf le ruban. Cela permet notamment de conserver les boutons d’édition de texte même lorsque l’on édite le bas de la page. Cette zone scrollable est redimensionnée dynamiquement par script en fonction de la hauteur du ruban qui peut varier selon l’onglet sélectionné, et de la hauteur du navigateur qui peut être changée à la volée par l’utilisateur.  Ce script qui contrôle la zone scrollable en temps réel causes des problèmes sur certains navigateurs, en particulier Safari et ses dérivés mobiles.

    image

    On trouve sur internet plusieurs approches pour masquer le ruban. Nous allons découvrir aujourd’hui celle implémentée il y a un an déjà sur le site www.oddo.fr, et que je réutilise aujourd’hui dans le cadre d’un autre site internet.

    L’objectif

    Afin de bien comprendre le principe, sachez que l’application web qui héberge le site est accessible en mode authentifié pour les auteurs et en mode anonyme pour les internautes.

    Concernant la solution envisagée, l’idée est que si l’utilisateur est anonyme, il s’agit d’un internaute et le ruban ne doit donc pas apparaitre. Dans ce cas, il n’y a pas de raison d’utiliser une div scrollable au lieu de la scrollbar de la fenêtre du navigateur.

    Afin d’en simplifier l’implémentation, j’ai redéfini mon objectif comme ceci :

    • Par défaut (et donc pour les utilisateurs anonymes) : masquer le ruban, activer la scrollbar du navigateur, désactiver la scrollbar de la div principale
    • Si l’utilisateur est authentifié (auteur du site) : afficher le ruban, désactiver la scrollbar du navigateur, activer la scrollbar de la div principale

    Les 3 composantes techniques de l’implémentation sont :

    • 1 contrôle dont le contenu ne s’affiche que si l’utilisateur connecté est authentifié. Celui-ci encapsulera le contrôle serveur du ruban et une surcharge CSS.
    • 1 règle CSS par défaut qui annule la div scrollable, et active les scrollbars du navigateur
    • 1 surcharge CSS qui réactive la zone scrollable uniquement si le ruban est affiché

    Le contrôle graphique AuthenticatedUserPlaceHolder

    Dans le projet, on crée le contrôle graphique suivant :

    public class AuthenticatedUserPlaceHolder : PlaceHolder

    {

        protected override void OnInit(EventArgs e)

        {

            //On n'affiche ce contrôle (et donc son contenu) que si l'utilisateur est authentifié

            this.Visible = HttpContext.Current.User.Identity.IsAuthenticated;

        }

    }

     

    Update : Selon le besoin initial, utiliser les contrôles SPSecurityTrimmedControl ou LoginView permettrait d’obtenir un résultat équivalent sans avoir à développer de contrôle supplémentaire, voir commentaires en bas du post.

    Règles CSS par défaut

    Dans la balise HEAD de la master page, ou dans la feuille de style principale du projet (préférable), on active la scrollbar du navigateur. Pour simplifier la compréhension, j’inclus ici mes règles CSS directement dans la balise HEAD de la master page :

     

    <head runat="server">

       

        …

     

        <style>

            /* active le scroll au niveau de la fenêtre du navigateur */

            body

            {

                height: 100%;

                overflow: auto;

                width: 100%;

            }

     

            /* supprime les barres de scroll au niveau de la zone scrollable de SharePoint */

            body #s4-workspace{

                   overflow:visible;

                   overflow-x:visible;

                   overflow-y:visible;

            }

        </style>

    </head>

    Attention : sur la balise <body>, un attribut scroll="no" peut empêcher la scrollbar du navigateur d’être affichée par notre règle CSS. S’il est présent, il est nécessaire de le supprimer.

    image

    Si on suit ce tutorial avec la master page V4.master, on supprimera aussi l’attribut class="v4master" qui surchargerait nos règles CSS avec des clauses !important. Sur une master page custom, en principe cette problématique disparait.

    Affichage conditionnel du ruban et des règles CSS associées

    Dans la master page, localiser la div ayant pour identifiant s4-ribbonrow, et l’encapsuler avec notre contrôle AuthenticatedUserPlaceHolder. On ajoutera aussi des règles CSS pour activer la zone scrollable (s4-workspace).

    Voici le résultat attendu :

    <Winwise:AuthenticatedUserPlaceHolder runat="server" >

       

        <style>

                  /* supprime le scroll du navigateur */

                  body{

                        overflow:hidden;

                 }

                

                  /* réactive le scroll de la zone scrollable de SharePoint */

                 body #s4-workspace{

                        overflow-x:auto;

                        overflow-y:scroll;

                 }

        </style>

       

        <div id="s4-ribbonrow" class="s4-pr s4-ribbonrowhidetitle">

            <div id="s4-ribboncont">

                <!-- ribbon starts here -->

                ...

                

            </div>

        </div>

    </Winwise:AuthenticatedUserPlaceHolder>

    Et hop, on obtient un site web internet sans ruban, avec un scrolling fonctionnel, en conservant une expérience utilisateur normale (avec ruban) lorsqu’un utilisateur est authentifié.

    Happy Branding !

    Arnault Nouvel
    www.winwise.com

    SharePoint : Gestion des paramètres applicatifs dans le Property Bag

    sharepoint-server

    Dans la plupart des développements SharePoint, il est nécessaire de stocker des paramètres applicatifs (chemin d’un répertoire temporaire, url d’un web service, clé de série d’un composant tiers, etc.). Le reflexe habituel des diverses équipes que j’ai pu côtoyer est de créer de nouvelles entrées dans la section AppSettings du Web.Config. Je préfère en général utiliser une autre approche que nous allons évoquer aujourd’hui, le property bag.

    Tout d’abord, pourquoi faudrait-il éviter de stocker un paramètre dans le Web.Config ?

    • Déployer le paramètre provoque un redémarrage de l’application web
    • Modifier sa valeur provoque aussi un redémarrage de l’application web
    • La valeur est inaccessible hors du contexte la web application : la central admin, aux SPJobDefinition, scripts PowerShell, etc. ne pourraient pas y accéder de manière directe 
    • Le paramétrage à répliquer sur chaque frontal de la ferme (risque d’erreur de saisie)
    • Problématiques liées aux backup/restore

    Dans SharePoint, la quasi totalité des paramètres se configurent à l’aide l’interface web (centrale admin, ou paramètres du site pour les fonctionnels) ou de lignes de commandes (stsadm ou PowerShell). Il parait donc naturel de faire de même avec les développements spécifiques. Je stocke donc toujours mes paramètres applicatifs dans le property bag.

    Les avantages sont multiples :

    • Les paramètres peuvent être associés à un périmètre précis : Application web, mais aussi ferme, collection de sites, site, liste et élément de liste.
    • Ils peuvent être modifiés sans nécessiter de redémarrage de l'application web
    • Ils sont persisté dans la base de données SharePoint, et sont donc backupés avec
    • Ils sont administrables par interface graphique (dev) ou par ligne de commande PowerShell
    • Les modifications n’ont pas à être faites sur chaque serveur

    Administration par ligne de commande PowerShell

    Afin d’éviter le développement d’une page de configuration pour ces paramètres, on aurait pu proposer une administration avec PowerShell. Voici un exemple qui récupère et redéfinit un paramètre :

    image


     

    Administration avec une interface générique

    Le projet communautaire SharePoint Property Bag Settings permet l’administration de tous les property bags de la ferme depuis l’administration centrale.

    image

    L’interface proposée est générique, efficace, mais réservée aux administrateurs de ferme.

    Téléchargement :

     

    Administration personnalisée avec une interface spécifique

    Pour une interface administration personnalisée, on pourra développer une CustomAction et une page applicative, ou tout simplement une web part. C’est l’approche que j’utilise le plus souvent. En voici un exemple.

    Déclaration de la custom action :

    image

    On obtient alors une nouvelle dans les paramètres du site :

    image

    Page applicative cible :

    image

    Pour la partie graphique de la page, on peut s’inspirer des pages présentes nativement dans 14\TEMPLATE\LAYOUTS, comme SiteNavigationSettings.aspx. Cela permet de conserver le look & feel de SharePoint.

    Enregistrement des données dans le property bag :

    protected void Validate_Click(object sender, EventArgs e)

    {

        if (!Page.IsValid)

            return;

     

        //Récupération du property bag de la collection de sites

        SPPropertyBag properties = Site.RootWeb.Properties;

     

        //Enregistrement des valeurs

        properties["Account_GoogleAnalytics"] = txtGoogleAnalytics.Text;

        properties["Account_ShareThis"] = txtShareThis.Text;

        properties["Search_Site_Url"] = txtSiteSearch.Text;

        properties["Search_Catalog_Url"] = txtCatalogSearch.Text;

        properties["WebService_Catalog_Url"] = txtTrainingWebServiceUrl.Text;

     

        //Persiste les modifications dans la base de données

        properties.Update();

     

        //Redirection vers l'URL source

        SPUtility.Redirect(Web.Url, SPRedirectFlags.UseSource, HttpContext.Current);

    }

    Récupération de la valeur d’un paramètre :

    //Récupération de l'adresse du web service

    String catalogServiceUrl = site.RootWeb.Properties["WebService_Catalog_Url"];

     

     

    Autres alternatives

    Nous avons parlé du web.config, du property bag, mais il existe 2 autres options intéressantes pour le stockage de paramètres : le Hierarchical Object Store, et les listes SharePoint.

    Vous trouverez ici un comparatif de ces 4 techniques  : http://msdn.microsoft.com/en-us/library/ff649798.aspx

     

    Arnault Nouvel
    Winwise


    Classé sous ,

    SharePoint : Développer des colonnes calculées

    Contrairement à ce que l’on pourrait penser, il y a 2 types de colonnes calculées dans SharePoint :

    • les <Field Type="Calculated" /> que l’on peut créer avec l’interface habituelle, dans lesquelles on manipule des formules,
    • et les <Field Type="Computed" /> qu’on ne peut créer que via une définition CAML ou par modèle objet.

    Les 2 types permettent de définir des colonnes en lecture seule dont la valeur dépend d’autres champs de l’élément. Le premier permet notamment de faire de très jolies choses lorsqu’il est couplé à du code JavaScript, comme expliqué ici : Using calculated columns to write HTML. Aujourd’hui, nous allons parler du 2ème type, qui m’a permis de répondre à 2 besoins à la fois chez l’un de mes clients. Dans son extranet SharePoint 2007, orienté publication de contenu, celui-ci utilise beaucoup de web parts associées à des bibliothèques. Celles-ci étant plus simples à mettre en place que des web parts requêtes de contenu, c’est elles que mon client utilise pour afficher le contenu de ses bibliothèques à ses utilisateurs.

    Son premier besoin est que si le titre d’un document est renseigné, ce soit le titre qui soit affiché au lieu de son nom. Il est très facile de répondre à ce besoin via une web part requête de contenu, mais rien ne permet nativement de le faire dans une web part de bibliothèque.

    D’autre part, les utilisateurs se plaignent que, lorsqu’ils cliquent sur un document office, l’application leur demande de se ré authentifier. Cela vient du fait que, dans les web parts de bibliothèques, les liens vers les documents indiquent aux applications office de s’ouvrir et de travailler avec le document de manière distante. L’application Office, qui par définition est executée dans un processus différent, doit donc s’authentifier indépendamment du navigateur.
    A contrario, sur un site web classique, un lien vers un document retourne simplement le dit document afin qu’il soit téléchargé par l’utilisateur et que celui-ci travaille avec en local. L’extranet de mon client étant orienté publication de contenu, il souhaite que les documents soient téléchargés et non ouverts de manière distante. Là encore, c’est plutôt simple à mettre en place avec une web part requête de contenu, mais ce n’est pas prévu en standard dans une web part de bibliothèque.

    Avec le comportement par défaut, on obtient ceci lorsque l’on clique sur le lien du document (colonne “Nom”) :

    f1

    Quelque-soit le mode choisit, Word s’ouvre et essaye d’ouvrir le document situé sur le serveur, provoquant une demande d’authentification :

    f2

    Ce comportement n’est pas souhaitable dans le cadre d’un site de publication. Ce qu’on veut, c’est que le document soit tout simplement téléchargé en local.

    Pour proposer un lien de téléchargement de document, on peut utiliser la “page” /_layouts/download.aspx, qui prend en query string un argument SourceUrl permettant de spécifier l’url d’un fichier que l’on souhaite télécharger. Nous allons voir comment proposer un lien dynamique vers cette “page” dans une colonne de bibliothèque. Exemple : http://sncfc.nwtraders.com/_layouts/download.aspx?SourceUrl=/monsite/documents/document1.docx.

    Les colonnes calculées (Type=”Computed”) permettent de définir un rendu HTML à partir de patterns XML. Le principe est approximativement le même que pour les transformations XSLT, mais le langage est différent. Ici pas de classe à développer, juste une définition de colonne à écrire en CAML.

    Voici la définition de colonne répondant au besoin énoncé ci-dessus :

    <Field ID="{19B08457-9C22-4d54-BC74-BC321E1704EC}" Type="Computed" Name="DownloadLinkWithTitleOrName" StaticName="DownloadlinkWithTitleOrName" DisplayName="Document" Hidden="FALSE" CanToggleHidden="FALSE" Sortable="TRUE" Filterable="FALSE" AuthoringInfo="(Lien de téléchargement avec affichage du titre ou du nom)" SourceID="http://schemas.microsoft.com/sharepoint/v3" FromBaseType="TRUE" ReadOnly="TRUE" >

           <FieldRefs>

                 <!-- Colonnes utilisées par la colonne calculée -->

                 <FieldRef Name="Title"/>

                 <FieldRef Name="FileRef"/>

           </FieldRefs>

           <DisplayPattern>

                 <!-- Le lien pointe vers /_layouts/download.aspx qui renvoie le fichier dont l'url est en paramètre -->

                 <HTML><![CDATA[<a href="http://blogs.developpeur.org/_layouts/download.aspx?sourceUrl=]]></HTML>

                 <!-- Url du fichier encodée -->

                 <LookupColumn Name="FileRef" URLEncodeAsURL="TRUE"/>

                 <HTML><![CDATA[">]]></HTML>

                 <!-- Définition d’une variable ItemTitle -->

                 <SetVar Name="ItemTitle">

                        <LookupColumn Name="Title" StripWS="TRUE" HTMLEncode="TRUE" />

                 </SetVar>

                 <Switch StripWS="TRUE">

                        <Expr>

                               <GetVar Name="ItemTitle" StripWS="TRUE" />

                        </Expr>

                        <!-- Si le titre est vide, j'affiche le nom du document -->

                        <Case Value="">

                               <UrlBaseName HTMLEncode="TRUE">

                                      <LookupColumn Name="FileRef"/>

                               </UrlBaseName>

                        </Case>

                        <!-- Si le titre est rempli, j'affiche le titre du document -->

                        <Default>

                               <GetVar Name="ItemTitle" StripWS="TRUE" />

                        </Default>

                 </Switch>

                 <HTML><![CDATA[</a>]]></HTML>

           </DisplayPattern>

    </Field>

    On notera qu’il est nécessaire de déclarer les colonnes dont on utilise la valeur, dans l’élémént FieldRefs. Si ce n’est pas fait, à l’éxecution, les colonnes apparaitront comme vides.

    On notera aussi l’utilisation de l’instruction Switch qui est résolue pour chaque élément du jeu de résultat, contrairement à FieldSwitch qui n’est résolue que pour le premier résultat et dont la valeur est réutilisée pour tous les éléments du jeu de résultat. Je précise cela car la plupart des exemples trouvés sur internet utilisent FieldSwitch.

    Une fois cette colonne associée (par code avec la méthode list.Fields.AddFieldAsXml(xml) ou via une définition de liste custom, on peut l’ajouter à nos vues :

    image

    Et voici le rendu. Notez que, contrairement à la colonne “Nom”, le lien de la colonne “Document” propose le document au téléchargement :

    image

    Vous trouverez ici l’ensemble des balises qu’il est possible d’utiliser dans les patterns de rendu : http://msdn.microsoft.com/en-us/library/ms439798.aspx

    Notez qu’il existe certaines limitations avec cette méthode lorsqu’elle est utilisée sur des types de contenu, décrites dans ce billet au titre un peu exagéré : Do not use SharePoint Computed fields 

    Arnault Nouvel
    Winwise


    Classé sous ,

    SharePoint 2010 : Développer un WebTemplate

    SharePoint 2010 propose de nouvelles manières de développer un modèle de site personnalisé :

    Développement d’une définition de site

    Pas de changement majeur par rapport à la version 2007, une définition de site impose toujours de déployer un fichier webtemp.xml en plus du fichier onet.xml. Pour SharePoint 2010, Visual Studio 2010 propose un type et un élément de projet spécifique pour créer une définition de site.

    Génération à la souris d’un modèle de site

    Je parle ici du modèle de site généré automatiquement lorsque l’on utilise la fonctionnalité “Enregistrer en tant que modèle de site” de la page des paramètres d’un site.

    Avec SharePoint 2010, cela génère un package .wsp de type solution sandbox (en 2007, cela générait un .stp qui avait certaines limitations).

    On peut éventuellement le réutiliser dans une autre ferme et/ou l’importer dans Visual Studio 2010 pour y effectuer des modifications. Malheureusement en l’important dans Visual Studio 2010, on constatera qu’un projet initié sur cette base serait difficilement maintenable car tous les éléments de base y sont redéfinis. On notera toutefois que le modèle de site généré est un WebTemplate.

    Développement d’un WebTemplate

    Nouveauté SharePoint 2010, l’élément de feature WebTemplate permet de créer un modèle de site en “héritant” d’une définition de site. Cet élément peut être de scope Farm ou Site. En cas de scope Site, il peut être déployé dans une solution sandbox.

    L’héritage en question n’est que déclaratif : on devra fournir un onet.xml qui sera utilisé par SharePoint au moment de la création d’un site. Suite à sa création, l’onet.xml sera “oublié” et le site sera considéré comme ayant été créé avec la définition de site “héritée”.

    A mon sens, l’intérêt majeur de cette nouveauté est la facilité qu’elle apportera lors de la migration vers la prochaine version de SharePoint. Chaque site existant créé via un WebTemplate bénéficiera des traitements de migration prévus par l’équipe produit pour la définition de site dont il hérite.

    Pour développer un WebTemplate, l’approche consiste donc à fournir un onet.xml minimal dans lequel on référence des features de scope web. Passer par des features plutôt que par des éléments xml dans l’onet facilite la maintenance et garantie une meilleure portabilité en cas de migration puisque migrer des features sera en principe plus aisé que de migrer une définition de site.

    On regrettera juste que Visual Studio 2010 n’en propose pas la création d’une manière automatique, contrairement aux définitions de sites.

     

    Voici un récapitulatif des avantages et inconvénients des 3 méthodes :

     

    Avantages

    Inconvénients

    Définition de site

    • Modèle de projet dans Visual Studio 2010
    • Migration manuelle

    Modèle de site

    • Création par un utilisateur avancé
    • Migration automatique
    • Sandbox Solution
    • Maintenance difficile

    WebTemplate

    • Migration automatique
    • Maintenance facile
    • Sandbox ou Farm Solution
    • Déployé en feature (donc activable/désactivable)
    • Limitation (contournable, voir plus bas) sur l’activation des features de collection de sites référencées dans la balise <SiteFeatures> de l’onet.xml

     

    Voyons maintenant comment développer un modèle de site avec un WebTemplate.

    Développement d’un WebTemplate

    Dans Visual Studio 2010, créer un projet SharePoint vide (ou charger un projet SharePoint existant) puis y ajouter un “Empty SharePoint Item” nommé WebTemplate_ClientMeetings.

    Dans le fichier elements.xml généré, ajouter la définition suivante :

    <?xml version="1.0" encoding="utf-8"?>

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

      <WebTemplate Name="WebTemplate_ClientMeetings"

                   BaseConfigurationID="1"

                   BaseTemplateName="STS"

                   BaseTemplateID="1"

                   Title="Rendez-vous clients"

                   Description="Site de gestion de rendez-vous clients"

                   DisplayCategory="Demo"

                   Locale="1036"

                   />

    </Elements>

     

    Cette définition indique que l’on crée un modèle de site “Rendez-vous clients” qui “hérite” du modèle de site “Site vierge” (STS#1).

    Attention, l’attribut Name doit correspondre au nom du répertoire dans la structure du projet, car il s’agit du nom du répertoire dans lequel SharePoint s’attendra à trouver le fichier onet.xml.

    Copier maintenant le fichier …14\TEMPLATE\SiteTemplates\STS\XML\ONET.XML dans le même répertoire.

    Sélectionner ensuite le fichier onet.xml dans la structure du projet et indiquer le mode de déploiement “ElementFile”.

    image

    On peut maintenant faire le ménage dans notre onet.xml afin de ne garder que ce qui nous intéresse, et ajouter les features que l’on souhaite activer. Dans l’exemple, WebTemplate a un attribut BaseConfigurationID="1", on peut donc ne conserver que la configuration ayant l’attribut ID="1".

    Voici contenu de mon fichier onet.xml :

    <?xml version="1.0" encoding="utf-8"?>

    <Project Title="$Resources:onet_TeamWebSite;" Revision="2" ListDir="$Resources:core,lists_Folder;" xmlns:ows="Microsoft SharePoint" UIVersion="4">

     

      <Configurations>

     

        <Configuration ID="1" Name="Blank" MasterUrl="_catalogs/masterpage/v4.master">

          <SiteFeatures>

            <!-- BasicWebParts Feature -->

            <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />

            <!-- Three-state Workflow Feature -->

            <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />

          </SiteFeatures>

          <WebFeatures>

            <!-- TeamCollab Feature -->

            <Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />

            <!-- MobilityRedirect -->

            <Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />

     

            <!-- WikiPageHomePage Feature -->

            <Feature ID="00BFEA71-D8FE-4FEC-8DAD-01C19A6E4053" />

            <!-- Apply_MasterPage -->

            <Feature ID="3805d5ae-b975-4652-a644-0f0578a25e1b" />

          </WebFeatures>

        </Configuration>

     

      </Configurations>

     

    </Project>

     

    Dans cet exemple sont référencées les mêmes features que dans la définition de site parente, plus la feature des pages wiki et une feature custom permettant d’appliquer une master page spécifique.

     

    Une fois déployé, un nouvel modèle de site devrait alors apparaitre dans l’écran de création de site :

    image

     

    Une limitation importante à connaitre

    Mon projet exemple est composé de 3 features :

    • Farm_WebTemplate (scope Farm) : la feature qui contient mon élément WebTemplate
    • Site_MasterPage (scope Site) : via un module, elle provisionne la master page personnalisée dans la galerie des master pages de la collection de sites
    • Web_ApplyMasterPage (scope Web) : par code, elle applique la master page personnalisée au site courant

    La limitation est la suivante : lorsque l’on crée un site en se basant sur un modèle de site WebTemplate, les features de niveaux collection de sites ne sont pas activées automatiquement. Si dans <SiteFeatures> on en référence une qui n’est pas activée, on aura le message d’erreur suivant lors de la création du site :

    image

    Pour contourner ce problème, une solution consiste à activer par code la feature de scope Site dans le receiver de la feature Web_ApplyMasterPage, et de ne référencer que la feature de scope Web dans l’onet.xml.

    Ci-dessous le code exécuté à l’activation de la feature Web_ApplyMasterPage, qui se charge de l’activation de Site_MasterPage :

    image 

    Pour plus d’informations sur l’élément WebTemplate, je vous invite à consulter l’article de Vesa Juvonen : SharePoint 2010 and web templates

    Arnault Nouvel
    Winwise

    SharePoint Saturday : Présentation de Winwise.SPMailing

    Logo_Club_SharePoint

    Le samedi 6 novembre 2010 aura lieu le premier "SharePoint Saturday" organisé par le club SharePoint. Cet évènement, en libre accès, proposera tout au long de la journée des sessions techniques autour de SharePoint. De 45 minutes chacune, elles se dérouleront en ligne via live meeting.

    J'ai publié il y a quelques semaines un projet CodePlex permettant de générer et envoyer des newsletters à partir de contenu publié dans SharePoint 2010. Déjà présenté par Arnaud Jund, je ferai une démonstration live de son installation et de son utilisation lors du SharePoint Saturday.

    Rendez-vous à 16H30 le 6 novembre prochain pour une session sur Winwise.SPMailing :)

    Le site de l'évènement : http://www.sharepointsaturday.org/france

    Arnault Nouvel
    Winwise

    SharePoint 2010 : Développer une web part d’authentification pour une page d’accueil

    Nous avons vu dans un précédent billet comment configurer l’authentification par formulaire dans SharePoint 2010. Il est possible de développer son propre formulaire d’authentification afin d’en modifier le design et le comportement. Chun Liu propose un tutorial à cet effet : http://blogs.msdn.com/b/chunliu/archive/2010/08/21/creating-a-custom-login-page-for-fba-in-sharepoint-2010.aspx.

    Je m’en suis inspiré pour développer une web part de login qui permet de s’authentifier en passant soit son login, soit son email. Mon autre objectif était de proposer l’authentification sur la page d’accueil du site, qui devait donc être en authentification anonyme. Ce billet détaille les étapes nécessaires pour parvenir à ce résultat.

    Paramétrage de l’accès anonyme

    Dans l’administration centrale : “Manage web applications”, sélectionner l’application web cible, cliquer dans le ruban sur “Authentication Providers”, sélectionner la zone cible, cocher “Enable Anonymous Access” et valider.

    image

    Dans la collection de sites : “Site Actions”, “Site Settings”, “Site permissions”, cliquer sur “Anonymous Access” dans le ruban, cocher “Entire Web Site” :

    image

    A ce stade, notre page d’accueil est accessible en authentification anonyme. Voyons maintenant comment développer une web part de login.

    Développement de la web part

    Avec Visual Studio 2010, créer un projet de type “Farm Solution”.

    Pour manipuler les classes nécessaires à l’authentification en mode Claims, il est nécessaire d’ajouter 3 références au projet :

    • System.IdentityModel.dll (répertoire C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0)
    • Microsoft.IdentityModel.dll (répertoire C:\Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5)
    • Microsoft.SharePoint.IdentityModel.dll (à récupérer par ligne de commande dans C:\Windows\assembly\GAC_MSIL\System.IdentityModel\3.0.0.0__b77a5c561934e089)

    Ajouter ensuite au projet une Visual Web Part

    Code du fichier .ascx :

    <table>

        <tr>

            <td>Login or email :&nbsp;</td>

            <td><asp:TextBox ID="txbLoginOrEmail" runat="server" Width="150px" TextMode="SingleLine" /></td>

        </tr>

        <tr>

            <td>Password :&nbsp;</td>

            <td><asp:TextBox ID="txbPassword" runat="server" Width="150px" TextMode="Password" /></td>

        </tr>

        <tr>

            <td colspan="2" align="right">

                <asp:Button ID="btnLogin" runat="server" Text="Login" OnClick="btnLogin_Click" />

            </td>

        </tr>

    </table>

    <asp:Label ID="lblError" runat="server" ForeColor="Red" EnableViewState="false" />

    Code du fichier .ascx.cs :

        public partial class CustomAuthenticationWebPartUserControl : UserControl

        {

     

            //Validates an email adress

            private static Regex REGEX_EMAIL = new Regex(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", RegexOptions.Compiled | RegexOptions.IgnoreCase);

     

            protected void btnLogin_Click(object sender, EventArgs e)

            {

     

                //Retrieves a security token from supplied credentials

                SecurityToken token = GetSecurityTokenFromUserInput();

     

                if (token != null)

                {

     

                    //Authenticates the user using the token

                    SPFederationAuthenticationModule.Current.SetPrincipalAndWriteSessionToken(token);

     

                    //Redirects user to current page or to previous page if there is a Source parameter in the query string

                    //(Source parameter is set by SharePoint when redirecting to webapp's login page)

                    SPUtility.Redirect(HttpContext.Current.Request.Url.ToString(), SPRedirectFlags.UseSource, HttpContext.Current);

                   

                }

                else

                    lblError.Text = "Invalid Credentials";

     

            }

     

           

            private SecurityToken GetSecurityTokenFromUserInput()

            {

               

                //Retrieves the SPFormsAuthenticationProvider associated to the current web application zone

                SPWebApplication webApp = SPWebApplication.Lookup(HttpContext.Current.Request.Url);

                SPIisSettings settings = webApp.IisSettings[SPContext.Current.Site.Zone];

                SPFormsAuthenticationProvider authProvider = settings.FormsClaimsAuthenticationProvider;

     

                //User input

                String login = txbLoginOrEmail.Text.Trim();

                String password = txbPassword.Text.Trim();

     

                //If the login input is an email, retrieves associated login using the membership provider

                if (REGEX_EMAIL.Match(login).Success)

                {

                    MembershipProvider provider = Membership.Providers[authProvider.MembershipProvider];

                    login = provider.GetUserNameByEmail(login);

                }

     

                //Returns the security token

                return SPSecurityContext.SecurityTokenForFormsAuthentication(HttpContext.Current.Request.Url, authProvider.MembershipProvider, authProvider.RoleProvider, login, password);

     

            }

     

        }

     

    On notera qu’avec le claims authentication mode, on ne peut plus utiliser FormsAuthentication.Authenticate(login, password) comme on le faisait dans SharePoint 2007.

    Après un Clic-droit + Deploy sur le projet, on peut positionner la web part sur la page d’accueil du site.

    image

    Cet exemple peut être téléchargé ici : SPCustomAuthenticationWebPart.zip

    Custom Sign In Page

    Lorsqu’un utilisateur non authentifié tente d’accéder à une ressource sécurisée, il est redirigé vers la page d’authentification dont l’url se paramètre au niveau web application. J’ai essayé de paramétrer la “Custom Sign In Page” sur l’url de la page d’accueil de mon site. Cependant, cela conduit à certains effets de bord désagréables. Par exemple, lorsqu’un utilisateur déjà authentifié accède à l’url de la “Custom Sign In Page” (la page d’accueil donc), SharePoint lève une erreur de sécurité.

    En conjonction de d’une web part de login, je recommande donc de mettre en place un formulaire d’authentification personnalisé comme détaillé dans l’article de Chun Liu.

     

    Arnault Nouvel – Winwise


    Classé sous , ,

    SharePoint 2010 : Configuration de l’authentification par formulaire avec annuaire AD-LDS (partie 4 – haute disponibilité de l’annuaire AD-LDS)

    Ce billet fait partie d’une série :

    Nous allons voir dans ce billet comment répliquer l’instance AD-LDS sur un second serveur et comment configurer la répartition de charge réseau afin d’assurer une haute disponibilité sur l’annuaire AD-LDS.

    Voici les étapes :

    • Répliquer l’instance AD-LDS sur un deuxième serveur
    • Créer un cluster de répartition de charge
    • Rediriger le nom de domaine annuaire.extranet.test vers l’adresse IP du cluster

    1. Installation d’une réplique de l’instance AD-LDS

    Avec le même compte que le compte administrateur spécifié lors de la création de l’instance installé EXTRANET-ADLDS, se connecter au serveur EXTRANET-ADLDS2.

    Après avoir installé le rôle “Active Directory Lightweight Directory Services”, lancer l’assistant de création d’instance comme nous l’avons fait dans la partie 2.

    Sur le premier écran, choisir la 2ème option pour indiquer que l’on souhaite créer une réplique d’une instance existante :

    23-replicat-install-adlds

    Indiquer le serveur sur lequel se trouve l’instance à répliquer :

    24-replica-choose-source

    Sélectionner la partition à répliquer :

    25-replica-choose-partition

    Dérouler l’assistant jusqu’à la ce que la réplique soit créée.

    Avec ADSIEdit.msc, il est possible de vérifier que l’instance est fonctionnelle (comme expliqué dans la partie 2), on retrouvera d’ailleurs les utilisateurs et groupes créés sur l’autre serveur.

    Il faut cependant bien comprendre qu’on a là 2 instances différentes qui se synchronisent à intervalles réguliers.

    2. Planification de la réplication

    Démarrer la console “Active Directory Sites and Services” : Start, Administrative Tools, Active Directory Sites and Services.

    Par défaut la console se connecte au domaine Active Directory du serveur. Nous allons lui demander de se connecter à notre instance AD-LDS via un clic-droit sur le noeud racine, puis “Change Domain Controller…”

    image

    Indiquer alors le nom d’un des serveurs (le principal ou la réplique, au choix) comme sur la capture suivante :

    29-change-directory-server

    Une fois connecté, on sélectionne le site “Default-First-Site-Name” et on ouvre les propriétés “NTDS Site Settings” :

    image

    Note : l’écran de propriétés n’est disponible que si le package MS-ADLDS-DisplayContainer.ldf a été importé lors de l’installation de l’instance principale.

    L’écran des propriétés nous propose notamment de modifier la fréquence de réplication grâce à cette interface :

    34-schedule

    Nos 2 instances étant opérationnelles et répliquées, nous allons maintenant mettre en place la répartition de charge avec Windows NLB.

    3. Planification de la répartition de charge avec Windows Network Load Balancing (NLB)

    Pour schématiser, nous allons créer un cluster NLB qui correspondra à une IP virtuelle, et y associer les cartes réseau de nos 2 serveurs (EXTRANET ADLDS et EXTRANET-ADLDS2). Ces cartes réseau seront configurées par Windows NLB pour écouter les paquets adressés à l’adresse IP virtuelle du cluster.

    La mise en place de ce système nécessite une planification.

    Premièrement, il nous faut une adresse IP libre pour le cluster NLB.

    Nous utiliserons ici l’adresse IP 192.168.70.10 pour notre cluster NLB, en sachant que EXTRANET-ADLDS utilise 192.168.70.11 et que EXTRANET-ADLDS2 utilise 192.168.70.12.

    Dans la partie 2 nous avons créé un alias DNS annuaire.extranet.test qui pointe sur EXTRANET-ADLDS. Une fois la répartition de charge mise en place, nous modifieront l’entrée DNS pour qu’elle pointe vers l’IP du cluster au lieu de l’IP du serveur AD-LDS principal.

    Ensuite, choisir son mode de fonctionnement :

    • En mode multicast, une carte réseau répond à la fois à son IP et à celle du cluster. Attention, certains équipements réseau (de vieux switchs par exemple) ne supportent pas ce mode. Avant de s’orienter sur ce mode, il faut vérifier si il est supporté par tous les équipements réseau situés entre les clients (le serveur SharePoint par exemple) et les serveurs cibles (AD-LDS).
    • En mode unicast, une carte réseau ne pourra répondre qu’aux paquets adressés au cluster, il faudra donc 2 cartes réseau par serveur du cluster.

    Nous utiliserons ici le mode multicast qui est plus simple à mettre en place puisqu’il ne nécessite qu’une carte réseau par serveur.

    Enfin, déterminer le “client affinity” qui correspond à la manière dont le NLB répartie les paquets provenant d’une même source :

    • None : les paquets sont envoyer aléatoirement à un ou l’autre des noeuds du cluster (le noeud cible reste le même pendant la durée de la session, une session étant lié à un port précis)
    • Single : une fois qu’un client (SharePoint par exemple) aura établit une première connexion à un noeud du cluster, les paquets suivants seront redirigés vers le même, quelque soit le port cible
    • Network : Le routage est fonction du sous-réseau de provenance du paquet

    Nous utiliserons ici le mode Single.

    4. Création du cluster NLB

    Sur chaque serveur AD-LDS, via la console Server Manager, installer la fonctionnalité Windows appelée “Network Load Balancing” :

    40-add-nlb-feature

    Ensuite, se connecter sur le premier serveur AD-LDS (EXTRANET-ADLDS).

    Exécuter la console d’administration du NLB : Cliquer sur Start, Administrative Tools, “Network Load Balancing Manager”.

    Clic-droit sur le noeud racine, puis “New Cluster” :

    41-creer-cluster

    Saisir le nom du premier serveur à ajouter au cluster

    42-creer-cluster-2

    La fenêtre Host Parameters qui vient ensuite nous permet de spécifier un paramétrage pour le serveur indiqué précédemment. On indique la priorité du serveur au sein du cluster (la plus basse reçoit les paquets en priorité) et la ou les adresses IP qui feront partie du le cluster (un serveur peut avoir plusieurs cartes réseau).

    42-cluster-host-parameters

    La fenêtre “Cluster IP Adresses” permet de saisir la ou les adresses IP du cluster.

    Nous allons ici ajouter l’adresse 192.168.70.10 qui est celle de notre cluster:

    44-cluster-add-ip

    La fenêtre “Cluster Parameters” permet de définir le host name à prendre en compte ainsi que le mode dont nous avons parlé plus haut, et ce pour chaque adresse IP. Indiquer annuaire.extranet.test pour le host name, et sélectionner le mode multicast :

    45-cluster-parameters

    L’écran suivant permet de définir quels ports seront pris en compte par le cluster. Par défaut, ils le sont tous.
    Supprimer cette plage de port et n’indiquer que les ports 389 et 636 utilisés par nos instances AD-LDS. Pour chacun, sélectionner le protocole TCP et le Filtering mode “Single” :

    46-cluster-ports

    47-cluster-ports2

    Nous avons à ce stade un cluster de répartition de charge qui contient un seul serveur, le EXTRANET-ADLDS. Nous allons maintenant ajouter le serveur EXTRANET-ADLDS2 au cluster.

    Faire un clic-droit sur le cluster, “add host to cluster”, puis re dérouler les étapes précédentes pour ajouter le serveur EXTRANET-ADLDS2 :

    48-cluster-final

    La répartition de charge étant prête, il ne reste plus qu’à rediriger le nom de domaine annuaire.extranet.test vers l’adresse IP de notre cluster.

    5. Redirection DNS

    Les requêtes LDAP émanant de la ferme SharePoint sont effectuées sur le nom de domaine annuaire.extranet.test, qui pointe sur le serveur EXTRANET-ADLDS. Nous allons maintenant modifier l’entrée DNS annuaire.extranet.test pour qu’elle corresponde à l’adresse IP du cluster.

    Se connecter au controlleur de domaine EXTRANET-AD avec le compte administrateur du domaine.

    Ouvrir la console de gestion DNS : Start, Administrative Tools, DNS.

    Déplier l’arborescence jusqu’au noeud extranet.test.

    Supprimer l’alias annuaire (clic-droit, remove)

    Créer une entrée de type Host (clic-droit, new Host) nommée annuaire pointant sur l’adresse IP du cluster : 192.168.70.10

    image

    A cause de son cache, le serveur SharePoint continue d’associer annuaire.extranet.test au serveur EXTRANET-ADLDS. Pour vider le cache DNS du serveur SharePoint afin qu’il associe annuaire.extranet.test à l’adresse IP du cluster NLB, il faut se connecter dessus et exécuter la ligne de commande suivante : ipconfig /flushdns

    SharePoint communique désormais avec un annuaire AD-LDS assurant une haute disponibilité. On peut s’amuser à éteindre et rallumer les serveurs AD-LDS un par un et vérifier que l’authentification fonctionne toujours.

     

    Arnault Nouvel – Winwise

    SharePoint 2010 : Configuration de l’authentification par formulaire avec annuaire AD-LDS (partie 3 – configuration de l’authentification par formulaire)

    Ce billet fait partie d’une série :

    Ce tutorial requiert que SharePoint 2010 soit installé, que la partition AD-LDS qui contient nos utilisateurs aie été configurée, et que les comptes de services utilisés par SharePoint y aient accès en lecture. Pour les détails, voir partie 2.

    Nous allons maintenant créer une nouvelle application web SharePoint en authentification par formulaire.

    1. Creation de l'application web

    L'authentification par formulaire sous SharePoint 2010 repose toujours sur le système du MembershipProvider hérité d'ASP.NET, qui permet de générer une identité à partir d'un système tiers. On ne pourra cependant utiliser l'authentification par formulaire que si on configure notre application web en mode claims.

    Dans l'administration centrale, cliquer sur le lien "Manage Web Applications". Dans le ruban, cliquer sur "New" pour ouvrir la fenêtre de création d'application web.

    On coche "Claims authentication mode", on indique optionnellement un nom de domaine (nécessite de définir un alias DNS), et dans la partie claims authentication on coche "Forms Authentication Mode" en indiquant un nom pour le membership provider et un autre pour le role provider.

    18-creation-webapp-1

    19-creation-webapp-2

    On ne décochera pas “Windows Authentication” sous peine de ne pas pouvoir faire fonctionner la recherche.
    Un contournement possible pour ne pas avoir l’authentification Windows tout en conservant la recherche serait de passer par une extension d’application web : une application web avec authentification Windows pour la recherche, une autre avec authentification par formulaire pour les utilisateurs.

    Nous allons maintenant devoir expliquer à SharePoint à quoi correspondent “AdldsMember” et “AdldsRole”. En l'occurrence nous allons les associer au LdapMembershipProvider fournit avec SharePoint Server 2010 qui permet d'exploiter LDAP générique. Il est donc parfaitement adapté à AD-LDS.

    Ce paramétrage s’effectue au niveau des fichiers web.config des applications web suivantes :

    • Administration centrale
    • Secure Store Service
    • L’application web que nous venons de créer

     

    2. Modification du web.config de l'administration centrale

    Ouvrir le fichier C:\inetpub\wwwroot\wss\VirtualDirectories\55555\web.config (55555 correspondant au numéro de port de l'administration centrale, il varie d'un environnement à l'autre).

    Remplacer les nœuds membership et roleManager par le bloc suivant :

    <membership>

       <providers>

          <add name="AdldsMember"    

               type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

               server="annuaire.extranet.test"

               port="389"

               useSSL="false"

               userDNAttribute="distinguishedName"

               userNameAttribute="cn"

               userContainer="OU=Users,OU=extranet,DC=annuaire,DC=extranet,DC=test"

               userObjectClass="user"

               userFilter="(ObjectClass=user)"

               scope="Subtree"

               otherRequiredUserAttributes="sn,givenname,cn" />

      </providers>

    </membership>

    <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider" >

       <providers>

          <add name="AdldsRole"

                type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

                server="annuaire.extranet.test"

                port="389"

                useSSL="false"

                groupContainer="OU=Users,OU=extranet,DC=annuaire,DC=extranet,DC=test"

                groupNameAttribute="cn"

                groupNameAlternateSearchAttribute="cn"

                groupMemberAttribute="member"

                userNameAttribute="cn"

                dnAttribute="distinguishedName"

                groupFilter="(ObjectClass=group)"

                userFilter="(ObjectClass=user)"

                scope="Subtree" />

       </providers>

    </roleManager>

    Afin de faire fonctionner la filtrage dans le sélecteur de personnes, une modification nécessaire s’impose.
    Dans le nœud PeoplePickerWildcards, ajouter les entrées pour AdldsMember et AdldsRole comme indiqué ci-dessous :

    <PeoplePickerWildcards>

          <clear />

          <add key="AspNetSqlMembershipProvider" value="%" />

          <add key="AdldsMember" value="*" />
          <add key="AdldsRole" value="*" />
    </PeoplePickerWildcards>

    Seules les parties surlignées en jaunes sont à modifier en fonction l'annuaire cible.

    Enregistrer le fichier.

    3. Modification du web.config du Secure Store Service

    Ouvrir le fichier : C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken\web.config

    A l’intérieur du nœud <configuration>, copier le XML suivant :

    <membership>

       <providers>

            <add name="AdldsMember"

                 type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

                 server="annuaire.extranet.test"

                 port="389"

                 useSSL="false"

                 userDNAttribute="distinguishedName"

                 userNameAttribute="cn"

                 userContainer="OU=Users,OU=extranet,DC=annuaire,DC=extranet,DC=test"

                 userObjectClass="user"

                 userFilter="(ObjectClass=user)"

                 scope="Subtree"

                 otherRequiredUserAttributes="sn,givenname,cn" />

       </providers>

    </membership>
    <roleManager enabled="true" defaultProvider="AdldsRole" >

       <providers>

            <add name="AdldsRole"

                 type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

                 server="annuaire.extranet.test"

                 port="389"

                 useSSL="false"

                 groupContainer="OU=Users,OU=extranet,DC=annuaire,DC=extranet,DC=test"

                 groupNameAttribute="cn"

                 groupNameAlternateSearchAttribute="cn"

                 groupMemberAttribute="member"

                 userNameAttribute="cn"

                 dnAttribute="distinguishedName"

                 groupFilter="(ObjectClass=group)"

                 userFilter="(ObjectClass=user)"

                 scope="Subtree" />

       </providers>

    </roleManager>

     

    Enregistrer le fichier.

    4. Modification du web.config de l'application web

    Ouvrir maintenant le fichier web.config de l'application web créée plus haut : C:\inetpub\wwwroot\wss\VirtualDirectories\portail.extranet.test80\web.config (le nom du répertoire change en fonction du host header et du numéro de port)

    A l'intérieur du nœud membership, copier le XML suivant (en conservant les autres nœuds existants):

    <add name="AdldsMember"

         type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

         server="annuaire.extranet.test"

         port="389"

         useSSL="false"

         userDNAttribute="distinguishedName"

         userNameAttribute="cn"

         userContainer="OU=Users,OU=extranet,DC=annuaire,DC=extranet,DC=test"

         userObjectClass="user"

         userFilter="(ObjectClass=user)"

         scope="Subtree"

         otherRequiredUserAttributes="sn,givenname,cn" />

    A l'intérieur du nœud roleManager, copier le XML suivant (en conservant les autres nœuds existants):

    <add name="AdldsRole"

         type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

         server="annuaire.extranet.test"

         port="389"

         useSSL="false"                   

         groupContainer="OU=Users,OU=extranet,DC=annuaire,DC=extranet,DC=test"

         groupNameAttribute="cn"

         groupNameAlternateSearchAttribute="cn"

         groupMemberAttribute="member"

         userNameAttribute="cn"

         dnAttribute="distinguishedName"

         groupFilter="(ObjectClass=group)"

         userFilter="(ObjectClass=user)"

         scope="Subtree" />

     

    Dans le nœud PeoplePickerWildcards, ajouter les entrées pour AdldsMember et AdldsRole comme indiqué ci-dessous :

    <PeoplePickerWildcards>

          <clear />

          <add key="AspNetSqlMembershipProvider" value="%" />

          <add key="AdldsMember" value="*" />
          <add key="AdldsRole" value="*" />
    </PeoplePickerWildcards>

    Enregistrer le fichier, puis éxecuter iisreset.exe.

    5. Création de la collection de sites racine de l'application web

    Naviguer dans l'administration centrale dans "Applications management", et cliquer sur "Create Site Collection". Sélectionner l'application web pour laquelle nous avons configuré l'authentification par formulaire, et donner un nom à la collection de sites.

    Ouvrir la fenêtre de sélection d'utilisateur pour définir l'administrateur de la collection de sites, on retrouve alors nos utilisateurs de l’annuaire AD-LDS dans la catégorie "Forms Auth". Sélectionner user1, et valider la création de la collection de sites.

    20-sitecoladmin

    Se connecter maintenant à l'application web (dans l'exemple, http://portail.extranet.test). On nous propose alors de choisir un mode d'authentification, choisir "Forms Authentication" puis saisir les credentials de user1.

    21-auth

    22-auth2

    23-auth3

    L’authentification par formulaire est maintenant opérationnelle.

    Bien qu’optionnelle vis à vis de l’authentification par formulaire, la 4ème partie de cette série de billets explique comment répliquer l’instance AD-LDS sur un second serveur et comment configurer la répartition de charge réseau afin d’assurer une haute disponibilité sur l’annuaire AD-LDS : Partie 4 : haute disponibilité de l’annuaire AD-LDS

     

    Arnault Nouvel – Winwise

    SharePoint 2010 : Configuration de l’authentification par formulaire avec annuaire AD-LDS (partie 2– installation et configuration de AD-LDS)

    Ce billet fait partie d’une série :

    Dans ce billet, nous allons mettre en place un annuaire AD-LDS sur un seul serveur, le serveur EXTRANET-ADLDS. La haute disponibilité AD-LDS étant optionnelle, elle sera traitée comme telle en partie 4.

    1. Paramétrage DNS

    Avant de créer l'instance, nous allons créer un alias DNS annuaire.extranet.test qui permettra à SharePoint de connaitre l'IP de la machine qui héberge l'annuaire. Cette étape est optionnelle puisque l’on pourrait utiliser le nom du serveur EXTRANET-ADLDS.extranet.test, cependant cet alias nous permettra de ne pas avoir à reconfigurer l’authentification par formulaire lorsque nous mettrons en place la haute disponibilité dans la partie 4.

    Connectons nous au contrôleur de domaine EXTRANET-AD avec le compte administrateur du domaine. Dans la console d'administration du DNS (Administrative Tools -> DNS), ajoutons un alias appelé "annuaire" qui pointe sur le serveur EXTRANET-ADLDS.

    0-dns

    Connectons nous maintenant au serveur EXTRANET-ADLDS avec le compte spadmin (qui est administrateur de la machine).

    2. Installation de rôle AD-LDS

    Afin de pouvoir créer une instance AD-LDS, il est nécessaire d'installer le rôle Active Directory Lightweight Directory Services.

    Via la console Server Manager, ajoutons ce rôle :

    1-ajout-role-adlds 

    3. Création de l'instance AD-LDS

    Une fois l'installation terminée, la console Server Manager dispose d'un nœud Roles/ADLDS et propose de créer une instance via le lien en haut à droite, cliquons dessus pour lancer l'assistant.

    2-creation-instance-adlds

    3-creation-instance-adlds

    Donner un nom à l'instance, ce nom définit celui du service Windows correspondant :

    4-nom-instance-adlds

    Dans notre cas, on laissera les ports par défaut :

    5-ports-adlds

    On indique ensuite que l'on souhaite créer une partition racine pour notre annuaire. Par convention, le nom de la partition reprend tout ou partie du nom de domaine du serveur LDAP. Bien que cela n’aie rien d’obligatoire, le "Distinguished Name" de notre partition se terminera par "DC=annuaire,DC=extranet,DC=test" afin d’établir une correspondance avec notre alias DNS annuaire.extranet.test. Plus d’informations sur les conventions de nommage des partitions : http://technet.microsoft.com/en-us/library/cc784421(WS.10).aspx

    Afin que la racine de la partition soit une "Organisational Unit" (là encore rien d'obligatoire, il y a d'autres options), nous allons nommer celle-ci "OU=extranet,DC=annuaire,DC=extranet,DC=test" :

    6-creation-partition-adlds

    L'écran suivant permet de sélectionner le compte de service utilisé par le service Windows correspondant à l'instance.

    7-service-account-adlds

    On sélectionne ensuite quel compte ou groupe Active Directory sera administrateur de l'instance : 

    8-admin-adlds

    Enfin, on sélectionne quels packages de définition seront importés dans notre instance AD-LDS :

    • MS-user.ldf car il définit la classe “user” que nous allons utiliser
    • MS-ADLDS-DisplayContainers.ldf qui permet d’administrer une instance AD-LDS avec la console Active Directory Sites and Services (utile pour planifier la réplication)

    9-ldif-adlds

    Un point intéressant à noter est la disponibilité du package MS-UserProxy qui permet de créer des utilisateurs bindés sur des comptes utilisateurs d'un autre annuaire LDAP ou Active Directory. Plus d'informations : http://technet.microsoft.com/en-us/library/cc775757(WS.10).aspx

    En déroulant la fin de l’assistant, notre partition racine sera créée. Nous allons maintenant nous y connecter et remplir notre annuaire.

    4. Connexion à l'annuaire AD-LDS

    Bien que nous ayons créé un alias DNS annuaire.extranet.test spécifiquement pour notre connexion à l’instance AD-LDS, nous n’allons pas l’utiliser avant la partie 3. En effet, durant l'installation de l'AD-LDS, une clé de registre a été modifiée afin d'empêcher toute connexion au serveur local en utilisant un alias DNS (la fameuse clé DisableLoopbackCheck). Nous pouvons toutefois nous connecter à notre instance en local en utilisant le nom de serveur LOCALHOST ou EXTRANET-ADLDS. 

    Ouvrons maintenant ADSIEdit (Start, run, "adsiedit.msc") et ajoutons une connexion :

    • Saisir le “distinguished name” de la partition racine dans la combo du haut
    • Saisir EXTRANET-ADLDS du dans la combo du bas

    Notre chaine de connexion est donc : LDAP://EXTRANET-ADLDS/OU=extranet,DC=annuaire,DC=extranet,DC=test

    11-adsiedit-connection-adlds

    En validant, ADSIEdit nous dévoile la structure de notre partition.

    12-structure-partition 

    5. Création des utilisateurs

    Nous allons créer une OU pour regrouper nos utilisateurs et groupes de sécurité : clic-droit sur l’OU racine, new, “object...”, organisationalUnit, puis saisir un nom pour l’OU.

    Ici, on crée une OU appelée “Users”.

    13-create-ou

    Nous allons maintenant créer un utilisateur “user1”. Pour créer un utilisateur dans l'OU Users, suivre les étapes suivantes :

    • Clic-droit sur l'OU Users, new, “object…”, user. On lui donne alors le nom “user1”.
    • Click-droit sur le compte, "Reset Password…", on définit alors son mot de passe.

    14-create-user-password

    • Enfin et surtout, on active le compte en double cliquant dessus pour afficher ses propriétés et en modifiant le champ ms-UserAccountDisabled qui est par défaut à TRUE. On le met à FALSE afin d'activer le compte.

    15-enable-user

    Note : On utilisera aussi cet écran de propriétés pour définir le nom d'affichage de l'utilisateur (champ displayName), son email (champ mail), et autres informations nécessaires.

    Pour les besoins du tutorial, répéter ces 3 étapes afin de créer un autre utilisateur appelé user2.

    6. Création d’un groupe

    Créons maintenant un groupe via un clic-droit sur l'OU Users, new, Object…, group.

    Pour ajouter des utilisateurs dans ce groupe, on ouvre la fenêtre des propriétés du groupe et on édite le champ "member" dans lequel on indique le distinguished name de chaque utilisateur à ajouter. Sur la capture suivante, on ajoute l'utilisateur user1 dans le groupe group1.

    16-add-user-to-group

    Note : pour éviter une erreur de saisie, une astuce consiste à faire un copier coller de la valeur du champ distinguishedName depuis l'écran des propriétés de l'utilisateur.

    7. Configuration des droits d’accès à la partition

    Avant de passer à la configuration de l’authentification par formulaire dans SharePoint, nous devons autoriser les comptes de service de SharePoint à se connecter en lecture à l'annuaire.

    Déplier le nœud CN=Roles et double cliquer sur CN=Readers pour afficher ses propriétés. Dans le champ "member", on ajoute les comptes Active Directory des différents comptes de service qui en auront besoin :

    • Application pool de l'administration centrale
    • Application pool de la web application qui héberge le portail
    • Application pool du Secure Token Service

    Afin de simplifier et d'éviter toute erreur dans le cadre du tutorial, nous allons ici ajouter le groupe "EXTRANET\Users" qui en principe les contient tous.

    17-readers-adlds

    Notre annuaire utilisateur est maintenant prêt à être utilisé par notre portail SharePoint 2010 : les comptes de service SharePoint sont autorisés à s'y connecter, et nous disposons de 2 utilisateurs de test dont un dans un groupe.

    Passons maintenant à la configuration de l’authentification par formulaire sous SharePoint : Partie 3 : configuration de l’authentification par formulaire

     

    Arnault Nouvel – Winwise


    Classé sous ,

    SharePoint 2010 : Configuration de l’authentification par formulaire avec annuaire AD-LDS (partie 1– introduction)

    Ce billet fait partie d’une série :

    Je travaille en ce moment sur la mise en place d'un portail extranet client en SharePoint 2010 dont l'infrastructure est intéressante. Cet extranet propose aux clients de manipuler des données provenant de divers systèmes d'informations existants mais hétérogènes, notamment du SAP. Afin de fournir à SharePoint un back-end unique pour manipuler les données, une infrastructure de web services SOA est développée en parallèle du portail. Celle-ci est hébergée sur une plateforme IBM WebSphere (contrainte client) qui se charge d’agréger les données à partir des back-ends existants. 

    3 équipes ont été mises en place et travaillent de concert :

    • Une équipe chargée d'effectuer les adaptations nécessaires dans les différents S.I. cibles
    • Une équipe en charge de la mise en place de la plateforme SOA
    • Une équipe en charge de la mise en place et de la réalisation du portail extranet

    Mon rôle dans ce projet est de définir l'architecture du portail et de mettre en place l’infrastructure qui va avec.

    Nous tirons partie de plusieurs des nouvelles fonctionnalités de SharePoint Server 2010 : les claims et le Secure Store Service pour la délégation d’identité, et le Business Data Connectivity Service qui permet à SharePoint de manipuler aisément des données provenant de systèmes externes. Dans notre cas les données proviennent des web services de la plateforme S.O.A.

    Pour des raisons évidentes de sécurité, les Web Services ont besoin de connaitre l’identité de l’utilisateur courant afin de l’autoriser ou non en lecture et en écriture sur les divers objets métiers. L'annuaire utilisateur doit donc être partagé entre SharePoint 2010 (authentification et autorisations d’accès au portail) et la plateforme SOA (autorisations d’accès aux objets métiers).

    Livré avec Windows 2008 R2, Active Directory LightWeight Services (AD-LDS) fournit un annuaire LDAP standard qui est exploitable à la fois par SharePoint 2010 et par les web services WebSphere. Il permet aussi d'assurer une haute disponibilité grâce à son système de réplication. Tous ces points étant des pré-requis du projet, nous avons adopté AD-LDS.

    Ci dessous un schéma macroscopique de l’infrastructure globale :

     

    infrastructure-macro

     

    Dans cette série de billets, nous allons nous concentrer sur la mise en place d’un annuaire utilisateurs dans AD-LDS et de l'authentification par formulaire sur SharePoint Server 2010. Nous configurerons ensuite la haute disponibilité au niveau d’AD-LDS en ajoutant un autre serveur et en utilisant le Windows Network Load Balancing (NLB).  Dans le projet en question tous les nœuds applicatifs bénéficient de haute disponibilité (3 frontaux SP, cluster SQL, etc.), mais ici nous ne nous intéresseront qu’à sa mise en place sur AD-LDS.

    Voici l'infrastructure sur laquelle je me suis appuyé pour réaliser ce tutorial :

    infrastructure-test

    Les 5 serveurs font partie d'un même domaine Active Directory extranet.test. Ce domaine contient les comptes de services utilisés par SharePoint 2010 et SQL Server, et les comptes utilisateurs des administrateurs des serveurs. Les utilisateurs distants qui pourront se connecter au portail extranet seront, eux, définis dans l'annuaire AD-LDS, ce qui permet en outre de ne pas polluer l'AD principal.

    Contexte de départ :

    • Les 5 serveurs sont des Windows 2008 R2 et font partie du domaine extranet.test
    • Le compte EXTRANET\spadmin est administrateur de tous les serveurs
    • SQL Server 2008 R2 est installé
    • SharePoint Server 2010 est installé en mode ferme et configuré selon les “best-practices” (avec des comptes de service dédiés pour les application pools, etc)

    Passons maintenant à l'installation et à la configuration de l'annuaire AD-LDS : Partie 2 - installation et configuration de AD-LDS

    Arnault Nouvel – Winwise

    SharePoint 2010 : Personnaliser la XSLT List View Web Part

    sharepoint-server

    Dans la version 2007 de SharePoint, la List View web part proposait la sélection d’une liste et d’un affichage de la liste choisie. Optionnellement, on pouvait modifier la vue pour par exemple afficher une colonne supplémentaire.

    Dans SharePoint 2010, cette web part est remplacée par la XSLT List View Web Part. Celle-ci conserve ces fonctionnalités, mais permet en plus de modifier le rendu HTML grâce à une transformation XSL personnalisable. Ce mécanisme permet de redéfinir entièrement le rendu des données issues d’une liste SharePoint, en ayant le contrôle sur la requête CAML sous-jacente. Un vrai couteau suisse :)

    Dans ce billet, nous allons voir comment modifier la requête CAML sous-jacente, comment personnaliser la transformation XSLT qui assure le rendu HTML, et comment déporter cette transformation dans un fichier xslt. En effet, par défaut le XSL customisé est stocké en propriété de la web part, mais il est  possible de l’enregistrer dans un fichier séparé afin de le réutiliser pour plusieurs web parts.

    Le tout sera fait avec l’interface web classique et SharePoint Designer.

    Créons tout d’abord une liste d’annonces, puis ajoutons la web part correspondante sur la page d’accueil.

    image

    A ce stade, la XSLT List View Web part exploite la transformation XSLT “out of the box”. Voyons comment modifier la requête CAML et le rendu avec SharePoint Designer. Pour cela on sélectionne la web part, puis dans l’onglet “Liste” on demande la modification de l’affichage avec SharePoint Designer, comme sur cette capture :

    image  

    SharePoint Designer s’ouvre alors en modification sur la page courante afin de nous permettre de modifier la définition de la web part. On constate que la requête CAML sous-jacente est embarquée dans la définition de la web part.

    image

    Modifions cette requête CAML pour y supprimer les colonnes Attachments et Modified, et ajoutons la colonne Body :

    image

    On peut alors enregistrer et constater le changement dans le navigateur :

    image

    Cette possibilité existait déjà avec SharePoint 2007. Voyons maintenant comment modifier le rendu HTML en personnalisant la transformation XSLT, ceci étant une nouveauté de la version 2010.

    Dans SharePoint Designer, on sélectionne la web part et dans l’onglet « Design » on clique sur « Customize XSLT -> Customize entire view »

    image

    La définition de la web part est alors modifiée et contient la transformation XSLT.

    image

    Celle-ci est très verbeuse car il s’agit de la transformation native qui permet un affichage dynamique en fonction des colonnes sélectionnées quel que soit la requête CAML sous-jacente. On y trouve aussi des appels à des fonctions javascript qui permettent la multi-sélection, le rafraîchissement automatique Ajax et autres fonctionnalités natives des listes SharePoint.

    Nous allons maintenant externaliser cette transformation dans un fichier xslt séparé. Cela permet une édition plus pratique et apporte la possibilité versionner, approuver et surtout de réutiliser la transformation dans plusieurs XSLT List View Web Parts. Cette étape est optionnelle car il est possible de modifier la transformation directement dans la définition de la web part, mais je tenais à mettre en avant cette possibilité dans ce billet.

    Copions tout le contenu de la balise <xsl></xsl> dans un fichier CustomAnnonces.xslt, et uploadons ce fichier dans la bibliothèque Style Library du site.

    image

    Maintenant que le fichier contenant la transformation XSLT est enregistré dans le site SharePoint, nous devons indiquer à la XSLT List View Web Part l’url du fichier xslt à utiliser. Pour cela, dans le navigateur, on modifie les propriétés de la web part et on spécifie l’url relative serveur du fichier dans le champ « Lien XSL » de la section « Divers ».

    image

    A ce stade, on peut travailler dans SharePoint Designer pour modifier la transformation CustomAnnonces.xslt. A chaque modification, on peut enregistrer le fichier et rafraichir son navigateur pour constater le changement.

    Il n’est pas toujours nécessaire de conserver les centaines de lignes de la transformation XSLT par défaut. La transformation native dite « schema independant » s’appuie sur la requête CAML (passée en paramètre de la transformation) pour renvoyer un rendu HTML en fonction des colonnes sélectionnées dans l’affichage. Plus d’informations sur cette logique « schema independant » sont disponibles dans ce billet : SharePoint 2010 List View Blog Series: Part 3 – List View Architecture.

    Pour l’exemple, je ne veux afficher que le champ titre et le champ body avec un rendu HTML très simple sous forme de balises ul / li, et je n’ai pas besoin de conserver les fonctionnalités natives que sont le filtrage dynamique, la multi sélection, etc.

    On peut vider le contenu de la balise principale et redéfinir la transformation comme on le souhaite :

    custom xslt

    Après enregistrement, voici le résultat dans le navigateur :

    rendu personnalisé

     

    Au travers de cet exemple simpliste, nous avons vu comment avec SharePoint Designer :

    - Personnaliser la requête CAML sous-jacente d’une XSLT List View Web Part

    - Personnaliser la transformation XSLT assurant le rendu HTML

    - Externaliser la transformation XSLT dans un fichier séparé

    Avec une mise en forme CSS et un peu de JavaScript, les possibilités de cette web part peuvent devenir très intéressantes puisqu’elle permet de répondre à énormément de besoins métiers sans nécessiter le déploiement de code serveur. Cette web part va sans nul doute faire beaucoup parler d’elle dans les mois à venir.

     

    Arnault Nouvel - Winwise

    SharePoint 2010 : Configuration du courrier sortant et du courrier entrant dans une machine virtuelle

    sharepoint-server

    Utile pour certaines démonstrations, formations, ou pour des développements spécifiques, la configuration du courrier entrant et sortant dans une machine virtuelle SharePoint 2010 n’est plus aussi aisée qu’auparavant. En effet, le serveur mail de Windows Server 2003 n’a pas été porté dans les éditions 2008 et 2008 R2 de Windows Server, seul le serveur SMTP a été conservé.

    Nous allons voir comment configurer le mail sortant et le mail entrant dans une machine virtuelle SharePoint 2010 disposant de l’environnement logiciel suivant :

    • Windows Server 2008 R2 (nom de machine : SPF2010)
    • Active Directory Domain Services (nom de domaine : office14.local)
    • SQL Server 2008 R2
    • SharePoint Foundation 2010
    • Office Professional 2010

    Pour mettre en place le courrier entrant et le courrier sortant sur la même machine virtuelle, l’astuce va consister à utiliser conjointement :

    • un serveur mail complet (SMTP + IMAP) pour les boites mail de nos utilisateurs ainsi que pour le courrier sortant (hMailServer)
    • le serveur SMTP de Windows Server pour le courrier entrant

    Nous allons tout d’abord installer un serveur mail gratuit téléchargeable sur internet : hMailServer. Celui-ci fera office de serveur mail pour nos utilisateurs ainsi que de serveur SMTP pour le courrier sortant.

     

    1. Configuration de hMailServer

    hMailServeur est disponible au téléchargement à l’adresse suivante : http://www.hmailserver.com/

    Installer hMailServer en laissant toutes les options par défaut.

    Une fois hMailServer installé, connectons nous à son interface d’administration intitulée hMailServer Administrator :

    hMailServer-ajout-domaine1

    Via le bouton « Add domain… », ajoutons le domaine office14.local correspondant au domaine de notre Active Directory.

    hMailServer-ajout-domaine1

    La seule information à spécifier est le nom du domaine.

    Configurons maintenant le serveur mail pour y désactiver certains paramètres de sécurité qui pourraient nous gêner pour la suite :

    Dans Settings -> Advanced -> Auto-ban : décocher la case “enabled” et enregistrer.

    hMailServer-autoban

    Dans Settings -> Advanced -> IP Ranges -> Internet, décocher les cases concernant l’authentification du serveur SMTP, puis enregistrer :

    hMailServer-auth

    Notre serveur de messagerie est maintenant opérationnel.

     

    2. Configuration DNS

    Nous allons configurer le DNS afin qu’Outlook puisse configurer automatiquement les adresses de messagerie correspondant au nom de domaine office14.local.

    Avant tout, vérifions dans les propriétés de la carte réseau que son serveur DNS principal est le serveur DNS local

    dns-principal

    Créons ensuite une entrée MX dans le DNS Manager (Tous les programmes -> outils d’administration –> DNS).

    dns-mx

    On laissera le premier champ vide afin de créer une entrée MX par défaut, et on sélectionnera le host correspondant à notre machine virtuelle dans le 2ème champ :

    dns-mx2

    La configuration nécessaire est maintenant effectuée. Créons un compte de messagerie administrator@office14.local pour l’utilisateur OFFICE14\Administrator.

     

    3. Création de boites de messagerie

    hMailServer permet de créer automatiquement des boites de messagerie pour les utilisateurs enregistrés dans l’Active Directory.

    Pour chaque utilisateur de l’Active Directory pour lequel on souhaite créer une boite mail, nous allons suivre la procédure suivante :

    Click droit sur le noeud Accounts, puis “Add AD Account”.

    hMailServer-ajout-utilisateur

    On sélectionne les utilisateurs pour lesquels on souhaite créer une boite de messagerie.

    hMailServer-ajout-utilisateur2

    Pour chaque utilisateur pour lequel on crée boite de messagerie, on inscrira l’adresse de messagerie correspondante dans l’Active Directory :

    AD-user-mail

    On peut maintenant ouvrir Outlook 2010 pour configurer le compte administrator@office14.local.

    outlook-configuration-utilisateur

    Grâce à la configuration DNS mise en place précédemment, l’assistant va configurer automatiquement le compte de messagerie :

    outlook-configuration-utilisateur2

    On répètera cette procédure pour tous les comptes utilisateurs pour lesquels on souhaite disposer d’une boîte de messagerie dans Outlook 2010.

     

    4. Configuration de SharePoint 2010 pour le courrier sortant

    Le courrier sortant permet à SharePoint d’envoyer des emails aux utilisateurs (alertes sur les listes, quotas, etc.). Voyons comment le configurer.

    Dans l’administration centrale de SharePoint, cliquer sur « System Settings » puis « Configure Outgoing E-Mail Settings »

    Indiquer le nom de la machine virtuelle comme sur la capture, ainsi que l’adresse mail au nom de laquelle SharePoint enverra des mails :

    sharepoint-courrier-sortant

    Pour tester, le plus simple est de créer une alerte avec l’utilisateur Administrator sur n’importe quelle liste SharePoint, car lors de sa création un email de confirmation est envoyé instantanément.

    On vérifiera tout d’abord que SharePoint connait l’email associée au compte utilisateur Administrator, dans ses paramètres personnels :

    sharepoint-mail-utilisateur

    Ensuite on crée une alerte sur une liste (la liste Resources dans l’administration centrale par exemple).

    sharepoint-creer-alerte

    On constate alors dans Outlook 2010 que SharePoint a envoyé un message à administrator@office14.local 

    confirmation-alerte

     

    5. Configuration du serveur SMTP pour le courrier entrant

    Le courrier entrant est une fonctionnalité très intéressante de SharePoint puisqu’il permet de créer du contenu dans des listes et bibliothèques SharePoint à partir de mails envoyés par les utilisateurs. Pour le mettre en place, il faudra créer un sous-domaine (ici sharepoint.office14.local) réservé à cette usage et le router vers un serveur SMTP dédié.

    Nous allons pour cela configurer le serveur SMTP de Windows Server. En effet, le SMTP de hMailServer utilise une structure de fichier qui ne pourrait pas convenir à SharePoint.

    Pour installer le serveur SMTP de Windows Server, on utilise l’écran d’ajout de feature Windows :

    smtp-feature

    Une fois la feature installée, on peut ouvrir la console d’administration de IIS 6.0 pour y configurer l’instance SMTP.

    Le port 25 étant déjà utilisé par hMailServer, nous allons devoir configurer le SMTP sur un port différent : ici, le port 6925.

    Clic-droit sur le noeud SMTP Virtual Server –> Properties -> bouton Advanced –> Edit :

    configuration-smtp

    Ensuite, on modifie le nom de domaine par défaut pour qu’il corresponde au sous-domaine que l’on souhaite réserver pour les adresses mails des listes SharePoint. Ici, on utilisera sharepoint.office14.local :

    configuration-smtp-domaine

    On peut alors démarrer le serveur SMTP.

    smtp-start

    Une chose importante reste à faire dans hMailServer. Il faut router les emails dont les destinataires sont xxxxx@sharepoint.office14.local vers le serveur SMTP Windows, en précisant le port 6925, comme indiqué dans la capture :

    hMailServer-routage

     

    6. Configuration de SharePoint 2010 pour le courrier entrant

    Dans l’administration centrale, cliquer sur « System Settings », puis « Configure incoming e-mail settings ». Puisque nous hébergeons localement le serveur SMTP, il suffit de sélectionner le mode automatique et de préciser le sous-domaine choisi pour les adresses mails :

    sharepoint-courrier-entrant

    Pour tester, associons une adresse mail à une bibliothèque de documents. Dans les paramètres de la bibliothèque de documents de l’administration centrale, cliquer sur « Incoming e-mail settings ».

    On peut alors associer une adresse de messagerie à la bibliothèque :

    sharepoint-courrier-entrant-bibliotheque

    Pour tester, nous allons ouvrir Outlook et écrire un mail à notre bibliothèque de documents, avec en pièces jointes les documents que l’on souhaite y envoyer :

    courrier-entrant-test

    Par défaut, le job SharePoint qui va récupérer les messages dans le drop folder du serveur SMTP s’exécute toutes les minutes. Il faut donc patienter quelques secondes avant que le document apparaisse dans la bibliothèque :

    courrier-entrant-test2

     

    Conclusion

    Dans ce billet, nous avons vu comment mettre en place le courrier entrant et le courrier sortant sur une seule machine virtuelle, en utilisant conjointement un serveur mail gratuit et le serveur SMTP de Windows Server. Nous avons aussi vu comment créer des boites de messageries pour les utilisateurs de notre Active Directory, et comment les configurer dans Outlook 2010.

    Je n’ai trouvé aucun serveur mail gratuit permettant de gérer le courrier entrant, n’hésitez pas à laisser un commentaire si vous en connaissez un.

     

    Arnault Nouvel - Winwise

    Plus de Messages Page suivante »

    Les 10 derniers blogs postés

    - Nouveau blog http://bugshunter.net par Blog de Jérémy Jeanson le 07-01-2017, 16:56

    - Office 365: Script PowerShell pour assigner des droits Full Control à un groupe défini par Blog Technique de Romelard Fabrice le 04-30-2017, 09:22

    - SharePoint 20XX: Script PowerShell pour exporter en CSV toutes les listes d’une ferme pour auditer le contenu avant migration par Blog Technique de Romelard Fabrice le 03-28-2017, 17:53

    - Les pièges de l’installation de Visual Studio 2017 par Blog de Jérémy Jeanson le 03-24-2017, 13:05

    - UWP or not UWP sur Visual Studio 2015 ? par Blog de Jérémy Jeanson le 03-08-2017, 19:12

    - Désinstallation de .net Core RC1 Update 1 ou SDK de Core 1 Preview 2 par Blog de Jérémy Jeanson le 03-07-2017, 19:29

    - Office 365: Ajouter un utilisateur ou groupe dans la liste des Site collection Administrator d’un site SharePoint Online via PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-24-2017, 18:52

    - Office 365: Comment créer une document library qui utilise les ContentTypeHub avec PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-22-2017, 17:06

    - [TFS] Supprimer en masse les dépendances à SQL Enterprise ou Developer avant de procéder à une migration par Blog de Jérémy Jeanson le 02-20-2017, 20:30

    - Office 365: Attention au volume utilisé par les fichiers de Thèmes de SharePoint Online par Blog Technique de Romelard Fabrice le 02-07-2017, 18:19