lunes, 13 de septiembre de 2010

Spring Remoting - Conexiones en Runtime

Resumen:
Usando Spring, crearemos una conexión por RMI en runtime, sin necesidad de especificarlo en el XML.


Breve introducción a Spring Remoting

Spring nos da soporte para hacer remoting  usando diferentes protocolos : RMI, HttpInvoker, Hessian/Burlap, etc.

Básicamente, para cada protocolo nos provee de una serie  Exporters y FactoryBeans que nos facilitan el trabajo.

Siguiendo el ejemplo que aparece en la documentación, supongamos que en nuestra apliación tenemos las siguientes clases:

AccountService
public interface AccountService {
    public void insertAccount(Account account);
    public List getAccounts(String name);
}

AccountServiceImpl
// the implementation doing nothing at the moment
public class AccountServiceImpl implements AccountService {
    public void insertAccount(Account acc) {
        // do something...
    }
  
    public List getAccounts(String name) {
        // do something...
    }
}

Para hacer este código accesible, por ejemplo a través de RMI,  añadimos en nuestro fichero de configuración de spring un bean de la clase org.springframework.remoting.rmi.RmiServiceExporter
<!-- Our AccountService bean -->
<bean id="accountService" class="example.AccountServiceImpl" />

<!-- Exporting AccountService -->
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
    <property name="serviceName" value="AccountService"/>
    <property name="service" ref="accountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
    <!-- defaults to 1099 -->
    <property name="registryPort" value="1199"/>
</bean>


En este punto ya hemos expuesto nuestro accountService a través de RMI y por tanto podremos acceder de manera remota desde una aplicación cliente.

Ahora, para que nuestra aplicación cliente pueda ejecutar los métodos de accountService, hay que definir en su fichero de configuración un Proxy Factory Bean que será el encargado de crear el proxy que se conectará a nuestro servicio.

Para ello, definimos un bean org.springframework.remoting.rmi.RmiProxyFactoryBean

<bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
    <property name="serviceUrl" value="rmi://my_server:1199/AccountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

En este punto, desde nuestra aplicación cliente podremos invocar los métodos de nuestro servicio como si fueran locales:
  // client application
  ...
  List <Account> accounts = accountService.getAccounts(someValue);
  ...

¿ Cuál es el problema ?

