org.viafirma.nucleo.autenticacion.imp.AutenticacionAppletBridgeImp.java Source code

Java tutorial

Introduction

Here is the source code for org.viafirma.nucleo.autenticacion.imp.AutenticacionAppletBridgeImp.java

Source

/* Copyright (C) 2007 Flix Garca Borrego (borrego at gmail.com)
      
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
      
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.
      
   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA 
 */

package org.viafirma.nucleo.autenticacion.imp;

import java.io.IOException;
import java.security.cert.X509Certificate;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.viafirma.excepciones.CodigoError;
import org.viafirma.nucleo.Nucleo;
import org.viafirma.nucleo.autenticacion.AutenticacionBridge;
import org.viafirma.util.FaceletsUtil;
import org.viafirma.util.XmlSignUtil;

/**
 * Implementacin especfica encargada de la recuperacin del certificado del cliente. 
 * Esta implementacin se basa en el uso de un Applet para recuperar el
 * certificado.
 * 
 * @author Felix Garcia Borrego (borrego at gmail.com)
 */
public class AutenticacionAppletBridgeImp extends HttpServlet implements AutenticacionBridge {

    /**
    * 
    */
    private static final long serialVersionUID = 1L;

    /**
     * Logger.
     */
    private Log log = LogFactory.getLog(AutenticacionAppletBridgeImp.class);

    /**
     * URI a la que se redirecciona para autenticar al usuario
     */
    public static final String URI_AUTENTICACION = "/autenticacionApplet/login.jsf";

    private static AutenticacionAppletBridgeImp singleton = new AutenticacionAppletBridgeImp();

    /**
     * Recupera la nica instancia del bridge. Basandose en el patron singleton
     * 
     * @return Instancia de la bridge
     */
    public static AutenticacionAppletBridgeImp getInstance() {
        return singleton;
    }

    /**
     * Crea una nueva instancia. Este mtodo solo es admisible que sea llamado
     * desde el Contenedor de servlet para crear el servlet.
     * 
     */
    public AutenticacionAppletBridgeImp() {
        super();
        // debe ser pblica por ser un Servlet( esto hace que el singleton se
        // vea modificado)
    }

    /***
     * Para solicitar el certificado redirecciona al cliente a una pgina que
     * contiene un Applet que solicita al usuario su certificado.
     * 
     * @see org.viafirma.nucleo.autenticacion.AutenticacionBridge#generarSolicitudCertificado(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    public void generarSolicitudCertificado(HttpServletRequest request, HttpServletResponse response) {
        log.debug("Iniciando solicitud de certificado");
        // almaceno el identificador de sessin( posteriormente se utiliza para
        // cachear los diferentes certificados)
        request.setAttribute("sessionID", request.getSession().getId());

        FaceletsUtil.forward(request, response, URI_AUTENTICACION);
    }

    /**
     * Este mtodo es invocado por el Applet de autenticacin cuando completa la
     * autenticacin. El mtodo recupera el identificador de sessin para
     * identificar este identificador con la peticin y redirecciona al nucleo
     * para que procese el certificado.
     * 
     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String resultado = request.getParameter("result");
        Nucleo nucleo = Nucleo.getInstance();
        if ("OK".equalsIgnoreCase(resultado)) {
            // El applet recupero correctamente el certificado y este fue
            // almacenado correctamente por el nucleo
            log.debug("El certificado ha sido ya recuperado, iniciamos su validacin");
            String sessionID = request.getParameter(Nucleo.SESSION_ID);

            // comprobamos el certificado y si todo esta correcto
            // redireccionamos
            nucleo.finAutenticacion(sessionID, request, response);
        } else if ("errorVerificacion".equalsIgnoreCase(resultado)) {
            // El certificado no es vlido
            nucleo.redireccionarError(CodigoError.ERROR_CERTIFICADO_NO_VALIDO, request, response);
        } else if ("error".equalsIgnoreCase(resultado)) {
            // se ha producido algun error lo enviamos a una pgina de error
            // informando de lo sucedido
            nucleo.redireccionarError(CodigoError.ERROR_CERTIFICADO_NO_FOUND, request, response);
        } else if ("cancel".equalsIgnoreCase(resultado)) {
            // El usuario ha cancelado y no ha enviado ningun certificado al
            // servidor.
            nucleo.redireccionarError(CodigoError.WARNING_CERTIFICADO_NO_ENVIADO, request, response);
        } else {
            log.error("Resultado no esperado:" + resultado);
            throw new ServletException("Resultado no espsrado :" + resultado);
        }
    }

    /**
     * Este mtodo es invocado por el Applet de autenticacin cuando recupera el
     * certificado. Recuperamos el certificado enviado por el applet( dentro de
     * un XML-sig), lo procesamos y lo almacenamod en la cache para que sea
     * recuperado posteriormente por el Nucleo.
     * 
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String resultado = request.getParameter("result");
        if ("OK".equalsIgnoreCase(resultado)) {
            // el applet ha podido recuperar el certificado correctamente,
            // iniciamos el proceso de autenticacin y validacin
            log("El usuario ha indicado un certificado");
            recuperarCertificado(request, response);

        } else {
            // el certificado no ha podido ser recuperado por el certificado
            log("El usuario no ha indicado un certificado");

        }
    }

    /**
     * Recupera el certificado enviado por el navegador y lo almacena en el
     * nucleo.
     * 
     * Proceso:
     * 
     * <pre>
     * 1.- Recupera el XmlSignature desde el parametro message
     * 2.- Desde el XmlSignature recupera el X509Certificado
     * 3.- Se lo pasa al ncleo para que lo valide.
     * </pre>
     * 
     * @param request
     * @param response
     * @throws ServletException
     */
    private void recuperarCertificado(HttpServletRequest request, HttpServletResponse response)
            throws ServletException {

        try {
            // certificado en xml codificado en base 64
            String xmldoc_b64 = request.getParameter("message");

            // recupero el identificador de sessin con el que posteriormente
            // poder identificar este objeto.
            String sessionID = request.getParameter("sessionID");

            XmlSignUtil xmlSignParser = XmlSignUtil.getInstance();
            // recupero el XmlSignature generado por el applet de autenticacin
            // ( Siempre tiene que aparecer 1
            X509Certificate certificadoX509 = xmlSignParser.parseCertificado(xmldoc_b64).get(0);

            // mostramos el certificado recuperado
            if (log.isDebugEnabled()) {
                log.debug("Recuperado certificado " + certificadoX509.getIssuerDN().getName());
            }

            // enviamos el certificado al ncleo para que este compruebe la
            // validez del mismo
            Nucleo nucleo = Nucleo.getInstance();
            // almacena el certificado recuperado en el ncleo para su
            // procesamiento posterior.
            nucleo.cachearCertificado(sessionID, certificadoX509);

        } catch (Exception e) {
            throw new ServletException(e);
        }

    }

}