Finalmente, una manera ÚTIL de federar con Windows Live y SharePoint 2010 usando OAuth y SAML

Artículo original publicado el jueves, 1 de marzo de 2012

Muchos usuarios me han hablado en el pasado acerca de la federación de SharePoint con Windows Live. A simple vista parece una idea bastante buena – Windows Live cuenta con millones de usuarios, todo el mundo inicia sesión con su dirección de correo electrónico, lo cual es algo que usamos mucho como notificación de identidad, es un gran servicio escalable y tenemos diversas instrucciones por ahí fuera sobre cómo hacerlo, ya sea directamente o mediante ACS (Access Control Service). Por tanto, ¿por qué se podría estar de mal humor por usarlo con SharePoint? Bueno, para aquellos de ustedes que lo hayan probado antes, saben que, cuando federa con Windows Live, nunca se le devuelve la dirección de correo electrónico de un usuario como notificación. Todo lo que obtiene es un identificador de Windows Live especial denominado PUID. Por lo que yo sé, “PUID” podría hacer referencia a “Prácticamente GUID”, porque casi es eso lo que parece y lo útil que resulta. 

Por ejemplo, si FEDERA con Windows Live, ¿cómo agrega a alguien a un sitio? Tiene que obtener su PUID y, a continuación, agregar el PUID a un grupo de SharePoint o un nivel de permiso. ¿Realmente conoce a alguien que sepa cuál es su PUID (si conoce a esta persona, es hora de que encuentre otra actividad para su tiempo libre). Aunque mágicamente se diera el caso de que sepa cuál es su PUID, ¿qué utilidad cree que tiene si está tratando de conceder derechos a los usuarios para diferentes colecciones de sitios? ¿Cree realmente que alguien más le elegiría en una línea de PUID (o selector de personas, como puede que sea el caso)? Por supuesto que no, por lo que me siento más frustrado.

De hecho pensé que podíamos probar aquí una solución más utópica con ACS. ACS es realmente fantástico a la hora de proporcionar enlaces listos para usar para varios proveedores de identidad como Windows Live, Google, Yahoo y Facebook. Con Facebook incluso añaden algo de magia y realmente usan OAuth para autenticar y, a continuación, devolver un conjunto de notificaciones SAML. ¡Genial! Con lo cual, ¿por qué no hacen eso también con Windows Live? Windows Live admite OAuth ahora por lo que parece que hay una oportunidad para que ocurra algo valioso finalmente. Bueno, a pesar de desear que fuera así, la gente de ACS no ha venido aquí al rescate. Y ahí radica el punto interesante de este preámbulo – finalmente me he decidido a escribir uno yo mismo y ese es el motivo de esta publicación.

¿Por qué nos preocupamos por OAuth? Bueno, al contrario que con el PUID, lo obtiene cuando federa directamente con Windows Live, la compatibilidad de OAuth en Windows Live le permite obtener MUCHA más información acerca del usuario, entre la que se incluye – espérela – su dirección de correo electrónico. Por tanto, el plan de ataque aquí es básicamente el siguiente:

  1. Escribir un proveedor de identidad personalizado usando Windows Identity Foundation (WIF).
  2. Cuando a una persona se le redirige a nuestro STS, si no se han autenticado ya los redirigimos de nuevo a Windows Live. Tiene que crear “una aplicación” con Windows Live para ello pero lo explicaré con más detenimiento posteriormente.
  3. Una vez autenticados, se redirigen de nuevo al STS personalizado. Cuando regresan, la cadena de consulta incluye un token de inicio de sesión; dicho token se puede intercambiar para un token de acceso.
  4. El STS entonces realiza otra solicitud a Windows Live con el código de inicio de sesión y pide un token de acceso.
  5. Cuando recibe de nuevo el token de acceso, realiza una solicitud final a Windows Live con el token de acceso y pide información básica acerca del usuario (explicaré lo que recibimos posteriormente).
  6. Una vez que recibimos la información de Windows Live, usamos nuestro STS personalizado para crear un conjunto de notificaciones SAML para el usuario y lo rellenamos con la información del usuario. A continuación, redirigimos de nuevo a cualquier aplicación que nos solicite autenticar para comenzar para permitirle realizar lo que desea con los tokens de SAML. En este caso concreto he probado mi STS con una aplicación ASP.NET estándar así como una aplicación web de SharePoint 2010.