Tal y como lo hemos definido, cuando nuestra aplicación cliente arranca :

  1. Debe conocer a priori la url del servicio (rmi://my_server:1199/AccountService)
  2. El servicio al que se quiere conectar debe estar levantado 
Pero ....
¿ Qué ocurre si la url se proporciona en tiempo de ejecución ?
¿ Qué ocurre cuando el servicio no está activo ? ¿ no podemos arrancar nuestra aplicación cliente ?


Solución :

Una vez conozcamos la URL y nos asegurmeos de que el servicio está levantado, crearemos el Proxy en tiempo de ejecución.

Para ello, simularemos el comportamiento que tienen los beans en tiempo de inicialización.

Observando la clase RmiProxyFactoryBean vemos que implementa las interfaces:



Si Spring fuera a instanciar un bean del tipo RmiProxyFactoryBean que hubiéramos definido en el fichero de configuración,  durante la Fase de Inicialización del Contexto de Aplicación,  llamaría automáticamente al método afterPropertiesSet(), para configurar el bean y posteriormente lammaría al método getObject() para obtener una instancia, en este caso del proxy.

Simulamos pues este comportamiento :

   String url = "rmi://my_server:1199/AccountService";

   // instanciamos el FactoryBean y le establecemos las properties
   RmiProxyFactoryBean factory = new RmiProxyFactoryBean();
   factory.setServiceUrl(url);
   factory.setServiceInterface(example.AccountService.class);
   
   // simulamos el comportamiento que tendría en tiempo de inicialización 
   factory.afterPropertiesSet();
   AccountService service = (AccountService) factory.getObject();

   // accedemos de la misma forma
   List <Account> accounts = accountService.getAccounts(someValue);

lunes, 6 de septiembre de 2010

Spring Security y SSO

RESUMEN:
Configuraremos una aplicación web para añadirle seguridad  usando Spring Security.
Posteriormente configuraremos la aplicación para autenticarnos mediante Single Sign On ( Usando el servidor CAS de jasig )

1. - Añadimos seguridad a una aplicación web ( sin CAS )


Primero descargaremos la aplicación demo de Loom. que nos servirá de base para nuestro ejemplo:

Accedemos a la página de descargas  y nos descargamos la demo:

$ wget http://downloads.sourceforge.net/project/loom/loom/2.1/loomdemo.war

Una vez hayamos descargado el fichero, necesitamos expandirlo para poder modificar la aplicación.

$ mkdir loomdemo
$ cd loomdemo
$ jar xvf ../loomdemo.war 


La aplicación loomdemo está basada en Spring y no viene con seguridad implementada.
Necesitaremos descargar y añadir las librerías relativas a Spring Security


$ cd WEB-INF/lib
$ wget http://www.jarvana.com/jarvana/archive-details/org/springframework/security/spring-security-acl/3.0.3.RELEASE/spring-security-acl-3.0.3.RELEASE.jar http://www.jarvana.com/jarvana/archive-details/org/springframework/security/spring-security-config/3.0.3.RELEASE/spring-security-config-3.0.3.RELEASE.jar http://www.jarvana.com/jarvana/archive-details/org/springframework/security/spring-security-core/3.0.3.RELEASE/spring-security-core-3.0.3.RELEASE.jar http://www.jarvana.com/jarvana/archive-details/org/springframework/security/spring-security-taglibs/3.0.3.RELEASE/spring-security-taglibs-3.0.3.RELEASE.jar http://www.jarvana.com/jarvana/archive-details/org/springframework/security/spring-security-web/3.0.3.RELEASE/spring-security-web-3.0.3.RELEASE.jar

El siguiente paso es modificar el fichero web.xml de la aplicación para añadirle seguirdad. Editamos el fichero WEB-INF/web.xml y añadimos al parámetro contextConfigLocation otro fichero de configuración de Spring ( que crearemos a continuación ) spring-security-config.xml

<context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>
   classpath:spring-config.xml
   classpath:spring-security-config.xml
 </param-value>
</context-param>

No nos debemos de olvidar de añadir también el filtro de seguridad Spring en el web.xml
<filter>
 <filter-name>springSecurityFilterChain</filter-name>
 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
 <filter-name>springSecurityFilterChain</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>



Crearemos primero un fichero de configuración de seguridad básico, para comprobar que todo funciona correctamente. Aseguraremos los accesos a /mortgages/create con el rol ROLE_USER y a /support/** con el rol ROLE_ADMIN. De paso solicitaremos que cualquier acceso se haga a través de https

$ vim WEB-INF/classes/spring-security-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:security="http://www.springframework.org/schema/security"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-3.0.xsd"
   default-autowire="byName">

 <security:http auto-config="true" path-type="ant">
   <security:intercept-url pattern="/mortgages/create" access="ROLE_USER"/>
   <security:intercept-url pattern="/support/**" access="ROLE_ADMIN"/>
   <security:intercept-url pattern="/**" requires-channel="https" />
   <security:logout logout-url="/logout" />
 </security:http>

 <security:authentication-manager>
   <security:authentication-provider>
     <security:user-service properties="/WEB-INF/user.properties"/>
   </security:authentication-provider>
 </security:authentication-manager>

</beans>

Los usuarios, roles y contraseñas los especificamos en el fichero user.properties
$ vim WEB-INF/user.properties

admin=admin,ROLE_ADMIN,ROLE_USER
user=user,ROLE_USER

Si todo ha ido correctamente, podemos desplegar la aplicación en Tomcat (copiamos la carpeta loomdemo a $CATALINA_HOME/webapps)

Una vez arrancado el Tomcat, podemos acceder a la aplicación : http://localhost:8080/loomdemo. Lo primero que vemos es que, tal y como le hemos especificado al requerir un canal seguro ( 8443 a través de https), nos hace automáticamente una redirección:



El siguiente paso es comprobar que funciona la seguridad. Para ello intentamos acceder a una URL protegida https://localhost:8443/loomdemo/mortgages/create Si todo está correcto, nos aparecerá una ventana solicitándonos el usuario y la contraseña:


Especificando un usuario definido previamente en el fichero user.properites (admin/admin) obtendremos el acceso:



Para poder hacer logout, añadiremos al menú lateral un enlace en donde además mostraremos el username.

Modificamos el fichero leftColumn.tag que se encuentra en WEB-INF/tags:

$ vim WEB-INF/tags/leftColumn.tag

<authz:authorize ifAnyGranted="ROLE_ADMIN,ROLE_USER">         
  Logged as :  <authz:authentication property="principal.username" />
  <ul>
    <li><l:url href="/logout" >logout</l:url></li>
  </ul>
</authz:authorize>

2. - Añadimos SSO - Autentificación por CAS a la aplicación:


El proceso para validar usuarios usando CAS, requiere de un servidor CAS, que es el encargado de comprobar las credenciales que aporta el usuario.




Para nuestro ejemplo, descargamos el servidor CAS de la página de Jasig y creamos el war usando maven

$ wget http://downloads.jasig.org/cas/cas-server-3.4.2.1-release.zip
$ unzip cas-server-3.4.2.1-release.zip
$ cd cas-server-3.4.2.1/cas-server-webapp/
$ mvn package
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 42 seconds
[INFO] Finished at: Mon Sep 06 10:39:11 WEST 2010
[INFO] Final Memory: 32M/58M
[INFO] ------------------------------------------------------------------------

Una vez creado el war, lo desplegamos en Tomcat:
$ target/cas.war $CATALINA_HOME/webapp/.

Comprobamos que se haya desplegado correctamente accediendo a http://localhost:8080/cas



Este servidor es una demo que autentifica a cualquier usuario siempre que el password sea igual al username. Introducimos admin/admin y validamos:


(*) Para hacer logout, accedemos a http://localhost:8080/cas/logout


En este punto ya tenemos arrancada nuestra aplicación a la que le hemos añadido seguridad y un servidor CAS. El siguiente paso es configurar nuestra aplicación para que se autentifique con el servidor.

Para no modificar el fichero anterior, creamos un fichero de configuración para la autentificación mediante CAS: spring-security-config-CAS.xml :

Nota: En lugar de usar localhost usaremos el nombre del servidor; en este caso myserver

$ vim WEB-INF/classes/spring-security-config-CAS.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:sec="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security-3.0.xsd">
 
<sec:http entry-point-ref="casEntryPoint" auto-config="true" path-type="ant">
  <sec:custom-filter before="CAS_FILTER" ref="casSingleSignOutFilter"/>
  <sec:custom-filter after="CAS_FILTER"  ref="casFilter"/>
  <sec:intercept-url pattern="/mortgages/create" access="ROLE_USER"/>
  <sec:intercept-url pattern="/support/**" access="ROLE_ADMIN"/>
  <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
  <sec:logout logout-success-url="https://myserver:8443/cas/logout" invalidate-session="true" logout-url="/logout" />
</sec:http>
 
<!-- which application am I authenticating -->
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
    <property name="service" value="https://myserver:8443/loomdemo/j_spring_cas_security_check"/>
    <property name="sendRenew" value="false"/>
</bean>
    
<!-- where do I go when I need authentication -->
<bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
    <property name="loginUrl" value="https://myserver:8443/cas/login"/>
    <property name="serviceProperties" ref="serviceProperties"/>
</bean>
 
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>
<bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" />
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
</bean>
    
<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider ref="casAuthenticationProvider" />
</sec:authentication-manager>
    
    
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
  <property name="userDetailsService" ref="userServices"/>
  <property name="serviceProperties" ref="serviceProperties"/>
  <property name="ticketValidator">
    <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
       <constructor-arg index="0" value="https://myserver:8443/cas"/>
    </bean>
  </property>
  <property name="key" value="my_password_for_this_auth_provider_only"/>
</bean>
   
<sec:user-service properties="/WEB-INF/user.properties" id="userServices"/>

</beans>

Ya solo nos queda especificar este fichero en lugar del anterior en el web.xml
<context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>
   classpath:spring-config.xml
   classpath:spring-security-config-CAS.xml
 </param-value>
</context-param>

Listo !!! .... ahora cuando intentemos acceder a una URL protegida, en lugar de redirigirnos a la antigua página de Login :


Nos redirigirá al servidor CAS :

martes, 31 de agosto de 2010

Tests con Selenium




Resumen:

  • Usando Selenium crearemos un test  en Java  para probar nuestra aplicación web.
  • Para facilitar la creación del test usaremos Selenium IDE, un add-on para firefox.
  • Para refinar el test que creemos, nos ayudaremos de XPath Checker, otro add-on para firefox.



Introducción :


Selenium  es un framework que nos permite realizar test sobre aplicaciones web.


Básicamente consta de :


  • Selenium Remote Control 
Es una herramienta que nos permite escribir tests en diferentes lenguajes de programación para acceder a sitios web.
Consta de dos partes :

       - Servidor  (Remote Control Server ), encargado de lanzar y controlar los navegadores sobre los que se realizan los tests.

       - Librerías clientes para los diferentes lenguajes de programación

  • Selenium IDE 
Es un add-on para Firefox que nos permite grabar ( y posteriormente reproducir ) la actividad que hagamos en Firefox (clicks, entrada de texto, etc. )





XPath Checker es un add-on para Firefox que nos permite ver la ruta XPath de un determinado elemento de la página





Creando y ejecutando tests

Una vez tengamos instalados los plugins. Abrimos Firefox y en el menú "Herramientas" abrimos Selenium IDE



Aparecerá la ventana del Selenium IDE


Volvemos a la ventana del navegador y navegamos por nuestra aplicación. En este ejemplo he usado la demo de Loom. Las acciones que vayamos realizando se irán registrando en la ventana de Selenium IDE. 


Una vez finalizada la navegación exportamos lo capturado por Selenium IDE como un test JUnit de java a través de la opción de menú "Export Test Case As..." 


El código generado :
package com.example.tests;
import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

public class Untitled extends SeleneseTestCase {
 public void setUp() throws Exception {
  setUp("http://change-this-to-the-site-you-are-testing/", "*firefox");
 }
 public void testUntitled() throws Exception {
  selenium.open("/loomdemo/mortgages/");
  selenium.click("link=Customers");
  selenium.waitForPageToLoad("30000");
  selenium.click("//div[@id='main']/div[1]/a");
  selenium.waitForPageToLoad("30000");
  selenium.type("customer.firstName", "Ernesto");
  selenium.type("customer.lastName", "Hernández");
  selenium.type("customer.idCard", "11111");
  selenium.type("prices[EUROPE]", "1000");
  selenium.type("prices[ASIA]", "1000");
  selenium.type("prices[AMERICA]", "1000");
  selenium.click("customer.creditType0");
  selenium.type("customer.password", "miPassword");
  selenium.type("confirmPassword", "miPassword");
  selenium.click("//input[@value='save']");
  selenium.waitForPageToLoad("30000");
 }
}


Modificamos el código para especificar en setUp() nuestro servidor (localhost:8080).

public class LoomDemoTest extends SeleneseTestCase
 ...
 setUp("http://localhost:8080/", "*firefox");

Listo, ya tenemos nuestra clase de test que podremos ejecutar cuando tengamos arrancado el Servidor de Selenium. En nuestro proyecto el arrancar el servidor Selenium lo podremos hacer por ejemplo usando un plugin de maven, aunque también lo podemos arrancar a mano.


$ java -jar target/dependency/selenium-server-1.0.1-standalone.jar


Una vez ejecutemos el test, se abrirán dos ventanas del navegador, una en donde irá apareciendo información sobre la ejecución del test




Y otra con el resultado del test ( nuestra aplicación )




Refinando los tests


En algunas ocasiones puede ser que necesitemos refinar nuestro test.
Supongamos que mientras grabábamos el test hicimos click en  el primer item del listado:


el código generado por Selenium IDE puede ser algo como:
selenium.open("/loomdemo/customers/list");
selenium.click("link=1 - in conguealiquet (ID: 5158319217)");
selenium.waitForPageToLoad("30000");

En donde vemos que se indica que haga click en el link con el texto "1 - in conguealiquet ... "
Un problema que puede ocurrir es que ese texto varíe ( datos de ejemplo ). 


En lugar de esto tal vez nos interesa especificar que haga click "en el primer elemento del listado". Para ello sustituiremos la expresión que le pasamos por parámetro al método click por otra ruta XPath.


Para calcular la ruta XPath del primer item del listado, sobre el enlace en concreto, haremos click con el botón derecho del ratón y seleccionamos "View XPath". Se nos abrirá la ventana del XPath con la ruta XPath del elemento seleccionado:

Usando el campo XPath podemos realizar búsquedas en la página, de esta forma podemos ver que además de la ruta que nos da por defecto  "id('main')/div[2]/ul[2]/li[1]/a" vemos que también nos sirve la ruta "//ul[2]/li[1]/a" . 

Podemos usar esta herramienta para comprobar rutas XPath. Por ejemplo :

 //div[@id="menu"]






Retomando nuestro test, podemos ahora sustituir  
selenium.click("link=1 - in conguealiquet (ID: 5158319217)");


por


selenium.click("//ul[2]/li[1]/a");



Con lo que nuestro test ahora siempre seleccionará el primer item de la lista independientemente del texto que contega.



lunes, 30 de agosto de 2010

Selenium y Firefox

RESUMEN:


Vamos a ver como crear un perfil de Firefox para usar con Selenium . Este perfil lo configuraremos para que nos permita conectarnos a través de https ( a un servidor con un certificado no firmado por una autoridad certicadora) sin que nos esté preguntando por la aceptación del certificado.

De paso, configuraremos el perfil de Firefox para que acepte automáticamente la descarga ficheros y los guarde en un determinado directorio.



1. - Creamos un perfil firefox que usaremos con Selenium


Para ello, arrancamos firefox en modo gestión de perfiles desde la línea de comandos.


$ firefox -ProfileManager -no-remote



Creamos un nuevo perfil que llamaremos Selenium y guardaremos en nuestro home, en la carpeta firefox-selenium-profile, que crearemos usando el botón "Choose folder"


Una vez creado, podremos seleccionarlo usando el Profile Manager de Firefox




2. - Configurar el perfil para que acepte un certificado determinado


Cuando accedemos por primera vez a un site con un certificado no firmado ( por ejemplo nuestra aplicación desplegada en Tomcat con un certificado que hemos creado nosotros mismo), Firefox detectará que no es una conexión verificada y preguntará qué queremos hacer.


Si estamos usando Selenium para realizar tests sobre nuestra aplicación, no nos interesa que nos esté preguntado esto en cada test qué hacer con el certificado. Para evitar esto, accederemos a nuestra URL con el nuevo perfil y aceptaremos el certificado.

$ firefox -P Selenium https://localhost:8443

Añadimos una excepción, obtenemos el certificado y confirmamos la excepción de seguridad


Cerramos Firefox. La siguiente vez que accedamos con este perfil,  no nos preguntará por el certificado


3.  - Configuramos Selenium para que use ese perfil.


Ahora cuando arranquemos el servidor Selenium le especificaremos qué perifl de Firefox queremos usar

 $ java -jar selenium-server-1.0.1-standalone.jar -firefoxProfileTemplate /home/ehdez/firefox-selenium-profile/



16:15:52.903 INFO - Java: Sun Microsystems Inc. 14.0-b16
16:15:52.914 INFO - OS: Linux 2.6.30.10-105.2.23.fc11.i686.PAE i386
16:15:52.969 INFO - v1.0.1 [2697], with Core v@VERSION@ [@REVISION@]
16:15:53.205 INFO - Version Jetty/5.1.x
16:15:53.207 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
16:15:53.208 INFO - Started HttpContext[/selenium-server,/selenium-server]
16:15:53.209 INFO - Started HttpContext[/,/]
16:15:53.214 INFO - Started SocketListener on 0.0.0.0:4444
16:15:53.217 INFO - Started org.mortbay.jetty.Server@110d81b



Si el servidor de Selenium lo arrancamos desde una tarea Ant :


<target name="start-selenium" >
<java jar="selenium-server-1.0.1-standalone.jar" 
fork="true" 
spawn="true" >
<arg line="-firefoxProfileTemplate /home/ehdez/firefox-selenium-profile/"/> </java>
</target>



4. - Especifciar ruta  para la descarga de ficheros en Firefox

Nuestra aplicación web puede generar ficheros para descargar,  Firefox nuevamente nos vuelve a preguntar qué queremos hacer con ese fichero:


  Nuevamente, si estamos realizando test con Selenium no nos interesa que nos esté preguntando dónde guardar esos ficheros, así que configuraremos el perfil para que los guarde automáticamente en un determinado directorio. Por ejemplo en /tmp



Editamos el fichero prefs.js que se encuentra en el directorio del perfil (/home/ehdez/firefox-selenium-profile) y añadimos las siguientes líneas

user_pref("browser.download.dir", "/tmp");
user_pref("browser.download.downloadDir", "/tmp");
user_pref("browser.download.folderList", 2); // this can probably be 0,1, or 2
user_pref("browser.download.manager.showWhenStarting", false);

domingo, 29 de agosto de 2010

Tomcat y HTTPS

RESUMEN:

Vamos a configurar Tomcat para  poder acceder  a nuestras aplicaciones a través https.


Necesitaremos un certificado que vamos a crear usando la herramienta keytool. Una vez lo hayamos creado, configuraremos Tomcat para que lo tenga en cuenta.

Posteriormente vamos a configurar el Tomcat para que confíe en otros certificados; en este caso para que confíe en ese mismo certificado


1. - Creamos un certificado propio y configuramos Tomcat para que use el certificado

Usando la herramienta keytool generamos una clave RSA que llamaremos tomcat y la almacenamos en  el fichero /certificados/tomcat.keystore. El password para el almacén de claves será "miPassword"

$ keytool -genkey -alias tomcat -keypass miPassword -keyalg RSA -keystore /certificados/tomcat.keystore

Escriba la contraseña del almacén de claves:  // miPassword
Volver a escribir la contraseña nueva:        // miPassword
¿Cuáles son su nombre y su apellido?
    [Unknown]:
¿Cuál es el nombre de su unidad de organización?
    [Unknown]:
¿Cuál es el nombre de su organización?
    [Unknown]:
¿Cuál es el nombre de su ciudad o localidad?
    [Unknown]:
¿Cuál es el nombre de su estado o provincia?
    [Unknown]:
¿Cuál es el código de país de dos letras de la unidad?
    [Unknown]:
¿Es correcto CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown?
    [no]:  si


2. - Configuramos Tomcat para que use el certificado
Modificamos el fichero server.xml que está en $CATALINA_HOME/conf


< Connector
   protocol="org.apache.coyote.http11.Http11Protocol"
   SSLEnabled="true" 
   clientAuth="false"
   keystoreFile="/certificados/tomcat.keystore" 
   keystorePass="miPassword"
   maxThreads="150" 
   port="8443"
   scheme="https" 
   secure="true" 
   sslProtocol="TLS"  
   URIEncoding="UTF-8"
/>


3. - Generamos el fichero que almacenará los certificados en los que Tomcat debe confiar

Ahora vamos a especificar a Tomcat que confíe en ese mismo certificado. Para ello, primero necesitamos exportar el certificado tomcat almacenado en /certificados/tomcat.keystore al fichero  /certificados/server.crt

$ keytool -export -alias tomcat -keypass password -file /certificados/server.crt  -keystore /certificados/tomcat.keystore

Escriba la contraseña del almacén de claves:  // miPassword
Certificado almacenado en el archivo </certificados/server.crt>



Los certificados en los que confiará Tomcat se almacenarán en el fichero /certificados/cacerts. Por tanto iremos importando en este fichero  los diferentes certificados en los que queremos confiar.


$ keytool -import -file /certificados/server.crt -keypass password -keystore /certificados/cacerts


Escriba la contraseña del almacén de claves:  // miPassword
Volver a escribir la contraseña nueva:  //miPassword
Propietario: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Emisor: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Número de serie: 4c7a36e0
Válido desde: Sun Aug 29 11:30:56 WEST 2010 hasta: Sat Nov 27 10:30:56 WET 2010
Huellas digitales del certificado:
   MD5:  DB:E7:4F:42:89:39:58:31:F7:25:20:67:F8:60:54:D6
   SHA1: 85:83:94:D1:42:D6:4D:D9:FA:9A:D5:35:28:C5:A4:23:45:CE:CB:AC
   Nombre del algoritmo de firma: SHA1withRSA
   Versión: 3
¿Confiar en este certificado? [no]:  si
Se ha añadido el certificado al almacén de claves


4. - Configuramos Tomcat para que confíe en otros certificados


Modificamos el fichero server.xml para especificarle el fichero de certificados en los que queremos confiar:


< Connector
   protocol="org.apache.coyote.http11.Http11Protocol"
   SSLEnabled="true"
   clientAuth="false"
   keystoreFile="/certificados/tomcat.keystore"
   keystorePass="miPassword"
   truststoreFile="/certificados/cacerts"                                            
   maxThreads="150"
   port="8443"
   scheme="https"
   secure="true"
   sslProtocol="TLS"
   URIEncoding="UTF-8"
/>

Presentación

Blogs hay muchos ... este simplemente es otro más en donde intentaré plasmar parte del conocimiento adquirido "cuando trasteo" con las diferentes tecnologías  que me voy encontrando.