Traduction

Cet article est la traduction la plus fidèle possible de l'article original de Steve Peschka, Writing A Custom Forms Login Page for SharePoint 2010 Part 2.

Écriture d'une page de connexion personnalisée avec authentification par formulaire pour SharePoint 2010 - partie 2

Dans la partie 1 de cette série, j'ai décrit comment créer une page de connexion entièrement nouvelle avec authentification par formulaire. Le scénario à la base de cela est la nécessité de recourir à quelque chose qui n'est pas disponible par le biais de l'interface utilisateur prédéfinie, par exemple pour une authentification à deux facteurs. Dans cet article, je vais parcourir un scénario différent. Dans le cas présent, l'interface utilisateur prédéfinie convient, mais nous souhaitons effectuer « quelque chose » de supplémentaire au moment de la connexion.

Pour ce scénario particulier, je veux que tous les utilisateurs acceptent les conditions d'utilisation du site avant d'y accéder pour la première fois. Donc, je vais commencer par créer une page de connexion. Je vais ajouter un gestionnaire pour l'événement de connexion et, dans cet événement, je vais voir s'il existe un cookie qui indique que les utilisateurs ont accepté les conditions d'utilisation. S'ils n'ont pas accepté, je les redirigerai alors vers une page qui leur permet de cocher une case indiquant qu'ils acceptent les conditions, et ils seront ensuite redirigés vers la page de connexion. Lorsqu'ils seront de nouveau connectés, je pourrai voir qu'ils possèdent le cookie des conditions d'utilisation et je pourrai donc simplement les rediriger vers la ressource qu'ils ont demandée - la page d'accueil, un document, etc.

Pour commencer, je vais créer ma nouvelle page de connexion. J'ai simplement ajouté une nouvelle page ASPX à mon projet. Dans ce projet, je vais devoir ajouter des références à Microsoft.SharePoint et à Microsoft.SharePoint.IdentityModel. Pour les détails sur la façon dont on ajoute la référence à Microsoft.SharePoint.IdentityModel, reportez-vous à la partie 1. Dans le code behind de ma page, je vais réutiliser un groupe d'instructions using. Voici celles que j'ai utilisées :

 
Sélectionnez
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.IdentityModel.Pages;
using System.Diagnostics;

Étant donné que la page que je suis en train d'écrire est une page de connexion pour une authentification par formulaire, elle doit hériter de FormsSignInPage. Ma déclaration de classe ressemble à ceci :

 
Sélectionnez
public partial class AgreeLogin : FormsSignInPage 

La première chose que je vais effectuer dans le code sera de surcharger l'événement Load. Dans cet événement, je vais ajouter un gestionnaire pour l'événement de connexion pour le contrôle de connexion ASP.NET de la page. Voici à quoi ressemble la surcharge de l'événement Load :

 
Sélectionnez
  1. protected override void OnLoad(EventArgs e) 
  2. { 
  3. try 
  4.        { 
  5.              base.OnLoad(e); 
  6.              this.signInControl.LoggingIn +=  
  7.                    new LoginCancelEventHandler(signInControl_LoggingIn); 
  8. } 
  9. catch (Exception ex) 
  10.        { 
  11.               Debug.WriteLine(ex.Message); 
  12.        } 
  13. } 

Une remarque ici - j'ai utilisé un bloc try…catch, car si vous foirez le balisage de la page, ce que j'expliquerai ci-dessous, vous obtiendrez une erreur lorsque base.OnLoad(e) est appelé. Je vais maintenant vous montrer l'implémentation du gestionnaire d'événements LoggingIn :

 
Sélectionnez
  1. void signInControl_LoggingIn(object sender, LoginCancelEventArgs e) 
  2. { 
  3. //look for a cookie; if not there then redirect to our accept terms page 
  4.        const string AGREE_COOKIE = "SignedTermsAgreement"; 
  5.      try 
  6.        { 
  7.        //we want to check for our cookie here 
  8.               HttpCookieCollection cookies = HttpContext.Current.Request.Cookies; 
  9.               HttpCookie ck = cookies[AGREE_COOKIE]; 
  10.               if (ck == null) 
  11.               //user doesn't have the cookie indicating that they've signed the 
  12.               //terms of use so redirect them 
  13.               Response.Redirect("AgreeTerms.aspx?" +  
  14.                      Request.QueryString.ToString()); 
  15. } 
  16.        catch (Exception ex) 
  17.        { 
  18.        Debug.WriteLine("There was an error processing the request: " +  
  19.               ex.Message); 
  20.        } 
  21. } 