Por tanto…se adjunta todo el código fuente a esta publicación pero todavía hay algo de configuración que realizar, y tendrá que volver a compilar la aplicación con el id. de aplicación y el secreto que obtiene de Windows Live. Sin embargo, aparte de copiar y pegar allí realmente no hay nada de código que tenga que escribir para empezar. Ahora vamos a avanzar por todo lo que necesita para usarlo.

Crear un certificado de firma de tokens

Tendrá que crear un certificado que usará para firmar sus tokens de SAML. No hay nada especial acerca del certificado que usa para firmar certificados, aparte de necesitar asegurarse de que dispone de la clave privada para ello. En mi caso tengo Servicios de certificados instalados en mi dominio por lo que solo abrí el Administrador de IIS y seleccioné la opción para crear un dominio de certificado. Seguí el asistente y antes de que lo supiera tenía un certificado nuevo completo con clave privada. Para este proyecto, he creado un certificado denominado livevbtoys. 

Como explicaré en la siguiente sección, cuando las solicitudes inicialmente llegan al STS, el usuario es un usuario anónimo. A fin de usar dicho certificado para firmar tokens de SAML, necesitamos conceder al proceso de IIS acceso a la clave privada para dicho certificado. Cuando llega una solicitud anónima al proceso de IIS la identidad es Servicio de red. Para proporcionarle derechos a la clave tiene que hacer lo siguiente:

  1. Inicie el MMC
  2. Agregue el complemento Certificados. Seleccione el almacén del equipo para el equipo local.
  3. Abra el almacén de certificados personales y encuentre el certificado que ha creado para firmar tokens de SAML. Si lo ha creado como he explicado anteriormente, el certificado se encontrará allí de forma predeterminada. Si lo crea de alguna otra manera puede que tenga que agregarlo a dicho almacén.
  4. Haga clic con el botón secundario en el certificado y elija la opción para Administrar claves privadas.
  5. En la lista de usuarios con derechos a las claves, agregue Servicio de red y proporciónele derechos de lectura.

Tenga en cuenta que si no lo hace correctamente, al tratar de ejecutar la aplicación, puede obtener un error que indique algo así como “el conjunto de claves no existe”. Eso solo significa que el proceso de IIS no tenía derechos suficientes para la clave privada, por lo que no pudo usarla para firmar el token de SAML.

Instalar la aplicación y los ensamblados requeridos

La instalación de la aplicación en este sentido realmente solo implica la creación de una aplicación ASP.NET en IIS, la copia de los bits y el asegurarse de que la versión más reciente de WIF está instalada. Una vez que hace que se configura y funciona en un servidor, por supuesto, desearía agregar uno o más servidores adicionales para asegurarse de que tiene una solución tolerante a errores. Sin embargo, solo haré un recorrido por la configuración necesaria en el servidor único.

No me adentraré en la manera de crear una aplicación ASP.NET en IIS. Puede hacerlo con Visual Studio, en el Administrador de IIS, etc. 

NOTA: si usa el código proporcionado aquí y solo abre el proyecto en Visual Studio, indica que el host o el sitio no existen. Eso se debe a que está usando el nombre desde mi servidor. La manera más sencilla de corregirlo es simplemente editar el archivo WindowsLiveOauthSts.sln de manera manual y cambiar los valores de https que se encuentran allí por los valores que existen realmente en el entorno.

Una vez que se haya creado realmente hay pocas cosas que desee asegurarse de que realiza.

  1. Agregue PassiveSTS.aspx como el documento predeterminado en el Administrador de IIS para el sitio web de STS.
  2. Cambie la configuración de autenticación para la aplicación en IIS de manera que todos los tipos de autenticación estén deshabilitados excepto para autenticación autónoma.
  3. El STS se tiene que ejecutar encima de SSL, por lo que tendrá que adquirir un certificado adecuado para ello y asegurarse de actualizar los enlaces en el servidor virtual de IIS donde se usa la aplicación de STS personalizada.
  4. Asegúrese que coloca la huella digital de su certificado de firma de tokens en el atributo de huella digital del elemento de adición en la sección trustedIssuers del archivo web.config de su usuario de confianza (si NO está usando SharePoint para prueba). Si usa el asistente para agregar referencia de STS en Visual Studio, hará esto para usted.

Esa debería ser toda la configuración necesaria en IIS.

Actualizar y crear el proyecto de STS personalizado Project

