XWiki: autenticando con Viafirma

Es de todos conocidos los grandes beneficios de usar una Wiki, para tener organizado y actualizado una gran cantidad de información y contenido, de forma que pueda ser rápidamente consultada y actualizada. Sin ninguna razón especial más allá de la simple curiosidad, vamos a poner como ejemplo en este caso una “implementación” wiki basada en Java (XWiki) y vamos a conseguir de forma sencilla que los usuarios puedan logarse con su Certificado Digital o DNI electrónico (DNIe).

Como no podría ser de otra forma, vamos a hacer uso del servicio de autenticación de la plataforma Viafirma, sirviéndonos de su cliente de autenticación, apoyándonos en su espectacular matriz de compatibilidad, además mantendremos el acceso por usuario/contraseña habitual de XWiki. Para realizar esta integración nos hemos basado principalmente en la documentación que podemos encontrar en las páginas oficiales de ambas plataformas, por un lado tenemos a Viafirma y por otro lado la web para desarrolladores de XWiki Development Zone

Primero una idea de lo que queremos hacer:

Dentro del formulario de login de XWiki, pondremos un enlace a una url dentro del propio XWiki que sea de la forma:
http://xwikiserver/.../viafirma.login

Esta URL será capturada dentro de la XWiki por un Filter que enviará al usuario automáticamente a Viafirma, que será el encargado de pedir el certificado digital al usuario y analizarlo (validarlo), tras esto enviará al usuario nuevamente a la XWiki (Viafirma coloca en la Session de esta petición el resultado de la validación del Certificado y será XWiki el encargado de tratar ese resultado) con una url con la forma:

http://xwikiserver/.../viafirmaAuthentication

El Request de esta URL será capturado por un Servlet que extiende al ViafirmaClientServlet, que nos proporciona el cliente de Viafirma, capturando de sesión el UsuarioGenericoViafirma que se ha obtenido. Este usuario aún no es un “usuario XWiki”. Este mismo Servlet se encargará de capturar la dirección a la que el usuario inicialmente quería acceder en XWiki y lo redirigirá allí de nuevo, siempre y cuando los resultados de Viafirma hayan sido válidos.

Por otro lado, extenderemos la clase XWikiAuthServiceImpl que implementa el servicio básico de autenticación de XWiki, introduciendo la posibilidad de realizar el Login en XWiki a partir de un UsuarioGenericoViafirma que tenemos en Sesión, para esto usaremos el API nativo de XWiki.

Por simplicidad para este ejemplo he adoptado la siguiente política de logado: dada una persona con NIF 12345678Z, su “Usuario XWiki” correspondiente será XWiki.12345678Z, es decir, debe existir un usuario dado de alta en XWiki cuyo Login coincida con el DNI de la persona. Cuando tengamos un UsuarioGenericoViafirma, consultamos su NIF y le preguntamos la XWiki a través de su API si existe usuario con ese Login. ¿Podría hacerse de forma más elaborada? Por supuesto, en vez de buscar un usuario con Login igual al Nif, podríamos haber definido una propiedad nueva para los Usuarios XWiki y para usarlo con este propósito, cuando lo hagáis no dudéis en poner vuestros comentarios al final de este post.

La secuencia de llamadas entre todos estos componentes lo podemos ver aquí:

Vamos a ir explicando paso a paso cómo hacer todo esto:
Paso 1.- Modificación del formulario de Login

Debemos editar el fichero templates/login.vm e introduciremos la redirección al servlet. Os propongo dos opciones, un enlace dentro de formulario ya existente y un formulario nuevo (para nuestro ejemplo funcionarán los dos):

...
<form>
...
#template("viafirmaLink.vm") <-Hiperenlace: opcion A
...
</form>
#template("viafirmaForm.vm") <- Formulario: opción B
...

Posteriormente copiaremos los ficheros viafirmaLink.vm y viafirmaForm.vm dentro del directorio templates.
Contenido de viafirmaLink.vm:

<div style="margin: 1em;">
 <a href="viafirma.login">ACCESO CON CERTIFICADO DIGITAL</a>
 <br/>
</div>

Contenido de viafirmaForm.vm:

<form id="loginFormViafirma" action="viafirma.login" method="post">
 <div>
 <fieldset>
 <legend>Certificado Digital</legend>
 <div><span><input type="submit" value="VIAFIRMA"/></span></div>
 </div>
</form>

Vemos que las dos opciones propuesta envian al usuario a la URL http://xwikiserver/…/viafirma.login .

Paso 2.- Implementación de un Filter, que será el encargado de capturar las peticiones a …/viafirma.login y enviar al usuario hacia Viafirma para que se autentique:

package org.viafirma.xwiki;
public class AuthenticationFilter implements Filter { ... }

Paso 3.- Implementación de un Servlet que recogerá de vuelta el resultado ofrecido por parte de Viafirma tras el análisis del certificado, capturando las peticiones a …/viafirmaAuthentication y coloque en sesión al usuario UsuarioGenericoViafirma:

package org.viafirma.xwiki;
public class AuthenticationServlet extends ViafirmaClientServlet implements Serializable { ... }

Paso 4.- Implementaremos un mecanismo usando otro Filter, para que Viafirma use una CSS definida por nosotros mismos. Viafirma “pide” por defecto una CSS llamada viafirmaStyle.css. En este ejemplo hemos optado por que XWiki sirva el CSS que usará Viafirma, aunque quizás lo más conveniente sea colocar este CSS en un servidor externo, por ejemplo un Apache, pero de todos modos vamos a hacerdo a modo de ejemplo. Bastaría con colocar una regla en Apache (por ejemplo) para que las peticiones al archivo viafirmaStyle.css no pasen a la XWiki, esto os lo dejo a vosotros.

Paso5.- Extenderemos el Servicio de Autenticación de XWiki, que sustituirá a la que tiene por defecto esta plataforma:

package org.viafirma.xwiki;
public class ViafirmaAuthImpl extends XWikiAuthServiceImpl implements  Serializable { ... }

Posteriormente, deberemos modificar el fichero xwiki.cfg de XWiki añadiendo o modificando:

xwiki.authentication.authclass=org.viafirma.xwiki.ViafirmaAuthImpl

Paso 6.- Configuraremos el web.xml de XWiki para dar de alta estos Filters y Servlets que hemos creado, adaptando los valores de los parámetros a nuestro entorno (url de Viafirma y ruta al css):

...
 <filter>
 <filter-name>ViafirmaLoginFilter</filter-name>
 <filter-class>org.viafirma.xwiki.AuthenticationFilter</filter-class>
 <init-param>
 <param-name>VIAFIRMA_URL</param-name>
 <param-value>http://viafirma.viavansi.com/viafirma</param-value>
 </init-param>
 <init-param>
 <param-name>VIAFIRMA_WS</param-name>
 <param-value>http://viafirma.viavansi.com/viafirma</param-value>
 </init-param>
 </filter>
 <filter>
 <filter-name>ViafirmaStyleFilter</filter-name>
 <filter-class>org.viafirma.xwiki.ViafirmaStyleFilter</filter-class>
 <init-param>
 <param-name>PATH_CSS</param-name>
 <param-value>D:/xwiki/skins/colibri/colibri.css</param-value>
 </init-param>
 </filter>

 <filter-mapping>
 <filter-name>ViafirmaLoginFilter</filter-name>
 <url-pattern>*.login</url-pattern>
 </filter-mapping>
 <filter-mapping>
 <filter-name>ViafirmaStyleFilter</filter-name>
 <url-pattern>*.css</url-pattern>
 </filter-mapping>
 ...
 <!-- Servlet de Autenticación de Viafirma-->
 <servlet>
 <servlet-name>viafirmaAuthentication</servlet-name>
 <servlet-class>org.viafirma.xwiki.AuthenticationServlet</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>viafirmaAuthentication</servlet-name>
 <url-pattern>/viafirmaAuthentication/*</url-pattern>
 </servlet-mapping>

Finalmente tendremos esto:

Teneis el proyecto mavenizado y todos los fuentes usados en este ejemplo aquí:

Descarga de fuentes aquí

Para integrar este ejemplo en XWiki, sólo es necesario:

  1. Empaquetar las clases generadas en un .jar y copiarlo en el WEB-INF/lib de XWiki, también deberá copiar en esa carpeta todas las librerías dependientes.
  2. Realizar las modificaciones anteriormente indicadas en el formulario de Login.
  3. Copiar los archivos .vm a la ruta indicada anteriormente.
  4. Modificar y configurar el web.xml de XWiki.

Aquí os dejo unas capturas de pantalla para demostraros que todo esto funciona correctamente 🙂

Formulario para logarnos:

Finalmente, vemos que XWiki nos ha logado correctamente:

Selección del Certificado Digital en Viafirma, vereis que tiene el CSS que queremos (obviamente ese CSS se puede mejorar) :

Finalmente veremos que ya estamos logados en XWiki (enhorabuena !!) :

Esto nos da por pensar en próximos capítulos: ¿publicación de contenidos firmados digitalmente? Quién sabe…

Un Saludo.

Deja un comentario