sábado, 13 de marzo de 2010

Autenticación basada en notificaciones (II)

En una entrada anterior os comencé a hablar del concepto notificación, o claim, y del sistema de autenticación basado en notificaciones. En esta segunda entrada de la serie os voy a explicar cómo configurar una aplicación web de SharePoint 2010 para hacer uso de estas capacidades. La información la obtuve de aquí, pero me encontré con algún que otro problema, así que en esta entrada os explico paso a paso todas las acciones que realicé.

Para empezar, abriremos la Administración Central de SharePoint y, dentro de la sección Administración de aplicaciones seleccionaremos la opción Administrar aplicaciones web.

image

Una vez allí, crearemos una nueva aplicación web desde la cinta o ribbon.

image

En la ventana modal que nos aparece seleccionaremos Autenticación basada en notificaciones.

image

En la misma ventana veremos que, por defecto, la autenticación de Windows está habilitada. Esto lo mantendremos igual pero también habilitaremos la autenticación basada en formularios, tal y como se indica en la imagen. Notad que he usado los nombres LDAPMembershipProvider y LDAPRoleProvider para los proveedores de suscripciones y de roles respectivamente. Necesitaremos estos dos nombres más adelante. Podéis modificar el resto de las propiedades (puerto, encabezado de host, nombre de la base de datos, etc.) según vuestras necesidades. Una vez estéis listos, aceptad el formulario para que se cree la aplicación web. No creéis todavía la colección de sitios.

image

A continuación necesitamos hacer ciertos cambios a algunos ficheros de configuración web.config. Lo primero que haremos es identificar estos ficheros:

Fichero 1 (el web.config de la aplicación web que acabamos de crear): lo podemos encontrar, por defecto, en la carpeta c:\inetpub\wwwroot\wss\VirtualDirectories\X, donde X es una combinación entre el número de puerto y el encabezado de host que hemos escogido en el paso anterior. Si habéis cambiado la carpeta por defecto de IIS, siempre podréis utilizar el siguiente método para abrir la carpeta contenedora de vuestra aplicación web: accedéis a la administración de IIS, pulsáis con el botón derecho del ratón sobre vuestra aplicación web y seleccionáis explorar.

image

Fichero 2 (el web.config de la Administración Central de SharePoint): para encontrarlo podemos utilizar el método anterior sobre la aplicación web SharePoint Central Administration v4.

Fichero 3 (el web.config del Security Token Service (STS)): para encontarlo podéis utilizar el método anterior sobre el directorio virtual SecurityTokenServiceApplication dentro de la aplicación web SharePoint Web Services.

image

Muy bien, una vez tengamos localizados nuestros tres ficheros, y atención porque los cambios a realizar en cada uno de estos son diferentes, procederemos a su configuración.

En el fichero 1 (nuestra aplicación web), buscaremos la sección:

<membership defaultProvider="i">
  <providers>
    <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  </providers>
</membership>

y la cambiaremos por:

<membership defaultProvider="i">
  <providers>
    <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    <add name="LDAPMembershipProvider"
           type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
           server="msdn.2010rc.local"
           port="389"
           useSSL="false"
           userDNAttribute="distinguishedName"
           userNameAttribute="sAMAccountName"
           userContainer="CN=Users,DC=2010rc,DC=local"
           userObjectClass="person"
           userFilter="(&amp;(ObjectClass=person))"
           scope="Subtree"
           otherRequiredUserAttributes="sn,givenname,cn" />
  </providers>
</membership>

Notad que hay algunos elementos que deberéis modificar en vuestro entorno. Lo primero, como nombre del proveedor he utilizado LDAPMembershipProvider, que es el nombre que he especificado a la hora de crear la aplicación web. Además, el FQDN de la granja donde estoy trabajando es 2010rc.local y el nombre del servidor de dominio se llama MSDN, así que todas las propiedades que hacen referencia a la cadena de conexión LDAP apuntarán a msdn.2010rc.local. Prestad especial atención al atributo userContainer que cambia un poco respecto a lo que encontramos en el artículo de Technet. Todos estos cambios deberán tenerse en cuenta en todas las modificaciones que hagamos en pasos sucesivos. Tenedlo en cuenta si copias el contenido directamente de esta página.

Además de este cambio deberemos buscar la siguiente sección:

<roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
  <providers>
    <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  </providers>
</roleManager>

y cambiarla por:

<roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
  <providers>
    <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    <add name="LDAPRoleProvider"
           type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
           server="msdn.2010rc.local"
           port="389"
           useSSL="false"
           groupContainer="DC=2010rc,DC=local"
           groupNameAttribute="cn"
           groupNameAlternateSearchAttribute="samAccountName"
           groupMemberAttribute="member"
           userNameAttribute="sAMAccountName"
           dnAttribute="distinguishedName"
           groupFilter="(&amp;(ObjectClass=group))"
           userFilter="(&amp;(ObjectClass=person))"
           scope="Subtree" />
  </providers>
</roleManager>

En el fichero 2 (Adminitración Central), buscaremos la siguiente sección (*):

<roleManager>
  <providers>
  </providers>
</roleManager>
<membership>
  <providers>
  </providers>
</membership>

y cambiarla por lo siguiente:

<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider" >
  <providers>
      <add name="LDAPRoleProvider"
           type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
           server="msdn.2010rc.local"
           port="389"
           useSSL="false"
           groupContainer="DC=2010rc,DC=local"
           groupNameAttribute="cn"
           groupNameAlternateSearchAttribute="samAccountName"
           groupMemberAttribute="member"
           userNameAttribute="sAMAccountName"
           dnAttribute="distinguishedName"
           groupFilter="((ObjectClass=group)"
           userFilter="((ObjectClass=person)"
           scope="Subtree" />
  </providers>
</roleManager>
<membership defaultProvider="AspNetSqlMembershipProvider">
  <providers>
      <add name="LDAPMembershipProvider"
           type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
           server="msdn.2010rc.local"
           port="389"
           useSSL="false"
           userDNAttribute="distinguishedName"
           userNameAttribute="sAMAccountName"
           userContainer="CN=Users,DC=2010rc,DC=local"
           userObjectClass="person"
           userFilter="(ObjectClass=person)"
           scope="Subtree"
           otherRequiredUserAttributes="sn,givenname,cn" />
  </providers>
</membership>

(*) Nota: si no encontramos esta sección dentro del fichero podemos añadir directamente el código anterior justo antes de la linea </system.web>.

Finalmente, en el fichero 3 (STS), añadiremos dentro de la sección <configuration> la siguiente sección:

<system.web>
    <membership>
        <providers>
            <add name="LDAPMembershipProvider"
                 type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                 server="msdn.2010rc.local"
                 port="389"
                 useSSL="false"
                 userDNAttribute="distinguishedName"
                 userNameAttribute="sAMAccountName"
                 userContainer="CN=Users,DC=2010rc,DC=local"
                 userObjectClass="person"
                 userFilter="(&amp;(ObjectClass=person))"
                 scope="Subtree"
                 otherRequiredUserAttributes="sn,givenname,cn" />
        </providers>
    </membership>
    <roleManager enabled="true" >
        <providers>
            <add name="LDAPRoleProvider"
                 type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                 server="msdn.2010rc.local"
                 port="389"
                 useSSL="false"
                 groupContainer="DC=2010rc,DC=local"
                 groupNameAttribute="cn"
                 groupNameAlternateSearchAttribute="samAccountName"
                 groupMemberAttribute="member"
                 userNameAttribute="sAMAccountName"
                 dnAttribute="distinguishedName"
                 groupFilter="(&amp;(ObjectClass=group))"
                 userFilter="(&amp;(ObjectClass=person))"
                 scope="Subtree" />
        </providers>
    </roleManager>
</system.web>

Una vez hecho esto ya estamos preparados para crear la colección de sitios. Accediendo a la Administración Central de SharePoint y seleccionando la opción Crear colecciones de sitios dentro de la sección Administración de aplicaciones.

 image

Ahora llega el momento de explicaros por qué hemos decidido esperar a este momento para crear la colección de sitios. Si seleccionáis la aplicación web que acabamos de configurar e indicamos los datos básicos para nuestra colección de sitios (título, descripción, plantilla, etc.) veremos un cambio a la hora de seleccionar el administrador de la colección de sitios veremos una pantalla similar a la siguiente:

image

Cómo véis, sin hacer nada especial podemos seleccionar desde un mismo punto usuarios de los dos mecanismos de autenticación que tenemos configurados para nuestra aplicación web: Directorio Activo y FBA. Podemos aprovechar este momento para seleccionar un administrador principal y uno secundario, cada uno de ellos escogidos de un proveedor diferente. De esa manera podremos autenticarnos con los dos métodos desde el inicio. El apartado de administradores de la colección de sitios querará más o menos así:

image

A partir de este momento, cuando accedamos al portal que hemos creado nos aparecerá una ventana de inicio de sesión como la de la siguiente figura. Esta ventana, evidentemente, es totalmente personalizable. Podemos cambiar la apariencia gráfica o incluso podemos cambiar el comportamiento para permitir, por ejemplo, que los usuarios que accedan desde una IP interna se autentiquen directamente contra Directorio Activo mientras que el resto sean redirigidos a una página con el típico formulario de nombre de usuario y contraseña.