El archivo zip adjunto incluye un proyecto de Visual Studio 2010 denominado WindowsLiveOauthSts. Una vez que IIS se configura y que ha actualizado el archivo WindowsLiveOauthSts.sln como se ha descrito anteriormente, debería poder abrir el proyecto correctamente en Visual Studio. Una de las primeras cosas que tendría que hacer es actualizar las constantes CLIENT_ID y CLIENT_SECRET en la clase PassiveSTS.aspx.cs. Las obtiene cuando crea una nueva aplicación de Windows Live. Aunque no voy a tratar eso de manera detenida (porque hay personas de Windows Live que pueden ayudarle con eso), permítame señalarle la ubicación a la que puede ir para crear su aplicación de Windows Live:  https://manage.dev.live.com/Applications/Index?wa=wsignin1.0. Además, cuando cree su aplicación, asegúrese de establecer el dominio de redirección en la ubicación en la que se hospeda su STS personalizado, es decir, https://myserver.foo.com.

Ahora que tiene el id. y el secreto, esto es lo que se tiene que actualizar en la aplicación:

  1. Actualice las constantes CLIENT_ID y CLIENT_SECRET en la clase PassiveSTS.aspx.cs.
  2. En el archivo web.config actualice el SigningCertificateName en la sección appSettings. Tenga en cuenta que no tiene que cambiar la configuración de IssuerName pero, obviamente, puede hacerlo si lo desea.
  3. Actualice el certificado de firma de tokens para el documento FederationMetadata.xml en el proyecto de STS. Una vez que haya seleccionado el certificado que va a usar, puede usar la aplicación test.exe incluida en esta publicación para obtener el valor de cadena para el certificado. Se tiene que copiar para reemplazar los dos valores de elemento de X509Certificate en federationmetadata.xml.

Hay otro aspecto que conviene señalar aquí – en el archivo CustomSecurityTokenService.cs tiene la opción de configurar una variable denominada enableAppliesToValidation en verdadero y, a continuación, proporcionar una lista de direcciones URL que pueden usar este STS personalizado. En mi caso he elegido no restringirla de ninguna manera, de modo que dicha variable sea falsa. Si no desea bloquear su STS personalizado debería cambiarlo ahora. Una vez que se hayan realizado todos estos cambios puede volver a compilar la aplicación y estará lista para su funcionamiento.

Otra nota aquí: también he incluido una aplicación ASP.NET de muestra que he usado para prueba mientras creaba esto. Se encuentra en un proyecto denominado LiveRP. Realmente no voy a tratarlo aquí; basta decir que puede encontrarlo ahí si desea probar cosas. Solo tiene que recordar cambiar la huella digital para el certificado de firma de tokens de STS como se ha descrito anteriormente.

Configuración de SharePoint

En este punto todo está configurado y debería estar funcionando para el STS personalizado. Lo único que queda por hacer realmente es crear un nuevo emisor SPTrustedIdentityToken en SharePoint y configurar una aplicación web nueva o existente para usarlo. Sin embargo, hay algunas cuestiones que debería saber acerca de la configuración del SPTrustedIdentityTokenIssuer; voy a proporcionarle el PowerShell que he usado para crear el mío y, a continuación, lo explicaré:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\livevbtoys.cer")

New-SPTrustedRootAuthority -Name "SPS Live Token Signing Certificate" -Certificate $cert

 

$map = New-SPClaimTypeMapping -IncomingClaimType "https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming

$map2 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/id" -IncomingClaimTypeDisplayName "WindowsLiveID" -SameAsIncoming

$map3 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/full_name" -IncomingClaimTypeDisplayName "FullName" -SameAsIncoming

$map4 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/first_name" -IncomingClaimTypeDisplayName "FirstName" -SameAsIncoming

$map5 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/last_name" -IncomingClaimTypeDisplayName "LastName" -SameAsIncoming

$map6 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/link" -IncomingClaimTypeDisplayName "Link" -SameAsIncoming

$map7 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/gender" -IncomingClaimTypeDisplayName "Gender" -SameAsIncoming

$map8 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/locale" -IncomingClaimTypeDisplayName "Locale" -SameAsIncoming

$map9 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/updated_time" -IncomingClaimTypeDisplayName "WindowsLiveLastUpdatedTime" -SameAsIncoming

$map10 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/account" -IncomingClaimTypeDisplayName "AccountName" -SameAsIncoming

