ATLAS MANUAL DE INTEGRACIÓN Servicios de Firma AFC Cliente

Anuncio
ATLAS
MANUAL DE INTEGRACIÓN
Servicios de Firma AFC Cliente
Versión 1.3
Arquitectura de Software
Framework Atlas
Servicios de Firma AFC Cliente
Hoja de Control
Título
Servicios de Firma AFC Cliente
Documento de Referencia
NORMATIVA ATLAS
Responsable
Arquitectura de Software
Versión
1.3
Fecha Versión
13/11/2015
Registro de Cambios
Versión
Causa del Cambio
1.0
Versión inicial del documento
Responsable del Cambio Fecha del Cambio
Unidad de Arquitectura
Revisión del documento.
1.1
06/02/2014
Unidad de Arquitectura
26/03/2014
Añadida información sobre Tipo de presentación de Unidad de Arquitectura
23/09/2014
Añadidos ejemplos de firma CADES.
Añadido opción de uso de @PostConstruct
1.2
ventana flotante
Añadida nota sobre variables y configuración de
Spring sobrante a partir de versión de atlas 1.2.8
1.3
Añadida información sobre presentación 4
Uso de nueva librería crypt
2 de 43
Unidad de Arquitectura
13/11/2015
Framework Atlas
Servicios de Firma AFC Cliente
Índice
1.
INTRODUCCIÓN ................................................................................................................................................................ 4
1.1.
AUDIENCIA OBJETIVO ...................................................................................................................................................... 5
2.
DESCRIPCIÓN .................................................................................................................................................................... 6
3.
EJEMPLOS ........................................................................................................................................................................... 7
4.
INSTALACION Y CONFIGURACION............................................................................................................................. 8
4.1.
ALTA EN AFC ............................................................................................................................................................... 8
4.2.
CONFIGURACION ....................................................................................................................................................... 9
4.2.1.
Configuración de acceso a AFC ............................................................................................................................. 9
4.2.2.
Configuración de acceso a COVE ....................................................................................................................... 10
4.3.
INSTALACION ............................................................................................................................................................ 10
4.3.1.
Paso 1: Añadir la dependencia al módulo de Administración Electrónica .......................................................... 10
4.3.1.
Paso 2: Actualizar la configuración de Spring ..................................................................................................... 11
5.
USO ....................................................................................................................... ¡ERROR! MARCADOR NO DEFINIDO.
5.1.
FIRMA DOCUMENTOS PDF ..................................................................................................................................... 12
5.1.1.
Solicitar url de Firma ............................................................................................. ¡Error! Marcador no definido.
5.1.2.
Realizar llamada a AFC ....................................................................................................................................... 18
5.1.3.
Opción de presentación 3 ..................................................................................................................................... 18
5.1.4.
Recibir la respuesta de la firma. ........................................................................................................................... 23
5.1.5.
Recepción de respuesta con anotación @PostConstruct ...................................................................................... 25
5.2.
FIRMA MASIVA DOCUMENTOS PDF ............................................................... ¡ERROR! MARCADOR NO DEFINIDO.
5.2.1.
Implementación de la Interfaz PdfFileProvider .................................................................................................... 28
5.2.2.
Selección del certificado cliente para la firma ..................................................................................................... 33
Solicitud de firma .................................................................................................................... ¡Error! Marcador no definido.
5.2.3.
Recibir la respuesta de las firmas. ........................................................................................................................ 37
5.2.4.
Recogida de firmas y procesado de las mismas .................................................................................................... 37
5.3.
FIRMA INDIVIDUAL DOCUMENTOS XML ........................................................................................................... 39
5.4.
FIRMA MASIVA DOCUMENTOS XML ................................................................................................................... 40
5.5.
FIRMA INDIVIDUAL CADES.................................................................................................................................... 40
5.6.
FIRMA MASIVA CADES ........................................................................................................................................... 42
ENLACES RELACIONADOS .................................................................................................................................................. 43
3 de 43
Framework Atlas
Servicios de Firma AFC Cliente
1. INTRODUCCIÓN
AFC es la solución de firma centralizada para las aplicaciones de la Comunidad de Madrid.
Objetivos buscados:
Operativo de firma similar y centralizada.
Formatos comunes de firma compatibles con ENI (Esquema Nacional de Interoperabilidad)
Simplificar la integración de requisitos de firma en los desarrollos.
Transparencia en las actualizaciones de la plataforma de firma
Inventario de aplicaciones y tipos de firmas
Histórico y estadísticas de operaciones realizadas
Operaciones que permite:
Firma digital en cliente
Firma digital en servidor
Validación de firmas
Estado de certificados
Datos de certificados
Tipos de firma (Admitidos por el ENI)
PADES – PDF Advanced Electronic Signature
XADES – XML Advanced Electronic Signature
CADES – CMS Advanced Electronic Signature
Integración:
La integración con la solución de AFC se realiza a través de la librería del Framework Atlas atlasfrm_eadm
(librería que conecta con los servicios de administración electrónica) hasta la versión 1.2.8, a partir de la versión
1.2.9 se utilizará la librería atlasfrm_crypt. Esta librería puede ser utilizada tanto por aplicaciones desarrolladas
con el framework Atlas así como las desarrolladas con otros frameworks Java (framework 2 o framework Justicia).
Dentro de esta librería podemos encontrar tres servicios:
AfcOpeClienteService: Servicio de Operaciones en cliente
AfcOpeServidorService: Servicio de Operacion en servidor
AfcOpeCertificadoService: Servicio de Operaciones con certificado
Este documento describe el servicio de afc para operaciones en cliente. Si se va a utilizar desde una aplicación
que no es del framework ATLAS consultar el manual FW2_MUS_Integracion_AFC.
4 de 43
Framework Atlas
Servicios de Firma AFC Cliente
1.1.
Audiencia objetivo
Este documento está orientado a desarrolladores java que necesiten realizar operaciones de firma en cliente.
5 de 43
Framework Atlas
Servicios de Firma AFC Cliente
2. DESCRIPCIÓN
Las operaciones que el servicio de afc ofrece en cliente son:
Firma individual de documentos: Se envía un documento integro a la firma.
Firma masiva de documentos: esta operación está especialmente diseñada para la firma de varios
documentos a la vez. En el caso de ficheros pdf el proceso se ha optimizado para que no sea necesaria la
transferencia de estos ficheros con el consiguiente ahorro de recursos. En lugar de enviar los ficheros a la
firma se enviará un hash de cada uno de los ficheros. Esta operación también es recomendada para la
firma de ficheros Pdf pesados aunque la firma sea individual
En el caso de ficheros pdf, la operativa actual permite obtener e insertar en el documento el código COVE para
su visualización pública.
A continuación se muestra un gráfico simplificado de la operativa de firma entre la aplicación del usuario de firma y
AFC Cliente:
APLICACION
AFCSERVICE
AFC_FIRMACLIENTE
SOLICITAR
URL FIRMA
REDIRIGIR
RECOGER
ERRORES
RECOGER
FIRMA
1. Solicitar url firma: en este momento se ejecutará una llamada al servicio de AFC con una solicitud de una
operación de firma. El servicio responderá con una URL a la que deberá redirigirse al usuario para la
ejecución de la operación.
2. Redirigir usuario a AFC_FIRMACLIENTE: en este punto, la aplicación cliente deberá redirigir al usuario a
la URL obtenida en el punto anterior. En esta aplicación el usuario podrá realizar la firma digital del
documento o documentos solicitados. Una vez concluida la firma, se devolverá al usuario a la URL de
retorno configurada en el paso 1 (solicitud de firma).
3. Recoger firmas/errores: si la operación de firma ha ido bien, la aplicación cliente solicitará al servicio de
AFC los documentos firmados por el usuario. En caso contrarió solicitará los errores generados en la firma.
6 de 43
Framework Atlas
Servicios de Firma AFC Cliente
3. EJEMPLOS
Se han desarrollado varios ejemplos para ver la integración en los distintos frameworks:
Aplicación ATLAS : afc_demo: https://desarrollo.madrid.org/afc_demo
Aplicación ATLAS : atlas_integracion_asf: https://desarrollo.madrid.org/atlas_integracion_asf
Aplicación Framework 2: ejpl_crypto_web: http://desarrollo.madrid.org/ejpl_crypto_web
7 de 43
Framework Atlas
Servicios de Firma AFC Cliente
4. INSTALACION Y CONFIGURACION
4.1.
ALTA EN AFC
Antes de utilizar el servicio de AFC en desarrollo es necesario autorizar a la aplicación. Las peticiones de
autorización de uso del servicio AFC se dirigirán a través del servicio Remedy al grupo GC.AE.
Para firma en cliente es necesario indicar en la petición los siguientes datos:
Aplicación: Código poaps del proyecto
Nombre del módulo técnico: Nombre del modulo técnico que se va a integrar con AFC. Este valor será el que se
informará en el fichero de configuración de la aplicación en la propiedad afc.modulo.
Descripción uso: Breve descripción del uso que se requiere del servicio AFC
Entorno: Entorno donde se requiere la autorización
Login administrador: Usuario con el que acceder al entorno AFC para la administración de documentos
Para cada tipo de documento a firmar
-
Nombre del tipo de documento
-
Formato: XADES, PADES o CADES
-
En caso de firma PADES si se incluye código de COVE o no
-
Número de firmas
-
Tipo de firma: Integra o Hash
-
Por cada firma:
o
Fuente: Por defecto Arial 8
o
Firma visible o no: Por defecto No
o
En caso de firma visible información acerca de la ubicación de la firma.(coordenadas y
página)
o
Descripcion del firmante
Una vez que se autorice su uso se recibirá una password (diferente para cada entorno) que habrá que informar en
el fichero de configuración en la variable afc.password.
8 de 43
Framework Atlas
Servicios de Firma AFC Cliente
4.2.
CONFIGURACION
4.2.1.
Configuración de acceso a AFC
La información de acceso se definirán en el fichero de configuración mediante las siguientes variables (el nombre
de estas variables es igual para todos los frameworks):
Variable
afc.modulo
Descripción
Nombre del módulo para autenticarse contra el servicio de
Obligatorio
SI
ASF. Se corresponde con el nombre dado de alta en el
Servicio de ASF.
afc.password
Contraseña de acceso, debe estar cifrada. Esta contraseña
SI
se proporciona cuando se solicita el acceso al Servicio de
AFC.
A continuación se muestra un ejemplo de configuración.
Ejemplo de configuracion
# Configuracion de acceso a AFC_Cliente
afc.modulo=ejpl_app
afc.password=98D943B7C420E3F9
# Opcionalmente se puede incluir información del tipo de documento a firmar si la
aplicación solamente trabaja con un tipo de documento
afc.documentoTipo=SolicitudAyuda
afc.numeroFirma=1
9 de 43
Framework Atlas
Servicios de Firma AFC Cliente
4.2.2.
Configuración de acceso a COVE
Si los documentos a firmar han de incluir el código de COVE es necesario especificar en el fichero de configuración
la información de acceso al Servicio de Administración Electrónica COVE. Las variables que es necesario
configurar son las siguientes (el nombre de las variables es el mismo para todos los frameworks):
Variable
Descripción
cove.aplicacion
Aplicación que accede al sistema COVE
cove.tipo
Código del Tipo de certificado a utilizar
cove.usuario
Usuario que accede al sistema COVE
A continuación se muestra un ejemplo de configuración.
Ejemplo de configuración
# Configuracion de acceso a COVE
cove.usuario=UUIA01
cove.tipo=EJARCH
cove.aplicacion=EJPL
4.3.
INSTALACION
El Servicio de AFC Cliente viene incluido en el módulo de Encryptación de Atlas. Para poder utilizarlo, bastará
con incluir la dependencia de este módulo en el fichero pom.xml del proyecto, añadir un import del fichero
applicationContext-crypt-lib.xml, y definir en el contexto de Spring la configuración del servicio para la aplicación.
4.3.1.
Paso 1: Añadir la dependencia al módulo de Encryptación de atlas
Para añadir la dependencia al módulo de Encriptación (crypt-lib) dentro de nuestro proyecto maven hay que
añadir una entrada “dependency” en la sección “dependencies” del fichero “pom.xml” del proyecto, como se
puede ver en el siguiente ejemplo:
10 de 43
Framework Atlas
Servicios de Firma AFC Cliente
pom.xml
<dependencies>
…
<dependency>
<groupId>atlasfrm</groupId>
<artifactId>atlasfrm-crypt-lib</artifactId>
<version>${atlasfrm-crypt-lib.version}</version>
</dependency>
</dependencies>
4.3.1.
Paso 2: Actualizar la configuración de Spring
Es necesario importar la configuración de Spring para los servicios de la librería crypt dentro del fichero
applicationContext-services.xml.
applicationContext-services.xml
<import resource="classpath:/conf/applicationContext-crypt-lib.xml" />
11 de 43
Framework Atlas
Servicios de Firma AFC Cliente
5. OPERACIONES DE FIRMA
Una vez configurada la aplicación se puede proceder a utilizar todas las funcionalidades que ofrece.
5.1.
FIRMA DOCUMENTOS PDF - PADES
Para realizar firmas de documentos del tipo PADES, existen 2 métodos, firma Individual:
AfcOpClienteService
/**
* Solicita a AFC una operación de firma individual.
* @param data contenido del documento a firmar
* @param signInfo información de acceso a AFC.
* @param loginCert certificado de login de usuario
* @param opcionesPresentacion tipo de presentación del documento en AFC
* @param urlOk url de retorno a la aplicación en una operación de firma
correcta.
* @param urlError url de retorno a la aplicación en una operación de firma
incorrecta.
* @return identificador de la operación en AFC (para recoger las firmas).
* @throws ServiceException si hubo problemas
*/
<E extends Serializable> String solicitarFirmaIndividual(byte[] data,
SignInfo<E> signInfo, X509Certificate loginCert,
String opcionesPresentacion, String urlOk, String urlError)
throws ServiceException;
Parámetro
Descripción
byte[] data
Fichero a firmar
SignInfo signInfo
Información de firma para el servicio de AFC
X509Certificate loginCert
Certificado con el que se ha logado en la aplicación. Si no
hay certificado se pone null.
String opcionesPresentacion
Opción de presentación:
1.- Se muestra el contenido del documento embebido en la
página de la firma
2.- Se muestra una lista con el fichero a firmar y la
posibilidad de pinchar en un enlace para visualizar el
documento
3.- Modo ventana flotante.
4.- Modo ventana flotante directa.
String urlOk
Url a la que redirigir al final de la firma si todo a ido bien
String urlError
Url a la que redirigir al final de la firma si se ha producido
algún error
Firma Masiva de documentos:
12 de 43
Framework Atlas
Servicios de Firma AFC Cliente
AfcOpClienteService
/**
* Solicita a AFC una operación de firma masiva Pdf.
* @param provider proveedor de ficheros para la operación de firma
* @param loginCertificate certificado de login de usuario
* @param urlOk url de retorno a la aplicación en una operación de firma
correcta.
* @param urlError url de retorno a la aplicación en una operación de firma
incorrecta.
* @return identificador de la operación en AFC (para recoger las firmas).
* @throws ServiceException si hubo problemas
*/
<E extends Serializable> String solicitarFirmaPdfMasiva(PdfFileProvider<E>
provider,
X509Certificate loginCertificate, String opcionesPresentacion, String
urlOk, String urlError)
throws ServiceException;
Parámetro
5.2.
Descripción
Objeto FileProvider
FileProvider con todos los ficheros a firmar
X509Certificate loginCert
Certificado con el que se ha logado en la aplicación. Si no
hay certificado se pone null.
String opcionesPresentacion
Opción de presentación:
1.- Se muestra el contenido del documento embebido en la
página de la firma
2.- Se muestra una lista con el fichero a firmar y la
posibilidad de pinchar en un enlace para visualizar el
documento
3.- Modo ventana flotante
4.- Modo ventana flotante directa
String urlOk
Url a la que redirigir al final de la firma si todo a ido bien
String urlError
Url a la que redirigir al final de la firma si se ha producido
algún error
FIRMA DOCUMENTOS XML – XADES
Para realizar la firma de ficheros XML, existen 2 métodos, para firmas individuales:
AfcOpClienteService
13 de 43
Framework Atlas
Servicios de Firma AFC Cliente
/**
* Solicita a AFC una operación de firma individual.
* @param data contenido del documento a firmar
* @param signInfo información de acceso a AFC.
* @param loginCert certificado de login de usuario
* @param opcionesPresentacion tipo de presentación del documento en AFC
* @param urlOk url de retorno a la aplicación en una operación de firma
correcta.
* @param urlError url de retorno a la aplicación en una operación de firma
incorrecta.
* @return identificador de la operación en AFC (para recoger las firmas).
* @throws ServiceException si hubo problemas
*/
<E extends Serializable> String solicitarFirmaIndividual(byte[] data,
SignInfo<E> signInfo, X509Certificate loginCert,
String opcionesPresentacion, String urlOk, String urlError)
throws ServiceException;
Y el método para firmas masivas:
AfcOpClienteService
/**
* Solicita a AFC una operación de firma masiva XAdES
* @param xmls ficheros a firmar
* @param loginCertificate certificado de acceso para filtrado en selección
* @param urlOk url de retorno a la aplicación en una operación correcta.
* @param urlError url de retorno a la aplicación en una operación incorrecta.
* @return url de acceso a la aplicación de firma al que redirigir al usuario
* @throws ServiceException si hubo problemas
*/
<E extends Serializable> String solicitarFirmaXadesMasiva(Map<SignInfo<E>,
byte[]> xmls,
X509Certificate loginCertificate, String opcionesPresentacion,
String urlOk, String urlError)
throws ServiceException;
Parámetro
Descripción
Map <SignInfo<E>, byte[]>
Mapa con los ficheros a firmar y la información de AFC
necesaria para realizar la firma
X509Certificate loginCert
Certificado con el que se ha logado en la aplicación. Si no
hay certificado se pone null.
String opcionesPresentacion
Opción de presentación:
1.- Se muestra el contenido del documento embebido en la
página de la firma
2.- Se muestra una lista con el fichero a firmar y la
posibilidad de pinchar en un enlace para visualizar el
documento
3.- Modo ventana flotante
4.- Modo ventana flotante directa
String urlOk
Url a la que redirigir al final de la firma si todo a ido bien
14 de 43
Framework Atlas
Servicios de Firma AFC Cliente
String urlError
5.3.
Url a la que redirigir al final de la firma si se ha producido
algún error
FIRMA DOCUMENTOS CADES
Para realizar la firma del tipo Cades, exiten igualmente 2 métodos, firma individual:
AfcOpClienteService
/**
* Solicita a AFC una operación de firma individual.
* @param data contenido del documento a firmar
* @param signInfo información de acceso a AFC.
* @param loginCert certificado de login de usuario
* @param opcionesPresentacion tipo de presentación del documento en AFC
* @param urlOk url de retorno a la aplicación en una operación de firma
correcta.
* @param urlError url de retorno a la aplicación en una operación de firma
incorrecta.
* @return identificador de la operación en AFC (para recoger las firmas).
* @throws ServiceException si hubo problemas
*/
<E extends Serializable> String solicitarFirmaIndividual(byte[] data,
SignInfo<E> signInfo, X509Certificate loginCert,
String opcionesPresentacion, String urlOk, String urlError)
throws ServiceException;
Y el método para firmas masivas:
AfcOpClienteService
/**
* Solicita a AFC una operación de firma masiva CAdES
* @param files ficheros a firmar
* @param loginCertificate certificado de acceso para filtrado en selección
* @param urlOk url de retorno a la aplicación en una operación correcta.
* @param urlError url de retorno a la aplicación en una operación incorrecta.
* @return url de acceso a la aplicación de firma al que redirigir al usuario
* @throws ServiceException si hubo problemas
*/
<E extends Serializable> String solicitarFirmaCadesMasiva(Map<SignInfo<E>,
byte[]> files,
X509Certificate loginCertificate, String opcionesPresentacion,
String urlOk, String urlError)
throws ServiceException;
Parámetro
Map <SignInfo<E>, byte[]>
Descripción
Mapa con los ficheros a firmar y la información de AFC
necesaria para realizar la firma
15 de 43
Framework Atlas
Servicios de Firma AFC Cliente
X509Certificate loginCert
Certificado con el que se ha logado en la aplicación. Si no
hay certificado se pone null.
String opcionesPresentacion
Opción de presentación:
1.- Se muestra el contenido del documento embebido en la
página de la firma
2.- Se muestra una lista con el fichero a firmar y la
posibilidad de pinchar en un enlace para visualizar el
documento
3.- Modo ventana flotante
4.- Modo ventana flotante directa
String urlOk
Url a la que redirigir al final de la firma si todo a ido bien
String urlError
Url a la que redirigir al final de la firma si se ha producido
algún error
6. PASOS PARA REALIZAR FIRMAS
A continuación se muestra los pasos a seguir para realizar una firma
6.1.1.
Preparación objetos
Distinguimos entre llamadas a firmas individuales y firmas masivas.
Firmas individuales
Para realizar firmas individuales, independientemente del tipo de firma (pades, xades o cades), tan solo
necesitamos configurar el objeto SignInfo<E>. Este objeto es del tipo que deseemos, el tipo escogido será
utilizado como ID y en la mayoría de los casos de firma individual, bastará con usar la Clase String.
El objeto SignInfo, requiere que se establezcan las siguientes propiedades:
Atributo
Descripción
<E> providerId
Objeto identificador de SignInfo. Puede ser del tipo que se
desee
String documentoTipo
Atributo donde especificaremos el tipo de documento de AFC
que queramos usar para la firma.
Al dar de alta el acceso en AFC, podremos asociar a nuestro
modulo a varios tipos de documentos.
String numeroFirma
Este atributo hace referencia al firmante para el tipo de
documento de AFC, posee entre otras cosas la posición de la
firma, si es visible o no, etc
CoveInfo coveInfo
Objeto Cove si se desea utilizar este servicio
16 de 43
Framework Atlas
Servicios de Firma AFC Cliente
String titulo
Titulo del fichero a firmar
Firmas masivas
Para realizar firmas masivas de documentos es necesario distinguir entre los formatos PADES y
CADES/XADES.
o
Firmas PADES masivas/hash
Las firmas PADES masivas se basan en recoger el Hash de los documentos a firmar, firmarlo y volver
a insertar dicho hash firmado en el documento pdf.
Para ello, necesitaremos crear una clase que implemente la interfaz PdfFileProvider<T extends
Serializable>, dicha interfaz obliga a nuestra clase a implementar los siguientes métodos:
Void setSignedFile(T paramT, InputStream paramInputStream)
InputStream getFileToSign(T paramT)
T[] getFileIds()
URI getDownloadUri(T paramT)
SignInfo<T> getSignInfo(T paramT)
CoveInfo getCoveInfo(T paramT)
PdfSignatureAppearanceGenerator getPdfAppearance(T paramT)
Donde <T> es la clase escogida como identificador. Se pueden ver ejemplos en las aplicaciones de
ejemplo de atlas y FW2 y en este documento en el apartado Ejemplo Implementación PDF HASH
o
Firmas CADES/XADES masivas
Las firmas Xades y Cades de forma masiva son iguales que las individuales, solo que usaremos un
objeto Mapa para guardar los objeto SignInfo junto con los ficheros (byte[]).
6.1.1.
Llamada a AFC
Una vez creados los objetos necesarios, ejecutaremos la llamada al método y como resultado obtendremos una
URL preparada con un parámetro token. Este token también se entrega adjunto en las URLs de retorno (Ok y
Error) de forma que sea sencillo capturarlo para después hacer la petición del fichero firmado.
17 de 43
Framework Atlas
Servicios de Firma AFC Cliente
Llamada a servicio web de AFC para obtener URL (FirmaPdfIndividualAfcBean.java)
// Envía la solicitud de firma a AFC
String url = afcService.solicitarFirmaIndividual(pdf,
signInfo, loginCert, operacionPresentacion, urlOk, urlError);
6.1.2.
Realizar llamada a AFC
Una vez obtenida el String con la URL que debemos utilizar para realizar la llamada a AFC, disponemos de 2
opciones.
1. Redirigir la llamada a la pantalla de AFC (Esto aplica para opciones de presentación 1 y 2)
Redirigir llamada a AFC (FirmaPdfIndividualAfcBean.java)
// Envía la solicitud de firma a AFC
String url = afcService.solicitarFirmaIndividual(pdf,
signInfo, loginCert, operacionPresentacion, urlOk, urlError);
redirectToAfc(url);
return null;
2. Establecer parámetro a true para mostrar IFrame (opciones de presentación 3 y 4)
Redirigir llamada a AFC (FirmaPdfIndividualAfcPrBean.java)
mostrarPanelFlotante =true;
this.signUrl = afcUrl;
6.1.3.
Opción de presentación con iFrame
En caso de opción de presentación 3 no debemos redirigir a otra pantalla con la URL obtenida, sino que tendremos
que actualizar el componente de iFrame incrustado en nuestra pantalla.
De inicio, dispondremos de un elemento iFrame y una división lógica (div) que estarán inactivos, ambos
componentes se refrescarán una vez obtenidos los datos de AFC.
Necesitaremos 2 elementos importantes:
firmaClienteIndividualFlotante.xhtml
18 de 43
Framework Atlas
Servicios de Firma AFC Cliente
<style>
#fondoDesactivado {
display: block;
position: absolute;
top:0;
left:180px;
width: 85%;
height: 100%;
background-color: white;
opacity: .50;
-webkit-opacity: .5;
-moz-opacity: .5;
filter: alpha(opacity=50);
z-index: 1000;
}
#ventanaFlotante {
background-color: white;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
box-shadow: 0 0 20px 0 #222;
-webkit-box-shadow: 0 0 20px 0 #222;
-moz-box-shadow: 0 0 20px 0 #222;
display: block;
top: 50;
width: 400px;
left: 50%;
margin: -120px 0 0 -160px;
padding: 10px;
position: fixed;
top: 50%;
z-index: 1000;
}
</style>
<div id="fondoDesactivado"></div>
El panel transparente para evitar acciones en la pantalla origen
firmaClienteIndividualFlotante.xhtml
<h:panelGroup id="panelFlot”>
<rich:panel rendered="#{firmaPdfIndividualAfcPrBean.mostrarPanelFlotante}">
…
…
…
</rich:panel>
</h:panelGroup>
Ambos componentes está rodeados por un panel que será el que se refrescará una vez obtenida la URL del
servicio de AFC:
La variable mostrarPanelFlotante se establece por defecto a false:
19 de 43
Framework Atlas
Servicios de Firma AFC Cliente
FirmaPdfIndividualAfcPrBean.java
/**
* boolean que se encarga de mostrar/ocultar panel flotante
*/
private boolean mostrarPanelFlotante = false;
Y se marca a true en cuanto disponemos de la URL de AFC
FirmaPdfIndividualAfcPrBean.java
if (opcionesPresentacion.equals("3")) {
mostrarPanelFlotante =true;
this.signUrl = url;
} else {
…
}
Establecemos el valor de “signUrl” con el valor obtenido del servicio de AFC.
firmaClienteIndividualFlotante.xhtml
<iframe src="#{firmaPdfIndividualAfcPrBean.signUrl}"
El componente obtiene así la url de llamada del iFrame (por defecto es vacía).
firmaClienteIndividualFlotante.xhtml
<a4j:commandLink id="btnFirmaFlot" styleClass="botonAplicacionTXT"
action ="#{firmaPdfIndividualAfcPrBean.procesarFirma}"
render="panelFlot">
Para finalizar, solo debemos refrescar los componentes para que tanto el iFrame como el fondo bloqueante
estén activos, para ello, en el botón que utilicemos para realizar la firma, hacer uso del atributo render.
Donde panelFlot será el identificador del componente a refrescar.
20 de 43
Framework Atlas
Servicios de Firma AFC Cliente
7. OPCIONES DE PRESENTACIÓN
Existen tres opciones de presentación:
1. Se muestra el contenido del documento embebido en la página de firma
2. Se muestra una lista con el fichero a firmar y la posibilidad de pinchar en un enlace para visualizar el
documento
21 de 43
Framework Atlas
Servicios de Firma AFC Cliente
3. Se muestra un iFrame en la misma pantalla que realiza la llamada a AFC
4. Se muestra un iFrame en la misma pantalla que realiza la llamada a AFC y el usuario no tiene que
confirmar la firma
22 de 43
Framework Atlas
Servicios de Firma AFC Cliente
7.1.1.
Recibir la respuesta de la firma.
En el retorno se comprobará si ha habido errores y se recogerá el documento firmado (si no ha habido problemas).
En JSF no existe ninguna forma de ejecutar una acción a partír de una URL externa, siempre se direccionarán
páginas. Para redirigir la respuesta a un método de un ManagedBean y poder recoger el fichero firmado se utiliza
la siguiente sección de código:
firmaPdfIndividualDesdeAfc.xhtml
<ui:composition template=”/WEB-INF/layout/vc.xhtml”>
<f:metadata>
<f:viewParam name=”error” required=”false”
value=”#{firmaPdfIndividualResultadoAfcBean.error}” />
<f:viewParam name=”token” required=”true”
value=”#{firmaPdfIndividualResultadoAfcBean.token}” />
<f:event type=”preRenderView”
listener=”#{firmaPdfIndividualResultadoAfcBean.procesar}” />
</f:metadata>
</ui:composition>
De esta forma se recogen los parámetros error y token y se redirige la ejecución a un método del ManagedBean
del resultado, en nuestro ejemplo firmaPdfIndividualResultadoAfcBean. Para evitar problemas en la recarga de la
página, la redirección a la acción de un ManagedBean debe ser el único elemento en la página.
23 de 43
Framework Atlas
Servicios de Firma AFC Cliente
En el managedbean una vez recuperados los errores o las firmas se debe realizar una navegación forzada a la
página de resultados:
FirmaPdfIndividualResultadoAfcBean.java
/**
* Método que recoge la firma o los errores en caso de error
* y redirecciona a la página de recogida de firma
*/
public void procesar() {
try {
// comprobar si ha habido errores
boolean bError = error ¡= null && “true”.equalsIgnoreCase(this.error);
if (bError) {
log.info(“Respuesta de ERROR recibida de AFC.”);
AtlasFacesUtils.addErrorMessage(“Error en la firma”);
Map<UUID, String> listaErrores = this.afcService.recogerErrores(token);
// Encola todos los errores de AFC como error messages de jsf
for (UUID uuid : listaErrores.keySet()) {
AtlasFacesUtils.addErrorMessage(listaErrores.get(uuid));
}
} else {
log.info(“Respuesta CORRECTA recibida de AFC.”);
byte[] pdf = this.afcService.recogerFirma(this.token);
// Preparar ficheros para descarga
this.name = (String)
AtlasFacesUtils.loadFromSession(PARAM_FILE_NAME, true);
this.fileId = (URL)
AtlasFacesUtils.loadFromSession(PARAM_FILE_PATH, true);
// Guardar contenido de fichero firmado en disco
this.outputPath = setSignedFile(name, new ByteArrayInputStream(pdf));
}
// Redirigir a la pagina de descarga del fichero
log.info(“Redireccionando a página “ + VISTA_RESULTADO);
AtlasFacesUtils.navigateTo(VISTA_RESULTADO);
} catch (ServiceException e) {
log.error(“Error procesando firmas en AFC”, e);
AtlasFacesUtils.addErrorMessage(“Error procesando firmas en AFC”);
}
}
24 de 43
Framework Atlas
Servicios de Firma AFC Cliente
7.1.2. Recepción de respuesta con anotación @PostConstruct
La otra manera de implementar la recepción de la respuesta es utilizando la anotación @PostConstruct en el
bean de respuesta.
Para implementar esta solución hay que implementar los siguientes pasos:
1. Página firmaPdfIndividual.xhtml: página que se encargará de seleccionar el fichero a firmar.
2. Managed bean FirmaPdIndividualAfcBean.java desde este managed bean se inicia el proceso
de firma solicitando la url de firma al Servicio de AFC y redirigiendo al usuario a afc_firmacliente
3. Managed bean FirmaPdfIndividualResultadoAfcBean.java: Esta managedbean se encargará
de gestionar el resultado de afc_firmacliente (ok o error) y obtener el fichero firmado o los errores en el
caso de que haya habido algún error.
4. Página firmaPdfIndividualResultado.xhtml: página que muestra el resultado de la firma una
vez recuperado.
Esta modalidad se desarrolla igual que la anteriormente descrita con la salvedad de que no es necesario
establecer una página de recarga previa a la recepción en la página de resultado.
Lo único que hay que tener en cuenta es la necesidad de anotar el método procesar como @PostConstruct lo
que indica que este método debe ser llamado una vez ejecutado el constructor del bean pero antes de realizar
nada más, con lo que tendremos las propiedades correctamente inyectadas.
25 de 43
Framework Atlas
Servicios de Firma AFC Cliente
La implementación del managed bean para la página de resultado sería así:
FirmaPdfIndividualResultadoAfcBean.java
/**
* Método que recoge la firma o los errores en caso de error
* y redirecciona a la página de recogida de firma
*/
@PostConstruct
public void procesar() {
if (!FacesContext.getCurrentInstance().isPostback()) {
try {
this.token = FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get("token");
this.error = FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get("error");
// comprobar si ha habido errores
boolean bError = error ¡= null && “true”.equalsIgnoreCase(this.error);
if (bError) {
log.info(“Respuesta de ERROR recibida de AFC.”);
AtlasFacesUtils.addErrorMessage(“Error en la firma”);
Map<UUID, String> listaErrores = this.afcService.recogerErrores(token);
// Encola todos los errores de AFC como error messages de jsf
for (UUID uuid : listaErrores.keySet()) {
AtlasFacesUtils.addErrorMessage(listaErrores.get(uuid));
}
} else {
log.info(“Respuesta CORRECTA recibida de AFC.”);
byte[] pdf = this.afcService.recogerFirma(this.token);
// Preparar ficheros para descarga
this.name = (String)
AtlasFacesUtils.loadFromSession(PARAM_FILE_NAME, true);
this.fileId = (URL)
AtlasFacesUtils.loadFromSession(PARAM_FILE_PATH, true);
// Guardar contenido de fichero firmado en disco
this.outputPath = setSignedFile(name, new ByteArrayInputStream(pdf));
}
// Redirigir a la pagina de descarga del fichero
log.info(“Redireccionando a página “ + VISTA_RESULTADO);
AtlasFacesUtils.navigateTo(VISTA_RESULTADO);
} catch (ServiceException e) {
log.error(“Error procesando firmas en AFC”, e);
AtlasFacesUtils.addErrorMessage(“Error procesando firmas en AFC”);
}
}
}
ATENCION
Si se opta por implementar @PostConstruct es muy importante que el archivo web.xml de la aplicación NO
tenga el atributo metadata-complete, de la etiqueta <web-app> con valor true ya que esto puede dar
problemas a la hora de interpretar la anotación en algunos servidores de aplicaciones.
26 de 43
Framework Atlas
Servicios de Firma AFC Cliente
8. EJEMPLO IMPLEMENTACIÓN PDF HASH
La firma masiva de documentos PDF se realiza contra los ficheros hash de los pdfs, de esta forma se evita que los
ficheros tengan que viajar a la aplicación de firma y que el rendimiento de la firma sea mejor ya que el tamaño del
hash es el mismo independientemente del tamaño del fichero a firmar. La generación de los hash se hace en la
aplicación cliente por lo tanto en el caso de firma masiva antes de llamar a AFC hay que hacer una serie de
operaciones.
Los pasos para la realización de una firma masiva son:
5. Creación de una clase que implemente el interfaz PdfFileProvider
6. Página firmaPdfMasiva.xhtml: página que se encargará de seleccionar el certificado de firma.
7. Solicitud de la firma en FirmaPdMasivaAfcBean.java esta acción se encargará de preparar los
hash de los ficheros y solicitar la operación de firma a AFC y redirigir al usuario a AFC_Cliente.
8. Página firmaPdfMasivaDesdeAfc.xhtml: en el retorno del usuario desde AFC esta página redirigirá
el control de ejecución al bean FirmaPdfMasivaResultadoAfcBean.
9. Acción FirmaPdfMasivaResultadoAfcBean.java: esta acción se encargará de gestionar el
retorno desde AFC e incrustar las firmas en los PDF.
10. Página firmaPdfMasivaResultado.xhtml: página que muestra el resultado de la firma y permite
descargar tanto los ficheros originales como los firmados
27 de 43
Framework Atlas
Servicios de Firma AFC Cliente
8.1.1.
Implementación de la Interfaz PdfFileProvider
Cuando se quiere realizar una firma masiva de documentos Pdf en cliente, será necesario implementar esta
interfaz. Dicha interfaz es una extensión de otra interfaz base llamada FileProvider.
Esta implementación se encargará de interactuar con los servicios de firma para proporcionar la información
necesaria y recoger los ficheros firmados.
En los ejemplos de la aplicación atlas_integracion_asf, el tipo del identificador en que se basa la interfaz es una
URL. Este objeto es el más conveniente si los ficheros residen en disco. Para ficheros en base de datos se pueden
utilizar objetos Long o String que identifiquen la clave primaria de este. Otra opción es construir un bean de datos
con la información necesaria para identificar el fichero en el sistema donde este resida, y establecer su tipo como Id
de la interfaz. La única restricción es que este objeto ha de ser Serializable. Una vez establecido el tipo del
identificador del fichero, la implementación de PdfFileProvider planteará pocos problemas.
FileProvider
public interface FileProvider<T extends Serializable> {
/**
* Devuelve una lista de identificadores que serán iterados para obtener
* los ficheros a firmar.
* @return
*/
T[] getFileIds() throws ServiceException;
/**
* Devuelve un objeto InputStream del fichero a firmar. El fichero será
* elegido en base al identificador pasado
* @param fileId
* @return
*/
InputStream getFileToSign(T fileId) throws ServiceException;
/**
* A este metodo se entrega el objeto InputStream del fichero ya firmado
* junto con su identificador para que sea almacenado.
* @param fileId
* @param signed
*/
void setSignedFile(T fileId, InputStream signed) throws ServiceException;
28 de 43
Framework Atlas
Servicios de Firma AFC Cliente
La interfaz PdfFileProvider permite además configurar la apariencia de la firma PDF (solo en casos estrictamente
necesarios) y aportar información para la inserción del código COVE.
PdfFileProvider
public interface PdfFileProvider<T extends Serializable> extends FileProvider<T> {
/**
* Metodo para personalizar la apariencia de la firma de pdf. Si se devuelve
* null, la apariencia será la estándar.
* @param fileId identificador del fichero
* @return objeto que renderizará la apariencia de la firma pdf
* @throws ServiceException
*/
PdfSignatureAppearanceGenerator getPdfAppearance(T fileId)
throws ServiceException;
/**
* Retorna un objeto con información necesaria para obtener el código
* COVE e insertarlo en el documento
* @param fileId identificador del fichero sobre el que se está pidiendo
* la información COVE.
* @return objeto de datos de COVE.
*/
CoveInfo getCoveInfo(T fileId);
/**
* Debe retornar un objeto {@link SignInfo} con la informacion de firma
* relativa al fichero con el identificador pasado
* @param fileId identificador del fichero a firmar
* @return devuelve la configuarción de AFC para este fichero.
*/
SignInfo<T> getSignInfo(T fileId);
/**
* Retorna la URI de visualización del fichero cuando se selecciona la
* operacion en AFC. La implementación de esta interfaz deberá
* proporcionar una URI donde se pueda descargar el fichero con el
* id indicado.
* @param fileId
* @return
*/
URI getDownloadUri(T fileId);
}
29 de 43
Framework Atlas
Servicios de Firma AFC Cliente
La forma de uso de esta interfaz será la siguiente:
1. En un primer estado se llamará al método getFileIds() y la implementación de esta interfaz tendrá
que retornar una lista de identificadores únicos, uno por cada fichero que se quiera firmar.
2. Por cada uno de los identificadores entregados en el paso anterior se solicitará el contenido a firmar
llamando al método getFileToSign(id) . La implementación deberá retornar un objeto InputStream
apuntando al contenido del fichero. Se realizarán tantas llamadas a getFileToSign como identificadores se
entreguen en el paso 1.
3. Una vez concluido el proceso de firma masiva, el sistema realizará llamadas a setSignedFile() para
entregar a la implementación los ficheros firmados. Se realizarán tantas llamadas como identificadores se
entreguen en el paso 1.
La interfaz FileProvider está parametrizada según el tipo de identificadores pasados. El tipo concreto de la interfaz
lo decidirá la implementación aportando los Ids de los ficheros a firmar. El único requisito sobre el tipo del
identificador es que este sea Serializable. Este puede ser un bean con atributos que identifiquen el fichero en el
sistema destino, o un único código. En los ejemplos del capítulo siguiente, dado que los ficheros de prueba residen
en el sistema, se ha establecido el identificador de fichero como un objeto de tipo URL que apuntará a la ubicación
de este en el disco.
En cuanto a la apariencia de la firma pdf, las posibilidades son las siguientes:
1. Si la apariencia es igual en todos los ficheros (tipos de letra, coordenadas, etc), la implementación más
simple es la siguiente:
2. Las configuraciones de apariencia de firma son distintas para cada fichero (distinta configuración de fuente
o de coordenadas).
30 de 43
Framework Atlas
Servicios de Firma AFC Cliente
Si la apariencia es igual en todos los ficheros (tipos de letra, coordenadas, etc), la implementación más
simple es la siguiente:
Implementación de PdfFileProvider
/**
* Apariencia personalizada. No se establece por defecto. El controlador lo hara
*/
PdfSignatureAppearanceGenerator appearance = null;
/**
* Obtiene la apariencia de la firma previamente almacenada.
* Solo para ficheros PDF.
*/
@Override
public PdfSignatureAppearanceGenerator getPdfAppearance(URL fileId) {
return this.appearance;
}
/**
* Establece la apariencia de la firma de los documentos PDF.
* El uso normal es almacenar aqui
* una versión de apariencia acorde a los metadatos de la firma
* obtenidos de AFC_Cliente.
* @param appearance implementación de apariencia de firma en documentos pdf.
*/
public void setAppearance(PdfSignatureAppearanceGenerator appearance) {
this.appearance = appearance;
}
dejando la responsabilidad de establecer la apariencia a la clase que instancia este proveedor de ficheros pdf
(se verá en detalle en los ejemplos de firma masiva).
31 de 43
Framework Atlas
Servicios de Firma AFC Cliente
Si las configuraciones de apariencia de firma son distintas para cada fichero (distinta configuración de
fuente o de coordenadas).
Este es el caso más general. Lo primero que habrá que hacer es obtener los metadatos de cada fichero y
preparar el método getPdfAppareace para devolver un objeto PdfSignatureAppearanceGenerator
creado a partir de los metadatos.
Implementación de PdfFileProvider DemoPdfProvider.java
/**
* Obtiene los metadatos de todos los ficheros a firmar
* Estos están definidos en AFC_GEST / Tipos de documento y Formatos de Firma
*
* @param afcService librería de operaciones en cliente de AFC
* @throws ServiceException
*/
public void obtenerMetadatosFirma(AfcOpClienteService afcService)
throws ServiceException {
// Obtener los ids de los ficheros a firmar
if (this.fileIds == null) {
getFileIds();
}
// Recopilar los metadatos de firma para cada fichero
for (URL fileId : this.fileIds) {
// Preparar informacion de firmado para el fichero
SignInfo<URL> signInfo = new SignInfo<URL>();
this.signInfos.put(fileId, signInfo);
// Almacenar informacion de acceso a AFC
signInfo.setProviderId(fileId);
signInfo.setDocumentoTipo(getAfcTipoFirma(fileId));
signInfo.setNumeroFirma(getAfcNumeroFirma(fileId));
signInfo.setTitulo(getName(fileId));
}
// Pedir todos los metadatos a AFC en una sola llamada
// Rellena el campo metadatosFirma de cada signInfo
afcService.getMetadatosFirma(this.signInfos.values()
.toArray(new SignInfo[0]));
}
/**
* Devuelve la apariencia de la firma PDF configurada segun los metadatos en AFC
*/
@Override
public PdfSignatureAppearanceGenerator getPdfAppearance(URL id) {
SignInfo signInfo = this.signInfos.get(id);
if (signInfo == null) {
throw new ServiceException("El Id pasado no existe.");
}
return PdfSignatureAppearanceAfc.getPdfAppearance(
signInfo.getMetadatosFirma());
}
32 de 43
Framework Atlas
Servicios de Firma AFC Cliente
Esta implementación depende de una estructura de datos de objetos SignInfo. Este objeto es una utilidad para
recoger los datos necesarios para la firma:
SignInfo.java
public class SignInfo<E extends Serializable> implements Serializable, Cloneable {
/** Identificador único del elemento a firmar */
private E providerId;
/** Código de tipo de firma. Parametrizado en AFC_GEST */
private String documentoTipo;
/** Código de numero de firma */
private String numeroFirma = "1"; // valor por defecto
/** Informacion para generar COVE */
private CoveInfo coveInfo;
/** Titulo del documento a mostrar en la pantalla de firma de AFC */
private String titulo;
/** Identificador del fichero para la descarga */
private UUID uuid;
/** Metadatos de la firma en AFC - Definidos en AFC_GEST */
private ResultadoSolicitarDatosFirma metadatosFirma;
...
Todos estos parámetros son obligatorios.
Las implementaciones de esta interfaz se verán en más detalle en los ejemplos de código.
8.1.2.
Selección del certificado cliente para la firma
En la firma masiva la selección del certificado se ha de hacer en la aplicación cliente ya que para poder preparar
los pdfs para la firma y hacer los hash es necesario tener previamente el certificado digital con el que se va a
firmar.
El componente de selección de certificados usado está en la librería atlasfrm-componentes-lib. Se puede ver un
ejemplo de uso en la aplicación de ejemplo atlas_integracion_asf:
src/main/webapp/secure/afc/firmaDigital/cliente/firmaPdfMasiva.xhtml
33 de 43
Framework Atlas
Servicios de Firma AFC Cliente
<html xmlns="http://www.w3.org/1999/xhtml"
...
xmlns:atlasafccrypt="http://atlas.core.componentes/jsf/atlasafccrypt">
<head
<atlasafccrypt:head />
</head>
.
.
<atlasafccrypt:certificados debug="true"
assignTo="#{firmaPdfMasivaAfcBean.certificado}" />
Para la carga del certificado, el applet <atlasafccrypt:certificados cargará 2 ficheros .js, a partir de la
versión 1.2.8 de atlas no será necesario ninguna configuración, en versiones anteriores será necesario disponer de
las siguientes variables en nuestro enviroment.properties
:
environment.properties
afc.clientJSUrl=https://desarrollo3.madrid.org/afirma/firma
afc.clientMiniJsUrl=https://desarrollo3.madrid.org/afirma/mini
Donde desarrollo3 correspondería con el entorno.
Además de la configuración siguiente en el fichero de configuración de afc de Spring:
applicationContext-services-afc.xml
<bean id="atlasAfcConfiguration"
class="atlas.componentes.afccrypt.AtlasAfcConfiguration">
<property name="clientJSUrl" value="${afc.clientJSUrl}" />
<property name="clientMiniJSUrl" value="${afc.clientMiniJsUrl}" />
</bean>
NOTA: la configuración arriba indicada NO debe existir para proyectos atlas iguales o superiores a 1.2.8
Los atributos disponibles de este componente son:
Atributo
Obligatorio
Valor por
defecto
Descripción
34 de 43
Framework Atlas
Servicios de Firma AFC Cliente
filtrarCAs
NO
true
Si el valor es true, se filtrarán los certificados listados en el combo
según la configuración en la plataforma ASF en la operación de
VERIFICACION.
Si el valor es una expresión de JSF que apunta a una variable de un
ManagedBean, se tomará el certificado almacenado en el Bean como
referencia de filtrado en lugar del certificado de login. El certificado
debe estar cifrado en Base64.
assignTo
NO
--
Si el valor es una expresión JSF que apunta a un atributo de un
ManagedBean, cada vez que el usuario seleccione un certificado, este
se enviará al servidor y se guardará en el atributo configurado.
cargarCerts
NO
true
Si el valor es true se cargarán los certificados; en caso contrario se
cargará el applet de firma, pero no los certificados.
debug
NO
false
Si el valor es true se mostrará un panel de log. El atributo debug solo
se podrá utilizar mientras se desarrolla y prueba la página
notify
NO
--
En este parámetro se puede indicar el nombre de una función
javascript a la que se llamará cada vez que se seleccione un
certificado.
forzarCert
NO
--
Si el valor es una expresión JSF que apunta a una variable de un
ManagedBean, solo se mostrará el certificado de la variable en la
selección (el certificado forzado debe estar en el almacén de
certificados del usuario).
35 de 43
Framework Atlas
Servicios de Firma AFC Cliente
8.1.3.
Selección del certificado cliente para la firma
En el método procesarFirma de FirmaPdfMasivaAfcBean es donde se generan los hash de los ficheros pdf (se
hace en local) y se envian a firma a AFC
procesarFirma() en FirmaPdfMasivaAfcBean.java
@ManagedProperty(value="#{afcOpClienteService}")
private AfcOpClienteService afcService;
@ManagedProperty(value="#{fileProvider}")
private DemoPdfFileProvider fileProvider;
public String procesarFirma() {
…
// Obtener metadatos de firma para todos los tipos de firma
log.info("Solicitando metadatos de firma...");
fileProvider.obtenerMetadatosFirma(this.afcService);
// Obtener el certificado con el que firmar
X509Certificate cert =
CertificateUtil.getCertificateFromString(this.certificado);
// Configurar URLs de retorno
String urlOk = DescargaPdf.getBaseUrl() + VISTA_RESULTADO;
String urlError = urlOk + "?error=true";
// Crea los hash de los pdf prepara la firma de los mismos
String afcUrl = afcService.solicitarFirmaPdfMasiva(fileProvider,
opcionesPresentacion cert, urlOk, urlError);
// Guardar provider en sesión para el retorno de AFC
AtlasFacesUtils.storeOnSession(PARAM_FILE_PROVIDER, this.fileProvider);
…
}
Antes de realizar la llamada a afcService.solicitarFirmaPdfMasiva será necesario implementar el objeto
fileProvider y recuperar el certificado desde la página como se ha descrito anteriormente.
En caso de la llamada a AFC el procedimiento es el mismo que con la firma individual, dependiendo de la opción
de presentación escogida, se redirigirá o se mostrara un componente iFrame.
36 de 43
Framework Atlas
Servicios de Firma AFC Cliente
8.1.4.
Recibir la respuesta de las firmas.
En el retorno se comprobará si ha habido errores y se recogerá el documento firmado (si no ha habido problemas).
En JSF no existe ninguna forma de ejecutar una acción a partír de una URL externa, siempre se direccionarán
páginas. Para redirigir la respuesta a un método de un ManagedBean y poder recoger el fichero firmado se utiliza
la siguiente sección de código:
firmaPdfIndividualDesdeAfc.xhtml
<ui:composition template=”/WEB-INF/layout/vc.xhtml”>
<f:metadata>
<f:viewParam name=”error” required=”false”
value=”#{firmaPdfMasivaResultadoAfcBean.error}” />
<f:viewParam name=”token” required=”true”
value=”#{firmaPdfMasivaResultadoAfcBean.token}” />
<f:event type=”preRenderView”
listener=”#{firmaPdfMasivaResultadoAfcBean.procesar}” />
</f:metadata>
</ui:composition>
8.1.5.
Recogida de firmas y procesado de las mismas
La gestión de los resultados se realiza en la clase FirmaPdfMasivaResultadoAfcBean:
Gestión resultado firma (FirmaPdfMasivaResultadoAfcBean.java)
37 de 43
Framework Atlas
Servicios de Firma AFC Cliente
public void procesar() {
try {
// Recuperar el provider de la sesión
this.fileProvider = (DemoPdfFileProvider)
AtlasFacesUtils.loadFromSession(PARAM_FILE_PROVIDER, true);
// Comprobar si ha habido errores
boolean bError = error != null && "true".equalsIgnoreCase(this.error);
if (bError) {
log.info("Respuesta de ERROR recibida de AFC.");
AtlasFacesUtils.addErrorMessage("Error en la firma");
Map<UUID, String> listaErrores =
this.afcService.recogerErrores(token);
// Encola todos los errores de AFC como error messages de jsf
for (UUID uuid : listaErrores.keySet()) {
String outPath = fileProvider.outputFiles
.get(this.providerIds.get(uuid));
String name = DemoPdfFileProvider.getName(outPath);
AtlasFacesUtils.addErrorMessage(name + ": " +
listaErrores.get(uuid));
}
} else {
log.info("Respuesta CORRECTA recibida de AFC.");
// Recupera las firmas de AFC y las inserta en los ficheros PDF
// se entregarán a la implementación de PdfFileProvider
this.providerIds = this.afcService.procesarFirmas(
this.fileProvider, token);
// Preparar ficheros para descarga
this.firmas = new ArrayList<DescargaBean>();
for (UUID id : this.providerIds.keySet()) {
String outPath =
fileProvider.outputFiles.get(this.providerIds.get(id));
String name = DemoPdfFileProvider.getName(outPath);
firmas.add(new DescargaBean(id.toString(), name));
}
// Ordenar la lista por el nombre del fichero
Collections.sort(firmas, new ComparatorByName());
}
// Redirigir a la pagina de descarga de los ficheros
log.info("Redireccionando a página " + VISTA_RESULTADO);
AtlasFacesUtils.navigateTo(VISTA_RESULTADO);
} catch (ServiceException e) {
log.error("Error procesando firmas en AFC", e);
AtlasFacesUtils.addErrorMessage("Error procesando firmas en AFC");
}
}
Para obtener información ampliada, consultar la aplicación de ejemplo.
9. EJEMPLO CADES/XADES
38 de 43
Framework Atlas
Servicios de Firma AFC Cliente
9.1.
FIRMA INDIVIDUAL DOCUMENTOS XML
El procedimiento para ejecutar una firma XAdES es similar al de firma individual de Pdf. Los pasos a seguir son los
mismos y solo hay pequeñas variaciones como el nombre de los métodos a llamar y la configuración de la firma.
En el caso de la firma xades individual, tanto firma normal, cofirma o contrafirma, no será obligatorio solicitar los
metadatos de la firma, por lo que las interacciones con AFC quedan reducidas a dos: solicitud de firma y recogida
del fichero firmado.
Solicitud de firma XAdES (FirmaXadesIndividualAfcBean.java)
private String xml;
private String visualizacion;
...
// Obtener el certificado de login para filtrado en pagina de firma
X509Certificate loginCert = UserUtil.getUserCertificate();
// Configurar URLs de retorno
String urlOk = DescargaUtil.getBaseUrl()
String urlError = urlOk + "?error=true";
+ VISTA_AFC_RESULTADO;
String afcUrl = afcService.solicitarFirmaIndividual(xml.getBytes(),
getSignInfoFirma(), loginCert, opcionesPresentacion urlOk, urlError);
if (this.visualizacion.equals("3")) {
this.signUrl = afcUrl;
mostrarPanelFlotante =true;
} else {
AtlasFacesUtils.redirectTo(afcUrl);
}
La única diferencia entre firmas, cofirmas y contrafirmas Xades es el tipo de documento pasado en el objeto
SignInfo. En la aplicación de ejemplo, una vez realizara una firma XAdES se activan las opciones de cofirma y
contrafirma (solo son útiles con ficheros ya firmados).
39 de 43
Framework Atlas
Servicios de Firma AFC Cliente
9.2.
FIRMA MASIVA DOCUMENTOS XML
El caso de la firma XAdES masiva es más sencillo que la firma de Pdf y no necesita de una implementación de
interfaz para intercambio de datos. A continuación se muestra un ejemplo de código:
Solicitar firma XAdES (FirmaXadesMasivaAfcBean.java)
// Obtener el certificado de login para filtrado en pagina de firma
X509Certificate loginCert = UserUtil.getUserCertificate();
Map<URL, byte[]> xmls = getXmlFiles();// Ficheros XML de demostracion
// Estructrura de objetos SignInfo (info de firma) y contenidos de los XML
Map<SignInfo<URL>, byte[]> datos = new HashMap<SignInfo<URL>, byte[]>();
for (URL url : xmls.keySet()) {
datos.put(getSignInfo(url), IOUtils.toByteArray(url));
}
// Configurar URLs de retorno
String urlOk = DescargaUtil.getBaseUrl()
String urlError = urlOk + "?error=true";
+ VISTA_AFC_RESULTADO;
// Configurar datos de firmado
log.info("Realizando peticion de firma masiva....");
String afcUrl = this.afcService.solicitarFirmaXadesMasiva(datos, loginCert,
opcionesPresentacion, urlOk, urlError);
// Guardar nombre para guardar el resultado de la firma en AFC
...
if (this.visualizacion.equals("3")) {
this.signUrl = afcUrl;
mostrarPanelFlotante =true;
} else {
AtlasFacesUtils.redirectTo(afcUrl);
}
Recogida de documentos firmados (FirmaXadesMasivaResultado.java)
boolean bError = error != null && "true".equalsIgnoreCase(this.error);
if (bError) {
log.info("Respuesta de ERROR recibida de AFC.");
AtlasFacesUtils.addErrorMessage("Se han producido errores en la firma.");
Map<UUID, String> listaErrores = this.afcService.recogerErrores(token);
...
} else {
log.info("Respuesta CORRECTA recibida de AFC.");
// Procesar firmas y almacenar ficheros en disco
Map<UUID, String> firmas = this.afcService.recogerFirmas(token);
...
9.3.
FIRMA INDIVIDUAL CADES
40 de 43
Framework Atlas
Servicios de Firma AFC Cliente
El procedimiento para ejecutar una firma CAdES es similar al de firma XAdES. Los pasos a seguir son los mismos
y solo hay pequeñas variaciones como el nombre de los métodos a llamar y la configuración de la firma.
En el caso de la firma cades individual, no será obligatorio solicitar los metadatos de la firma, por lo que las
interacciones con AFC quedan reducidas a dos: solicitud de firma y recogida del fichero firmado.
Solicitud de firma CAdES (FirmaCadesIndividualAfcBean.java)
private byte[] data;
private String visualizacion;
...
// Obtener el certificado de login para filtrado en pagina de firma
X509Certificate loginCert = UserUtil.getUserCertificate();
// Configurar URLs de retorno
String urlOk = DescargaUtil.getBaseUrl()
String urlError = urlOk + "?error=true";
+ VISTA_AFC_RESULTADO;
String afcUrl = afcService.solicitarFirmaIndividual(data, getSignInfoFirma(),
loginCert, opcionesPresentacion, urlOk, urlError);
log.info("Enviando usuario a AFC: '" + afcUrl + "'.");
AtlasFacesUtils.redirectTo(afcUrl);
41 de 43
Framework Atlas
Servicios de Firma AFC Cliente
9.4.
FIRMA MASIVA CADES
El caso de la firma CAdES masiva es también muy similar a la firma XAdES masiva, y no necesita de una
implementación de interfaz para intercambio de datos. A continuación se muestra un ejemplo de código:
Solicitar firma CAdES (FirmaCadesMasivaAfcBean.java)
// Obtener el certificado de login para filtrado en pagina de firma
X509Certificate loginCert = UserUtil.getUserCertificate();
Map<URL, byte[]> ficheros = getDemoFiles();// Ficheros de demostracion
// Estructrura de objetos SignInfo (info de firma) y contenidos de los ficheros
Map<SignInfo<URL>, byte[]> datos = new HashMap<SignInfo<URL>, byte[]>();
for (URL url : ficheros.keySet()) {
datos.put(getSignInfo(url), IOUtils.toByteArray(url));
}
// Configurar URLs de retorno
String urlOk = DescargaUtil.getBaseUrl()
String urlError = urlOk + "?error=true";
+ VISTA_AFC_RESULTADO;
// Configurar datos de firmado
log.info("Realizando peticion de firma masiva....");
String afcUrl = this.afcService.solicitarFirmaCadesMasiva(datos,
loginCert,opcionesPresentacion, urlOk, urlError);
// Guardar nombre para guardar el resultado de la firma en AFC
...
log.info("Enviando usuario a AFC: '" + afcUrl + "'.");
AtlasFacesUtils.redirectTo(afcUrl);
Recogida de documentos firmados (FirmaCadesMasivaResultado.java)
boolean bError = error != null && "true".equalsIgnoreCase(this.error);
if (bError) {
log.info("Respuesta de ERROR recibida de AFC.");
AtlasFacesUtils.addErrorMessage("Se han producido errores en la firma.");
Map<UUID, String> listaErrores = this.afcService.recogerErrores(token);
...
} else {
log.info("Respuesta CORRECTA recibida de AFC.");
// Procesar firmas y almacenar ficheros en disco
Map<UUID, String> firmas = this.afcService.recogerFirmas(token);
...
42 de 43
Framework Atlas
Servicios de Firma AFC Cliente
ENLACES RELACIONADOS
Producto
URL
Axis2
http://ws.apache.org/axis2/
Certificados ICM
http://desarrollo.madrid.org/certificados/
Descarga certificados de prueba
http://desarrollo.madrid.org/certificados/descarga_de_certificados.htm
43 de 43
Descargar