image

Una vez introduzcamos nuestra credenciales (sea cual sea la opción de autenticación que tomemos) accederemos a la colección de sitios que acabamos de crear, con las mismas credenciales puesto que estamos usando LDAP contra el mismo directorio activo para autenticarnos por formularios pero con unos atributos totalmente diferentes. Os recomiendo, para continuar, que pongáis en práctica un desarrollo que realicé para un artículo anterior para comprobar los atributos que tenemos en cada uno de los casos.

8 comentarios:

Unknown dijo...

Muchas gracias por este estupendo post, he seguido los pasos tal como describes y efectivamente, ahora el sistema me da la opción de iniciar sesión con un u otro modo de login.!!

Damián Alvarez dijo...

Hola muy buen post.. Tengo una pregunta.. Yo tengo una aplicaciòn web creada con el modo clasico de autenticación, ademas esta tiene creada una extension en la zona Internet.. Ahora cuando quiero configurar la autenticacion form para esta extenciòn el checkBox Formularios me aparece deshabilitado?.. Como puede hacer para habilitarlo? debo cambiar a modo Autenticacion por Notificaciones la aplicaciòn Web? Eh buscado hacer eso pero no eh tenido exito... Espero que puedas ayudarme,.. Desde ya muchas gracias..

Damian

David Martos dijo...

Hola Damián. Siento comunicarte que desde la versión RTM, SharePoint 2010 no soporta el escenario que describes, así que tendrás que pasar a Claims-Based authentication (http://technet.microsoft.com/en-us/library/cc262350.aspx).

En su día configuré ese escenario utilizando el comando stsadm y todo parecía funcionar correctamente (pese a que mediante la interfaz no era posible) pero fue para una demo. Siendo un escenario no soportado yo no me lo plantearía a no ser que tengas una razón de peso.

Saludos,

Damián Alvarez dijo...

Hola ... Con respecto a la pregunta que te hice antes, eh encontrado poder cambiar el modo de autenticacion via PowerShell. Cambia el modo de authenticación sin problemas pero me ha pasado que la aplicación en algunas ocaciones deja de andar (error 404) asique no confio en ese comando. Asique cree otra Web App con la autenticaciòn correcta y use el Content Deployment job para exportar los datos. Una consulta, al usar notificaciones me obliga que habilite la NTLM sino el crawl de búsqueda no crawlea esta web app. entonces la duda es como configuro el formulario de login para que no me pregunte sin quiero autenticarme con Windows o Form? sino que siempre se Form. Disculpas por el tamaño del comentario.. Saludos.. y muchas gracias.. damián

David Martos dijo...

Hola Damián,

puedes probar con esto: http://jsiegmund.wordpress.com/2010/05/20/sp2010-creating-a-mixed-mode-login-page-for-claims-based-authentication/

Espero que te ayude

tripticoii - alra dijo...

David: gracias por tu publicación, pero quería hacerte 2 preguntas... 1) Testando en mi computadora, vi qeu no tengo en el IIS 'SecurityTokenServiceApplication'
2) no entendi bien el concepto del parámetro 'userContainer' y 'groupContainer'...
Podrías darme una mano con eso.. te lo agradecería un monton. GRACIAS.. y una buena semana

Anónimo dijo...

Primeramente gracias por compartir tus conocimientos, a sido de mucha ayuda, te pido tu ayuda para aclarar algunas dudas que se generaron al realizar el ejercio la primera es como permitir que los usuarios que no tengan cuenta en DC logren acceder al sitio? y la segunda cual seria el objetivo de tener a un usuario con 2 tipo de autenticación...

Él dijo...

En el articulo se usa un proveedor de identidades LDAP, así que podrías dar acceso a cualquier usuario que existiera en cualquier sistema que usase ese protocolo, no únicamente directorio activo. De todas maneras, podrías utilizar un proveedor de identidades basado en SQL Server siguiendo el siguiente artículo: http://msdn.microsoft.com/en-us/library/gg252020(v=office.14).aspx

Respecto a tu segunda pregunta, las razones son muchas. Por ponerte un ejemplo, imagina que internamente usas AD para tus usuarios y quieres dar acceso a usuarios externos sin pagar una licencia de AD para cada uno de ellos. En ese caso te haría falta un sistema doble de autenticación. Por otro lado, podrías querer dar acceso a tu sitio mediante credenciales de Twitter, Facebook, Live o similares.