$map11 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/accesstoken" -IncomingClaimTypeDisplayName "WindowsLiveAccessToken" -SameAsIncoming

$realm = "https://spslive.vbtoys.com/_trust/"

$ap = New-SPTrustedIdentityTokenIssuer -Name "SpsLive" -Description "Window Live oAuth Identity Provider for SAML" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2,$map3,$map4,$map5,$map6,$map7,$map8,$map9,$map10,$map11 -SignInUrl "https://spr200.vbtoys.com/WindowsLiveOauthSts/PassiveSTS.aspx" -IdentifierClaim "https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"

Estos son los aspectos que conviene tener en cuenta:

  1. Como he indicado anteriormente, he creado un certificado denominado livevbtoys.cer con el que firmar mis tokens, por lo que lo he agregado a mi lista SPTrustedRootAuthority y lo he asociado con mi emisor de tokens.
  2. He creado asignaciones de notificaciones para todas las notificaciones que mi STS personalizado está devolviendo. Como puede ver, es SIGNIFICATIVAMENTE MAYOR Y MEJOR de lo que podría obtener si solo federara directamente en Windows Live. Otro aspecto que hay que tener en cuenta aquí – Incluyo el token de acceso que obtengo de Windows Live como notificación aquí. Aunque eso funciona con Facebook, no lo he probado por lo que no puedo decir con seguridad si Windows Live le permitirá volver a usarlo o no. Sin embargo, ese puede ser el tema de una futura publicación.
  3. El valor de $realm es muy importante. Debe señalar al sitio raíz de su aplicación web e incluir el directorio /_trust/. Si no lo hace de manera correcta, obtendrá 500 errores de SharePoint cuando se le redirija de nuevo tras la autenticación.
  4. El parámetro –SignInUrl cuando se crea el emisor de token es la dirección URL absoluta a la página PassiveSTS.aspx para mi STS personalizado.

Así es básicamente - una vez que está configurado todavía está usando los proveedores de notificaciones y el selector de personas listos para usar, por lo que no tendrá ninguna capacidad de búsqueda, como podría esperar. Concede derechos a las personas con las direcciones de correo electrónico que usan para iniciar sesión en Windows Live. De hecho podría ampliar este ejemplo y usar además el proveedor de notificaciones de Azure sobre el que hablé aquí en el blog:  https://blogs.msdn.com/b/sharepoint_sp/archive/2012/03/07/proveedor-de-notificaciones-personalizado-azure-para-el-proyecto-de-sharepoint-project-parte-1.aspx. Eso significa que estaría usando este STS para habilitarle para autenticar con Windows Live y que se le devuelvan algunas notificaciones de SAML reales y, a continuación, estaría usando el proyecto de notificaciones personalizadas de Azure para agregar dichos usuarios autenticados al almacén de directorios de Azure y al selector de personas para elegirlos.

Las imágenes lo dicen todo, por lo que así se muestra cuando llega por primera vez al sitio de SharePoint y autentica con Windows Live:

Cuando inicie sesión por primera vez, le preguntará si está bien compartir su información con la aplicación de STS personalizada. No hay nada aquí por lo que preocuparse - eso es lo que suele suceder con los permisos de OAuth estándar. Este es el aspecto que tiene; tenga en cuenta que muestra los datos que estoy pidiendo en el STS – podría pedir un conjunto completamente diferente de datos si lo deseara. Solo tiene que mirar el SDK de OAuth de Windows Live para averiguar lo que tiene que cambiar y la manera de hacerlo:

Una vez que acepte, se le redirigirá de vuelta al sitio de SharePoint. En este ejemplo estoy usando el elemento web de notificaciones de SharePoint sobre el que escribí aquí en el blog:  https://blogs.technet.com/b/speschka/archive/2010/02/13/figuring-out-what-claims-you-have-in-sharepoint-2010.aspx. Puede ver todas las notificaciones que obtengo de Windows Live mediante OAuth ahora que ahora tengo como notificaciones SAML gracias a mi STS personalizado, así como el hecho de que he iniciado sesión con mi dirección de correo electrónico de Windows Live que he creado para este proyecto (desde el control de inicio de sesión, esquina superior derecha):

 

Esta entrada de blog es una traducción. Puede consultar el artículo original en Finally A USEFUL Way to Federate With Windows Live and SharePoint 2010 Using OAuth and SAML