Scrittura di una pagina di accesso personalizzata con autenticazione basata su moduli per SharePoint 2010 - Parte 2
Scrittura di una pagina di accesso personalizzata con autenticazione basata su moduli per SharePoint 2010 - Parte 2
NUOVA INTRODUZIONE DEL POST E COMMENTO APERTO PER IL PROPRIETARIO DEL SITO:
Poiché il sito blog è stato aggiornato all'ultima versione, qualunque essa sia, la formattazione non è più chiara. In genere dedico abbastanza tempo per tentare di ricorreggere il markup che risulta inappropriato (o la totale assenza di markup) nella nuova versione. INVITO A CONTATTARE IL WEBMASTER PER INFORMARLO DI QUANTO SIA DIFFICILE LEGGERE QUESTI POST FORMATTATI IN MODO COSÌ APPROSSIMATIVO. Nel frattempo come soluzione ho allegato un documento di Word con i post originali che sono riuscito a digitare. Chi dice che la tecnologia ha fatto passi da gigante? E ora è possibile iniziare...
Nella prima parte di questa serie, disponibile all'indirizzo https://blogs.msdn.com/b/sharepoint_it/archive/2010/11/16/scrittura-di-una-pagina-di-accesso-personalizzata-con-autenticazione-basata-su-moduli-per-sharepoint-2010-parte-1.aspx, è stato descritto come creare una pagina di accesso completamente nuova con autenticazione basata su moduli. Lo scenario indica come precedere se si desidera eseguire operazioni non disponibili nell'interfaccia utente inclusa, ad esempio l'autenticazione a due fattori. In questo post verrà illustrato uno scenario diverso. In questo caso l'interfaccia utente inclusa è sufficiente, ma si desidera effettuare "ulteriori operazioni" in fase di accesso.
Per questo scenario specifico, si desidera che tutti gli utenti accettino le condizioni per l'utilizzo del sito prima dell'accesso. Per iniziare verrà creata pertanto una nuova pagina di accesso. Verrà aggiunto un gestore dell'evento di accesso e verrà ricercato nell'evento un cookie che indica che gli utenti hanno accettato le condizioni per l'utilizzo. In caso negativo, gli utenti verranno reindirizzati a una pagina in cui potranno selezionare una casella per indicare che accettano le condizioni per l'utilizzo e quindi verranno reindirizzati alla pagina di accesso. Al momento del nuovo l'accesso, verrà ricercato il cookie relativo alle condizioni per l'utilizzo in modo da far accedere gli utenti alla risorsa richiesta, ovvero alla home page, a un documento e così via.
Per iniziare, verrà creata una nuova pagina di accesso. È stata appena aggiunta una nuova pagina ASPX al progetto. In questo progetto sarà necessario aggiungere riferimenti a Microsoft.SharePoint e Microsoft.SharePoint.IdentityModel. Per informazioni dettagliate su come aggiungere il riferimento a Microsoft.SharePoint.IdentityModel, vedere la prima parte, a cui è possibile accedere dal collegamento sopra riportato. Nel code-behind della pagina verranno di nuovo utilizzate le istruzioni using. Vengono riportate di seguito le istruzioni using utilizzate:
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;
Poiché la pagina che viene creata è una pagina di accesso per l'autenticazione basata su moduli, è necessario che la pagina erediti da FormsSignInPage. La dichiarazione della classe è simile alla seguente:
public partial class AgreeLogin : FormsSignInPage
La prima operazione che verrà definita nel codice è l'override dell'evento di caricamento della pagina. Verrà aggiunto un gestore dell'evento di accesso per il controllo di accesso ASP.NET della pagina. Viene riportato di seguito l'override del caricamento della pagina:
protected override void OnLoad(EventArgs e)
{
try
{
base.OnLoad(e);
this.signInControl.LoggingIn +=
new LoginCancelEventHandler(signInControl_LoggingIn);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
Una nota: questo codice è stato inserito in un blocco try...catch perché in caso di errori nel markup della pagina, come illustrato più avanti, verrà generato un errore quando viene chiamato base.OnLoad(e). Successivamente viene illustrata l'implementazione del gestore dell'evento LoggingIn:
void signInControl_LoggingIn(object sender, LoginCancelEventArgs e)
{
//look for a cookie; if not there then redirect to our accept terms page
const string AGREE_COOKIE = "SignedTermsAgreement";
try
{
//we want to check for our cookie here
HttpCookieCollection cookies = HttpContext.Current.Request.Cookies;
HttpCookie ck = cookies[AGREE_COOKIE];
if (ck == null)
//user doesn't have the cookie indicating that they've signed the
//terms of use so redirect them
Response.Redirect("AgreeTerms.aspx?" +
Request.QueryString.ToString());
}
catch (Exception ex)
{
Debug.WriteLine("There was an error processing the request: " +
ex.Message);
}
}
Quando viene eseguito l'accesso, viene controllato innanzitutto che il cookie indichi che l'utente ha accettato le condizioni per l'utilizzo del sito. Se il cookie non è presente, l'utente verrà reindirizzato alla pagina AgreeTerms.aspx. La stringa di query completa ricevuta dalla pagina di accesso viene inclusa perché indica la risorsa richiesta dall'utente quando ha selezionato la pagina di accesso, in modo che sia possibile indirizzarlo a tale risorsa dopo la sottoscrizione delle condizioni per l'utilizzo. È importante ricordare a questo punto che è necessario apportare una modifica al file web.config dell'applicazione Web SharePoint per accedere in modo anonimo alla pagina con le condizioni per l'utilizzo. Altrimenti, in caso di una risorsa protetta, come qualsiasi pagina del sito, si verificherebbe un ciclo infinito. In altri termini, verrebbe rilevato che non è presente il cookie, l'utente verrebbe reindirizzato alla pagina AgreeTerms.aspx che, essendo protetta, reindirizzerebbe alla pagina di accesso personalizzata e così via di seguito all'infinito. Il file web.config pertanto è stato modificato per includere questa voce prima del tag di chiusura </system.web>:
<location path="_layouts/AgreeTerms.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
È ora possibile accedere alla pagina AgreeTerms.aspx senza essere autenticati. Per il momento non verrà esaminata l'interfaccia utente della pagina, ma il code-behind della pagina è piuttosto semplice:
protected void SubmitBtn_Click(object sender, EventArgs e)
{
const string AGREE_COOKIE = "SignedTermsAgreement";
try
{
//make sure the checkbox is checked
if ((AgreeChk.Checked) && (Request.Browser.Cookies))
{
//create the cookie
HttpCookie ck = new HttpCookie(AGREE_COOKIE, "true");
//set the expiration so it's persisted
ck.Expires = DateTime.Now.AddYears(3);
//write it out
HttpContext.Current.Response.Cookies.Add(ck);
//get the src attribute from the query string and redirect there
Response.Redirect(Request.QueryString["Source"]);
}
else
StatusLbl.Text = "You must agree to the terms of use before continuing.";
}
catch (Exception ex)
{
string msg = "There was an error processing the request: " + ex.Message;
Debug.WriteLine(msg);
StatusLbl.Text = msg;
}
}
Dovrebbe essere abbastanza chiaro. Se si seleziona la casella, viene fornito il cookie e tramite Response.Redirect l'utente viene reindirizzato all'origine inizialmente richiesta. In questo modo verrà visualizzata di nuovo la pagina di accesso e questa volta all'accesso verrà individuato il cookie e funzionerà tutto correttamente. Se non vengono accettate le condizioni per l'utilizzo, non sarà possibile procedere con le operazioni.
Questo è tutto dal punto di vista della codifica, ma è necessario tenere conto di un altro elemento MOLTO importante, ovvero il markup della pagina di accesso. Come già affermato precedentemente, se il markup non è corretto, si verificheranno diversi problemi. Viene riportato pertanto di seguito il markup con cui iniziare:
<%@ 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" %>
<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
<SharePoint:EncodedLiteral ID="ClaimsFormsPageTitle" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/>
</asp:Content>
<asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">
<SharePoint:EncodedLiteral ID="ClaimsFormsPageTitleInTitleArea" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/>
</asp:Content>
<asp:Content ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage" />
<asp:login id="signInControl" FailureText="<%$Resources:wss,login_pageFailureText%>" runat="server" width="100%">
<layouttemplate>
<asp:label id="FailureText" class="ms-error" runat="server"/>
<table class="ms-input">
<colgroup>
<col width="25%"/>
<col width="75%"/>
</colgroup>
<tr>
<td nowrap="nowrap"><SharePoint:EncodedLiteral ID="EncodedLiteral3" runat="server" text="<%$Resources:wss,login_pageUserName%>" EncodeMethod='HtmlEncode'/></td>
<td><asp:textbox id="UserName" autocomplete="off" runat="server" class="ms-long ms-login-textbox"/></td>
</tr>
<tr>
<td nowrap="nowrap"><SharePoint:EncodedLiteral ID="EncodedLiteral4" runat="server" text="<%$Resources:wss,login_pagePassword%>" EncodeMethod='HtmlEncode'/></td>
<td><asp:textbox id="password" TextMode="Password" autocomplete="off" runat="server" class="ms-long ms-login-textbox"/></td>
</tr>
<tr>
<td colspan="2" align="right"><asp:button id="login" commandname="Login" text="<%$Resources:wss,login_pagetitle%>" runat="server" /></td>
</tr>
<tr>
<td colspan="2"><asp:CheckBox id="RememberMe" text="<%$SPHtmlEncodedResources:wss,login_pageRememberMe%>" runat="server" /></td>
</tr>
</table>
</layouttemplate>
</asp:login>
</asp:Content>
L'unico elemento effettivamente da modificare è la prima riga, la direttiva @Page.
<%@ 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 parte evidenziata in giallo deve essere cambiata nel nome sicuro dell'assembly personalizzato.
Dopo aver raggruppato e compilato tutto questo codice, sarà possibile registrare l'assembly nella GAC e copiare la pagina o le pagine ASPX nella directory Layouts. L'ultimo passaggio prima della verifica consiste nel cambiare la pagina di accesso dell'area dell'applicazione Web in cui viene utilizzata l'autenticazione basata su moduli. A tale scopo, è sufficiente accedere ad Amministrazione centrale, Gestione applicazioni, Gestisci applicazioni Web. Selezionare l'applicazione Web e quindi fare clic sul pulsante Provider di autenticazione sulla barra degli strumenti. Fare clic sull'area che si desidera cambiare e quindi nella finestra di dialogo visualizzata fare clic sul pulsante di opzione Pagina di accesso personalizzata e immettete l'URL della pagina di accesso. In questo esempio l'URL è _layouts/AgreeLogin.aspx. Dopo aver salvato le modifiche, si è pronti per accedere al sito.
Viene riportato di seguito il risultato ottenuto accedendo al sito con le pagine personalizzate. Mi auguro che questo post possa rivelarsi utile per ottenere lo stesso risultato.
1. Accesso iniziale
2. Pagina Condizioni per l'utilizzo (Terms Of Use)
3. Infine l'accesso al sito
Questo è un post di blog localizzato. L'articolo originale è disponibile in Writing A Custom Forms Login Page for SharePoint 2010 Part 2.