Donc, ce que je suis en train de faire ici est que lorsque je commence à me connecter, je vais d'abord chercher mon cookie qui indique que l'utilisateur a accepté les conditions d'utilisation du site. Si je ne trouve pas le cookie, je vais alors rediriger l'utilisateur vers ma page AgreeTerms.aspx. Je vais inclure la chaîne de requête complète que la page de connexion a reçue, car elle m'indique la ressource que l'utilisateur était en train de demander lorsqu'il est arrivé sur la page de connexion, cela me permettra de savoir vers où les rediriger une fois qu'ils auront accepté les conditions d'utilisation. Une chose importante à se rappeler ici est que je dois apporter une modification à mon fichier web.config pour mon application Web SharePoint afin que la page des conditions d'utilisation soit accessible de façon anonyme. Sinon, s'il s'agissait d'une ressource sécurisée à l'image d'une page sur deux dans le site, je serais pris dans une boucle sans fin - j'aurais dit que vous ne possédez pas le cookie, je vous aurais redirigé vers la page AgreeTerms.aspx, mais puisqu'il s'agit d'une ressource sécurisée, vous seriez indéfiniment redirigé vers la page de connexion personnalisée. Donc, j'ai modifié le fichier web.config de manière à inclure l'entrée suivante juste avant la balise </system.web> fermante :

 
Sélectionnez
<location path="_layouts/AgreeTerms.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>

Donc, maintenant, il est possible d'atteindre la page AgreeTerms.aspx sans être authentifié. Je ne vais pas vous ennuyer avec l'interface utilisateur de la page maintenant, mais sachez qu'elle est assez simple dans le code behind de cette page :

 
Sélectionnez
  1. protected void SubmitBtn_Click(object sender, EventArgs e) 
  2. { 
  3. const string AGREE_COOKIE = "SignedTermsAgreement"; 
  4. try 
  5.        { 
  6.               //make sure the checkbox is checked 
  7. if ((AgreeChk.Checked) && (Request.Browser.Cookies)) 
  8.               { 
  9.                      //create the cookie 
  10. HttpCookie ck = new HttpCookie(AGREE_COOKIE, "true"); 
  11. //set the expiration so it's persisted 
  12. ck.Expires = DateTime.Now.AddYears(3); 
  13. //write it out 
  14. HttpContext.Current.Response.Cookies.Add(ck); 
  15. //get the src attribute from the query string and redirect there 
  16. Response.Redirect(Request.QueryString["Source"]); 
  17. } 
  18. else 
  19. StatusLbl.Text = "You must agree to the terms of use before continuing."; 
  20. } 
  21. catch (Exception ex) 
  22.        { 
  23.               string msg = "There was an error processing the request: " + ex.Message; 
  24.               Debug.WriteLine(msg); 
  25.               StatusLbl.Text = msg; 
  26. } 
  27. }  

Cela devrait être assez clair - si vous cochez la case, je vous donne le cookie et je vous redirige vers la source initialement demandée avec un « Response.Redirect ». Cette opération vous redirige vers la page de connexion et cette fois, lorsque vous vous connectez, vous allez voir le cookie et tout fonctionnera facilement. Si vous n'acceptez pas les conditions d'utilisation, vous n'irez nulle part.

