Artículo original publicado el domingo, 1 de mayo de 2011

NOTA AL MARGEN: Una vez más aplausos para el magnífico equipo que dirige este sitio. Esta última versión ahora tiene incluso MENOS formato de Word y Visual Studio que antes. No creí que fuera posible hacer este sitio peor de lo que ya estaba, y ahora han destrozado, qué digo, han superado mis expectativas al respecto. ¡Enhorabuena! Espero seguir su ejemplo pronto y deshacerme de Word, Excel y PowerPoint por el Bloc de notas. De todos modos, ¿quién necesita el formato?

Recientemente tuve la necesidad de omitir la página de selección del proveedor que se obtiene al habilitar varios proveedores de autenticación en una sola zona en SharePoint 2010. El escenario que tenía era bastante sencillo, pero la metodología se puede ampliar bastante para que admita escenarios mucho más complicados. En mi caso, tenía la autenticación de Windows y la autenticación basada en formularios (FBA) habilitadas en una zona. Sin embargo, siempre quise poder redirigir a los usuarios para que usen FBA en este escenario concreto.

Lograr esto fue relativamente sencillo mediante los siguientes pasos:

  1. HAGA UNA COPIA DE SEGURIDAD de default.aspx en la carpeta C:\Archivos de programa\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN.
  2. Abra Visual Studio y cree un nuevo proyecto de biblioteca de clases de Windows.
  3. Agregue referencias a System.Web, Microsoft.SharePoint.dll y Microsoft.SharePoint.IdentityModel.dll. Lamentablemente, el ensamblado del modelo de identidad solo se encuentra en la GAC, por lo que tuve que obtener una copia de este y colocarlo en la raíz de mi unidad para agregar la referencia. Para ver una sugerencia de cómo encontrarlo y copiarlo, puede consultar mi entrada que describe cómo obtenerlo aquí: http://blogs.technet.com/b/speschka/archive/2010/07/21/writing-a-custom-forms-login-page-for-sharepoint-2010-part-1.aspx.
  4. Asigne un nombre seguro al ensamblado porque se va a ir a la GAC.
  5. Agregue una nueva página ASPX al proyecto. Sinceramente, considero que la manera más fácil de hacerlo es copiar una página desde un proyecto de aplicación web ASP.NET existente; de este modo, se pueden copiar los archivos .aspx, .aspx.cs y .aspx.designer.cs al mismo tiempo. Recuerde que en este caso queremos un archivo denominado “default.aspx” y resultará más fácil si aún no hay código escrito en él y el marcado es mínimo en la página.
  6. En el código subyacente (archivo .aspx.cs), cambie el espacio de nombres para que coincida con el espacio de nombres del proyecto actual.
  7. Cambie la clase para que herede de Microsoft.SharePoint.IdentityModel.Pages.MultiLogonPage.
  8. Invalide el evento OnLoad. Lo que sucede cuando los usuarios visitan un sitio con varios proveedores de autenticación habilitados es que son remitidos primero a la página /_login/default.aspx (la que describí arriba en el punto 1). En esa página, un usuario seleccionará el proveedor de autenticación que desea usar y, a continuación, se le redirigirá a la página correcta para autenticarse. En este escenario, como mencioné, siempre prefiero que los usuarios se autentiquen con FBA, por lo que siempre deseo enviarlos a /_forms/default.aspx. Si lleva a cabo paso a paso un inicio de sesión normal, verá que se le redirige a /_login/default.aspx, realiza la selección, luego vuelve a /_login/default.aspx y, por último, se le redirige a la página de inicio de sesión correcta. Por lo tanto, en este caso simplemente comprobé si se estaba devolviendo mi página de inicio de sesión. Si no es así, sé que todavía no se ha hecho ninguna selección para el proveedor de autenticación. Por lo tanto, simplemente enumero todos los valores de cadena de consulta y, a continuación, los anexo a /_forms/default.aspx y redirijo al usuario allí. Este es el aspecto que tiene todo el fragmento de código:

protected override void OnLoad(EventArgs e)

{

   base.OnLoad(e);

 

   try

   {

       //if this isn't a postback, then the user hasn't selected which

       //auth provider they want to use

       //in this case we want to always refer the person to forms login

       if (!this.IsPostBack)

       {

          //grab all the query string parameters

          System.Text.StringBuilder qp = new System.Text.StringBuilder(2048);

 

          foreach (string key in this.Request.QueryString.Keys)

          {

             qp.Append(key + "=" + this.Request.QueryString[key] + "&");

          }

 

          //redirect to the forms login page

          this.Response.Redirect("/_forms/default.aspx?" + qp.ToString());

       }

   }

   catch (Exception ex)

   {

       Debug.WriteLine(ex.Message);

   }

}

  1. Ahora compile la aplicación para que pueda obtener el nombre seguro para esta y agregarlo al marcado de default.aspx.
  2. Pegue lo siguiente en default.aspx; solo tendrá que cambiar la clase de la que hereda la página (que se resalta más abajo). Tenga en cuenta que lo único que hice fue simplemente copiarlo desde /_login/default.aspx y reemplazar el valor Inherits con la información de mi clase personalizada:

<%@ Page Language="C#" CodeBehind="Default.aspx.cs" Inherits="MultiAuthLoginPage._Default,MultiAuthLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=907bf41ebba93579" MasterPageFile="~/_layouts/simple.master" %>

<%@ Assembly Name="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register Tagprefix="SharepointIdentity" Namespace="Microsoft.SharePoint.IdentityModel" Assembly="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>

<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>

<%@ 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 ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

                <SharePoint:EncodedLiteral runat="server"  EncodeMethod="HtmlEncode" Id="ClaimsLogonPageTitle" />

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">

                <SharePoint:EncodedLiteral runat="server"  EncodeMethod="HtmlEncode" Id="ClaimsLogonPageTitleInTitleArea" />

</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>

<asp:Content ID="Content4" ContentPlaceHolderId="PlaceHolderMain" runat="server">

<SharePoint:EncodedLiteral runat="server"  EncodeMethod="HtmlEncode" Id="ClaimsLogonPageMessage" />

<br />

<br />

<SharepointIdentity:LogonSelector ID="ClaimsLogonSelector" runat="server" />

</asp:Content> 

  1. Registre el ensamblado en la GAC.
  2. Copie la nueva página default.aspx personalizada en la carpeta C:\Archivos de programa\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN. UNA VEZ MÁS, HAGA UNA COPIA DE SEGURIDAD DE LA ORIGINAL ANTES DE HACER ESTO.
  3. Realice los pasos 1, 11 y 12 en cada front-end web del conjunto o granja de servidores.

Eso es todo. Lo probé con un nombre de inicio de sesión de usuario estándar, además de abrir los documentos directamente desde los clientes de Microsoft Office 2010. Otra cosa que es importante mencionar aquí: esto cambia el comportamiento de TODAS las aplicaciones web de la granja de servidores. Reitero que se trata de un ejemplo sencillo. Sin embargo, fácilmente podría mirar el nombre de host de la solicitud (que se asigna a la aplicación web) y tomar decisiones de autenticación diferentes en función de la aplicación web a la que se tiene acceso o incluso la colección de sitios. Obviamente, puede tomar otras decisiones en función de la información que tenga acerca del usuario actual. Las clases HttpRequest.Context.Current, Page.Request y Page.Response pueden ofrecerle mucha información para tomar este tipo de decisiones.

 

Esta entrada de blog es una traducción. Puede consultar el artículo original en Bypassing the Multi Authentication Provider Selection Page in SharePoint 2010