Creación de una página de inicio de sesión de formularios personalizada para SharePoint 2010 Parte 1

Creación de una página de inicio de sesión de formularios personalizada para SharePoint 2010 Parte 1

En SharePoint 2007 crear una página de inicio de sesión personalizada para un sitio de autenticación basada en formularios (FBA) no era demasiado complicado. Era necesario saber algunas cosas, la mayoría de las cuales no eran específicas a SharePoint, y algunas sugerencias para que el formulario de inicio de sesión tenga el aspecto de una página de diseño de SharePoint estándar. Pero en general, si conocía ASP.NET y la clase FormsAuthentication no tenía ningún problema. En SharePoint 2010, en cambio, las cosas se complican un poco.

En esta entrada analizaremos un escenario de una página de inicio de sesión personalizada. En este ejemplo hemos decidido que necesitamos una página de inicio de sesión totalmente personalizada y que no solo cambiaremos la apariencia sino que además queremos una UI totalmente distinta. Por ejemplo, quizá necesitamos captar las credenciales de pertenencia que se usan para iniciar sesión y que alguien escriba un identificador de autenticación secundario, como en el caso de SecurID. En ese caso, tendremos un par de cuadros de texto en una página ASP.NET para el nombre de usuario y la contraseña y deberemos captarlos y permitir que nuestro usuario inicie sesión mediante programación.

Lo más importante para recordar es que ya no necesitaremos de un viejo amigo, la clase FormsAuthentication. Esto se debe a que en SharePoint 2010 los usuarios FBA son usuarios de notificaciones. Por eso, aunque quizá piense que está trabajando con un usuario de pertenencia y proveedor de rol ASP.NET estándar, en realidad estos objetos tienen un shell de autenticación basada en notificaciones. Por esta razón, necesitamos usar algunas de las clases de notificaciones de SharePoint para llevar a cabo el proceso de inicio de sesión de FBA.

¡Pero antes una advertencia! Normalmente, de alguna manera u otra, antes de publicar algo en mi blog estoy seguro o confirmo con alguien en la medida de lo posible que sí, que efectivamente es la forma correcta, adecuada o admitida de hacer algo. En este caso, intenté reiteradamente que alguien confirmara este enfoque pero no lo logré. He usado este código para un proyecto en el que estaba trabajando y funciona, pero no quiero que a alguien le dé un ataque si la "policía" del código le dice más adelante que debe modificarlo para buscar una manera mejor o más apropiada de hacer las cosas. Pero basta de excusas y veamos el código.

Antes de empezar, hay un par de referencias que vamos a necesitar que probablemente no ha usado antes. La primera es Microsoft.SharePoint.Security.dll, y está en el subárbol 14 de la carpeta ISAPI. La otra es más complicada y es la razón principal por la que hice la advertencia anterior. Necesita una referencia a Microsoft.SharePoint.IdentityModel.dll. No obstante, si va a agregar referencias, no encontrará fácilmente este ensamblado. Eso es lo que me hace sentir algo avergonzado y cauteloso a la vez. Como describí en otra entrada, he comprobado que lo más conveniente es buscarlo en el sistema de archivos, copiarlo a una ubicación fácil de encontrar y agregar la referencia a la versión copiada. En mi caso, como soy de la vieja escuela, por lo general voy a un símbolo del sistema, cambio a la raíz de la unidad de disco y hago un "dir Microsoft.SharePoint.IdentityModel.dll /s" para encontrarlo. Una vez que lo tenga, probablemente desee agregar un pequeño grupo de instrucciones Using:

using System.Web.Security;

using System.IdentityModel.Tokens;

using Microsoft.SharePoint;

using Microsoft.SharePoint.IdentityModel;

Ahora que nos deshicimos de esa pequeña dificultad, cuando llamo a la clase de notificaciones para validar las credenciales del usuario FBA que el usuario escribió, debo indicarle qué proveedor de pertenencia y de rol debería usar. Simplemente necesita un nombre. En mi caso en particular, había escrito un proveedor de pertenencia y de rol personalizado para lo que estaba haciendo, por lo que simplemente enumeré todos los proveedores que mi aplicación web conocía hasta que encontré el mío:

//get the provider names for our type

string userProviderName = string.Empty;

string roleProviderName = string.Empty;

//get the membership provider name

foreach (MembershipProvider p in Membership.Providers)

{

if (p.GetType().Equals(typeof(Microsoft.SE.AnonProvider.Users)))

       {

       userProviderName = p.Name;

              break;

       }

}

//get the role provider name

foreach (RoleProvider rp in System.Web.Security.Roles.Providers)

{

if (rp.GetType().Equals(typeof(Microsoft.SE.AnonProvider.Roles)))

       {

       roleProviderName = rp.Name;

              break;

       }

}

 

¡Perfecto! Tengo los nombres de mis proveedores. Ahora necesitamos tomar el nombre de usuario y la contraseña y obtener de vuelta un SecurityToken. Para ello, vamos a usar la clase SPSecurityContext. Tiene un método diseñado justamente para hacer este inicio de sesión de autenticación basada en formularios; si se realiza correctamente, devuelve un SecurityToken. De lo contrario, devuelve null. Aquí puede verse cómo se autentican las credenciales del usuario:

SecurityToken tk = SPSecurityContext.SecurityTokenForFormsAuthentication(

new Uri(SPContext.Current.Web.Url), userProviderName, roleProviderName,

          UserNameTxt.Text, PasswordTxt.Text);

 

He pasado una dirección URL para el sitio que estoy intentando autenticar. Le he indicado el nombre de mis proveedores de pertenencia y de rol y paso los valores de nombre de usuario y de contraseña escritos en los cuadros de texto en mi página de inicio de sesión. Ahora necesito comprobar que mi SecurityToken no es null. Si no lo es, debo escribir un token de sesión. Eso se hace con el SPFederationAuthenticationModule. Después de escribir el token de sesión, puedo continuar y redirigir el usuario a la página o recurso que solicitó. Aquí está el resto del código que hace eso:

if (tk != null)

{

//try setting the authentication cookie

SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;

fam.SetPrincipalAndWriteSessionToken(tk);

       //look for the Source query string parameter and use that as the redirection

       string src = Request.QueryString["Source"];

       if (!string.IsNullOrEmpty(src))

       Response.Redirect(src);

}

else

{

StatusLbl.Text = "The credentials weren't valid or didn't work or something.";

}

 

Como ven, después de haber hecho todo correctamente, simplemente capto el parámetro de cadena de consulta de origen, ya que nos indica a dónde se dirigía originalmente el usuario. Una vez que lo tengo, simplemente envío al usuario a donde quería ir.

Espero que esto le sea útil para empezar. Sé que fue realmente complicado encontrar la documentación sobre cómo conviene hacer esto cuando la busqué. En la parte 2 veremos cómo hacerlo de otra forma en un escenario distinto. En ese escenario, queremos que el usuario acepte los términos de uso del sitio web antes de usarlo por primera vez. Para ello, deberemos extender la página de inicio de sesión de base y agregar un controlador en el momento del inicio de sesión.

Esta entrada de blog es una traducción. Encontrará el artículo original en Writing A Custom Forms Login Page for SharePoint 2010 Part 1