Share via


Escrevendo uma página de logon de formulários personalizados para o SharePoint 2010 parte 2

Escrevendo uma página de logon de formulários personalizados para o SharePoint 2010 parte 2

NOVO PREFÁCIO PARA ESTA POSTAGEM E COMENTÁRIO ABERTO PARA O PROPRIETÁRIO DO SITE:

Como o site do blog foi atualizado, a formatação aumentou muito. Em geral, passo um tempo razoável tentando entender a marcação (ou a falta dela) fornecida por essa nova versão. AVALIE A POSSIBILIDADE DE CONTATAR O WEB MASTER E INFORMAR SOBRE A DIFICULDADE DE LER AS POSTAGENS QUE TIVEREM FORMATAÇÃO ESTRANHA! Por enquanto, tentarei anexar um documento do Word com a postagem original digitada sempre que possível. Quem disse que a tecnologia não atrapalha?? Então aqui vamos nós...

Na parte 1 desta série, que você pode encontrar em https://blogs.msdn.com/b/sharepoint_br/archive/2010/11/19/escrevendo-uma-p-225-gina-de-logon-de-formul-225-rios-personalizados-para-o-sharepoint-2010-parte-1.aspx, descrevi como criar uma página de logon de formulários inteiramente novos. A motivação disso se dá quando você precisa de algo além do que está disponível na IU pronta – por exemplo, autenticação de dois fatores. Nesta postagem, vamos conhecer um cenário diferente. Nesse caso, a IU pronta funciona bem, mas queremos fazer mais alguma coisa na hora do logon.

Para este cenário em particular, quero que todos os usuários concordem com os termos de uso para o site antes de acessá-lo. Então vou começar criando uma nova página de logon. Adicionarei um manipulador para logon no evento e, nesse evento, verificarei se há um cookie que diga que o usuário concordou com os termos de uso. Se ele não tiver concordado, eu o redirecionarei para uma página em que possa marcar uma caixa de seleção dizendo que concorda e depois ele será redirecionado para a página de logon. Quando o usuário fizer logon de novo, verei que ele tem o cookie dos termos de uso, portanto, posso enviar para ele o recurso solicitado – a home page, um documento etc.

Para começar, vou criar uma nova página de logon. Acabei de adicionar uma nova página ASPX para o meu projeto. Neste projeto, precisarei adicionar referências ao Microsoft.SharePoint e ao Microsoft.SharePoint.IdentityModel. Para obter detalhes sobre como adicionar a referência ao Microsoft.SharePoint.IdentityModel, consulte a parte 1, que eu vinculei acima. No código por trás da minha página, utilizarei algumas instruções de uso novamente. Aqui estão as que usei

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;

Como a página que estou escrevendo é uma página de logon para autenticação baseada em formulários, ela precisa herdar de FormsSignInPage. Minha declaração de classe fica parecida com esta:

public partial class AgreeLogin : FormsSignInPage

A primeira coisa que farei no código é substituir o evento Load da página. Nesse ponto, adicionarei um manipulador ao evento de logon do controle ASP.NET Login da página. A substituição de Page Load fica parecida com esta:

protected override void OnLoad(EventArgs e)

{

try

       {

             base.OnLoad(e);

             this.signInControl.LoggingIn +=

                   new LoginCancelEventHandler(signInControl_LoggingIn);

}

catch (Exception ex)

       {

       Debug.WriteLine(ex.Message);

       }

}

Uma observação aqui: coloquei isso em um bloco try…catch porque se você errar a marcação de página, que explicarei abaixo, provocará um erro quando base.OnLoad(e) for chamado. Em seguida, continuarei e mostrarei a implementação do manipulador de eventos 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);

       }

}

Então o que estou fazendo aqui é que, quando começo a fazer o logon, primeiro procuro meu cookie que diz que o usuário concordou com os termos de uso do site. Se não encontrar o cookie, vou redirecionar o usuário para minha página AgreeTerms.aspx. Estou incluindo a cadeia de caracteres de consulta completa que a página de logon recebeu porque ela informa qual recurso o usuário estava solicitando quando acessou a página de logon, portanto, saberei para onde enviá-lo novamente depois que ele concordar com os termos de uso. É importante lembrar que preciso fazer uma alteração no meu web.config para meu aplicativo Web do SharePoint, de modo que a página dos termos de uso possa ser acessada anonimamente. Caso contrário, se ele era um recurso protegido, como todas as outras páginas do site, eu ficaria preso em um loop infinito; digamos que se você não tivesse o cookie, eu o redirecionaria para a página AgreeTerms.aspx, mas como ele é protegido, eu seria redirecionado para minha página de logon personalizado outra vez e assim sucessivamente. Então, eu modifiquei o web.config para incluir essa entrada logo abaixo da marca </system.web> de fechamento:

<location path="_layouts/AgreeTerms.aspx">

<system.web>

<authorization>

<allow users="*" />

</authorization>

</system.web>

</location>

Então agora posso acessar minha página AgreeTerms.aspx sem ser autenticado. Não vou incomodá-lo com a IU da página agora, mas o código por trás dessa página é bastante simples:

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;

}

}

Isso deve estar bastante claro: se você marcar a caixa, eu lhe darei o cookie e usarei Response.Redirect para levá-lo à fonte solicitada originalmente. Isso o levará de volta à página de logon e, dessa vez, quando fizer logon, veremos o cookie e tudo funcionará maravilhosamente bem. Se você não concordar com os termos de uso, não irá para lugar nenhum.

Isso é tudo o que há para saber, de uma perspectiva de codificação, mas há uma outra coisa que é SUPERIMPORTANTE ter: a marcação da página de logon. Conforme descrevi antes, se a marcação estiver errada, você terá todo o tipo de dificuldade. Então, para começar, aqui está a marcação que deve ser usada no início:

<%@ 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>

A única coisa que você realmente deseja alterar é a primeira linha, a política @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" %>

A parte realçada em amarelo deve ser alterada para o nome forte do assembly personalizado.

Depois que você reunir e compilar tudo isso, bastará registrar o assembly no GAC e copiar as páginas ASPX no diretório de layouts. A última etapa antes de realmente tentar isso é alterar a página de logon para a zona do aplicativo Web em que você está usando FBA. Vá para a administração central, Gerenciamento de Aplicativos, Gerenciar aplicativos Web. Selecione o aplicativo Web e clique no botão Provedores de Autenticação na barra de ferramentas. Clique no link para a zona que você deseja alterar e, na caixa de diálogo que surge, clique no botão de opção Página de Entrada Personalizada e insira a Url para a página de logon. No meu caso era _layouts/AgreeLogin.aspx. Salve suas alterações e você estará pronto para fazer logon no site.

Finalmente, o código teria esta aparência quando eu fizer logon no site com minhas páginas personalizadas; espero que esta postagem o ajude a fazer o mesmo!

1. Logon inicial

2. Página dos termos de uso

3. Por fim o acesso ao site

 

Esta é uma postagem de blog traduzida. O artigo original pode ser encontrado em Escrevendo uma página de logon de formulários personalizados para o SharePoint 2010 parte 2