Le tour est joué d'un point de vue codage, mais il y a un autre truc que vous devez absolument maîtriser, à savoir le balisage de la page de connexion. Comme je l'ai décrit précédemment, si le balisage est incorrect, vous allez vous retrouver avec toutes sortes de problèmes. Donc, pour commencer, voici le balisage sur lequel vous devez vous appuyer :

 
Sélectionnez
  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AgreeLogin.aspx.cs" Inherits="FormsLoginPage.AgreeLogin, FormsLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf32e76ff986e00f" MasterPageFile="~/_layouts/simple.master" %> 
  2.   
  3. <%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>  
  4. <%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>  
  5. <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %>  
  6. <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
  7. <asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server"> 
  8.     <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitle" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/> 
  9. </asp:Content> 
  10. <asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server"> 
  11.     <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitleInTitleArea" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/> 
  12. </asp:Content> 
  13. <asp:Content ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/> 
  14. <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server"> 
  15. <SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage" /> 
  16.  <asp:login id="signInControl" FailureText="<%$Resources:wss,login_pageFailureText%>" runat="server" width="100%"> 
  17.     <layouttemplate> 
  18.         <asp:label id="FailureText" class="ms-error" runat="server"/> 
  19.         <table class="ms-input"> 
  20.           <colgroup> 
  21.           <col width="25%"/> 
  22.           <col width="75%"/> 
  23.           </colgroup> 
  24.         <tr> 
  25.             <td nowrap="nowrap"><SharePoint:EncodedLiteral ID="EncodedLiteral3" runat="server" text="<%$Resources:wss,login_pageUserName%>" EncodeMethod='HtmlEncode'/></td> 
  26.             <td><asp:textbox id="UserName" autocomplete="off" runat="server" class="ms-long ms-login-textbox"/></td> 
  27.         </tr> 
  28.         <tr> 
  29.             <td nowrap="nowrap"><SharePoint:EncodedLiteral ID="EncodedLiteral4" runat="server" text="<%$Resources:wss,login_pagePassword%>" EncodeMethod='HtmlEncode'/></td> 
  30.             <td><asp:textbox id="password" TextMode="Password" autocomplete="off" runat="server" class="ms-long ms-login-textbox"/></td> 
  31.         </tr> 
  32.         <tr> 
  33.             <td colspan="2" align="right"><asp:button id="login" commandname="Login" text="<%$Resources:wss,login_pagetitle%>" runat="server" /></td> 
  34.         </tr> 
  35.         <tr> 
  36.             <td colspan="2"><asp:CheckBox id="RememberMe" text="<%$SPHtmlEncodedResources:wss,login_pageRememberMe%>" runat="server" /></td> 
  37.         </tr> 
  38.         </table> 
  39.     </layouttemplate> 
  40.  </asp:login> 
  41. </asp:Content> 

La seule et unique chose à réellement modifier est la toute première ligne, à savoir la directive @Page.

 
Sélectionnez
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AgreeLogin.aspx.cs" Inherits="FormsLoginPage.AgreeLogin, FormsLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf32e76ff986e00f" MasterPageFile="~/_layouts/simple.master" %> 

La partie en rouge « Inherits="FormsLoginPage.AgreeLogin, FormsLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf32e76ff986e00f" » doit être remplacée par le nom fort de votre assembly personnalisé.

Une fois toutes ces informations agencées et compilées, il vous suffit d'inscrire votre assembly dans le GAC et de copier votre(vos) page(s) ASPX dans le répertoire des dispositions. La dernière étape avant un premier véritable test consiste à modifier la page de connexion associée à la zone d'application Web dans laquelle vous utilisez l'authentification par formulaire. Accédez à l'Administration centrale, puis cliquez sur « Gestion des applications », ensuite sur « Gérer les applications Web ». Sélectionnez votre application Web, puis cliquez sur le bouton « Fournisseurs d'authentification » dans la barre d'outils. Cliquez sur le lien de la zone à modifier, puis dans la boîte de dialogue qui apparaît, cliquez sur la case d'option « Page de connexion personnalisée » et saisissez l'URL de votre page de connexion. Dans mon cas, il s'agissait de _layouts/AgreeLogin.aspx. Enregistrez vos modifications et vous êtes alors prêt à vous connecter à votre site.

Conclusion

Enfin, voici à quoi cela ressemblait lorsque je me suis connecté à mon site avec mes pages personnalisées - j'espère que cet article vous aidera à accomplir la même chose !

1. Connexion initiale

Image non disponible

2. Page des conditions d'utilisation

Image non disponible

3. Enfin, connexion au site

Image non disponible

Remerciements

Je tiens ici à remercier Steve Peschka de m'avoir autorisé à traduire son article.
Je remercie Jean-Michel Ormes pour sa relecture technique et ses propositions.
Je remercie également ClaudeLELOUP pour sa relecture orthographique et ses propositions.