Cliente .Net para WebServices Java/Axis2/WS-Security sobre HTTPS

dotnet_2010

Se me solicito realizar un implementación de WebServices para publicar los servicios de la Empresa para la cual estoy dando servicios.

Una vez terminado dicho proyecto, se procedió a realizar las pruebas necesarias de la implementación, para esto ser utilizo la herramienta SoapUI, sin encontrar inconvenientes en el consumo de estos (https + ws-security).

Bueno, todo estaba bien, hasta que se intento realizar un demo con .Net (VS2010).

Dejo una URL donde aparece una forma bastante “didáctica” de como consumir un WebService:
http://www.elguille.info/colabora/NET2005/sergio_CallWebService.htm

Una vez realizado dicha tarea, nos agrega la siguiente configuración al archivo app.config:
25-04-2012 03-29-57 p-m-

Seleccionamos el EndPoint que vamos a utilizar, en nuestro ejemplo:
25-04-2012 03-33-42 p-m-

El código utilizado para la llamada al WebService es el siguiente:
25-04-2012 03-38-51 p-m-

Cuando ejecutamos el programa ejemplo, nos encontramos con el primer problema grave, que es el reclamo que el certificado es “falso”:
25-04-2012 04-34-52 p-m-

El sistema de seguridad del framework .Net es bastante exigente en ese punto. Para poder continuar con nuestras pruebas, vamos a “enganchar” una función que realice esta funcionalidad y no el framework:

ServicePointManager.ServerCertificateValidationCallback =
                new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);

Donde la función es la siguiente:

public static bool IgnoreCertificateErrorHandler(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
        {
            System.Console.WriteLine("Warning, trust any certificate");

            return true;
        }
Solo retornamos “true” para todas las validaciones y con esto podemos continuar con la invocación del WebService:
25-04-2012 05-15-16 p-m-
 

Ahora si ejecutamos el programa, nos genera una excepción porque no cumplimos con los criterios de seguridad puestas en el WebService (WS-Security):

25-04-2012 05-16-41 p-m-

Para esto abrimos el archivo “app.config” de nuestro proyecto y le indicamos el nivel de seguridad necesario:

25-04-2012 05-22-00 p-m-

Lo cambiamos por:

25-04-2012 05-22-51 p-m-

Una vez hecho esto, ejecutamos nuestro programa obteniendo la siguiente respuesta:

25-04-2012 05-24-50 p-m-

Esto significa que el WebService nos esta exigiendo las credenciales necesarias impuesta en la configuración del WS-Security, para nuestro caso UserToken:

serviceProxy.ClientCredentials.UserName.UserName = "comercio1";
serviceProxy.ClientCredentials.UserName.Password = "comercio1";

Quedando nuestro programa de la siguiente forma:25-04-2012 05-55-07 p-m-

Ahora con esto, nuestra aplicación no debiese tener ningún inconveniente para poder consumir el WebService. Ejecutamos:

25-04-2012 06-03-55 p-m-

Otro error más!!! Si analizamos el mensaje:

El procesador de seguridad no encontró un encabezado de seguridad en el mensaje. La causa puede ser que el mensaje sea un error no protegido o que no coincidan los enlaces entre las partes de la comunicación. Esto puede suceder si el servicio esta configurado para seguridad y el cliente no usa seguridad.

Bueno!, ahora nos encontramos con este problema, lo cual analizando nuestro WebService, este si respondió al requerimiento, es decir, por el lado del servidor, todo esta funcionando correctamente; el mensaje fue recibido, fue procesado, y se obtuvo una respuesta exitosa al requerimiento. Pero algo no le gusto al “Procesador de Seguridad” de .Net que nos “atrapa” la respuesta.
 
Después de mucho buscar y analizar el problema, se encontró con una solución bastante atípica. La cual consiste en eliminar del mensaje la cabecera SOAP del requerimiento la fecha y hora (TimeStamp), para que de esta forma en la respuesta no viaja la cabecera SOAP, y evita que el “Procesador de Seguridad” haga la fallida comparación.
 
BindingElementCollection elements = serviceProxy.Endpoint.Binding.CreateBindingElements();
                elements.Find<SecurityBindingElement>().IncludeTimestamp = false;
                serviceProxy.Endpoint.Binding = new CustomBinding(elements);
Quedando nuestro código de la siguiente forma:

25-04-2012 06-32-21 p-m-
 
Ahora ejecutamos nuestro programa:

25-04-2012 06-49-39 p-m-
 
Y Funciona!. Espero que sea de ayuda….
 
Caluroso Marco!

 

Etiquetas de Technorati: ,,,,,,

Agregando propiedades a nuestro JPos-Q2Server

jpos.org

jpos.org

Hay situaciones donde tenemos que agregarle información desde el archivo de configuración del JPos Q2Server. Utilizando nuestro proyecto anterior, le vamos agregar a la configuración, información de acceso a una base de datos donde vamos a almacenar la data que se procesa. Solo voy a incluir el código para acceder a dicha información, en algún pos futuro veremos como insertar efectivamente la transacción.

Tenemos nuestro actual archivo de configuración para el Q2Server:

Archivo configuración QServer

Archivo configuración QServer

Le agregamos las siguientes lineas, a nuestro archivo de configuración (lo que esta en rojo, ya esta en el archivo, solo se indican para ubicar correctamente la información):

<request-listener class="cl.gomark.listener.RequestListener" logger="Q2">
<property name="db.driver" value="org.postgresql.Driver" />
<property name="db.url" value="jdbc:postgresql://localhost/gomark_24082010" />
<property name="db.user" value="postgres" />
<property name="db.password" value="****" />
</request-listener>

Con esto nos queda el siguiente archivo de configuración (en mi caso de nombre 90-gomark-server.xml):

Configuración Q2Server

Configuración Q2Server

Una vez con nuestro archivo de configuración ya listo, modificamos nuestra clase (le agregamos la implementación ReConfigurable):

public class RequestListener extends Log implements ISORequestListener,
ReConfigurable, LogSource {

Luego agregamos el siguiente metodo a nuestra clase “RequestListener”:

@Override

public void setConfiguration(Configuration configuration) {

	_config = configuration;

	LogEvent logEvt = new LogEvent(this, "RequestListener:setConfiguration");

	logEvt.addMessage("db.driver = " + _config.get("db.driver"));

	logEvt.addMessage("db.url = " + _config.get("db.url"));

	logEvt.addMessage("db.user = " + _config.get("db.user"));

	logEvt.addMessage("db.password = " + _config.get("db.password"));		

	Logger.log(logEvt);

}

Donde _config es una propieda de la clase de tipo privada, la cual contiene toda la configuración agregada al archivo, para extraer un respectivo dato:

String miValor = _config.get(“db.url”);

Si todo sale bien, cuando iniciemos nuestro servicio JPos Q2Server, deviese verse de la siguiente forma:

Bueno, esto seria por esta vez. Cualquier comentario, es bienvenido!

Saludos!

Intalación JPOS en Ubuntu 10.4

Para poder instalar JPOS, se requieren tener instalada las siguientes herramientas:

  1. Java JDK (mini Howto para instalar jdk en ubuntu 10.4 http://www.ubuntu-es.org/node/133779)
  2. Subversion (instalar subversion: sudo aptitude install subversion)
  3. ANT (instalar ant: sudo apt-get install ant ant-optional)

Una vez instalada las herramientas, iniciamos la descarga desde el repositorio de la rama en desarrollo de JPOS (existe una versión estable para descarga en http://www.jpos.org)

svn co https://jpos.svn.sourceforge.net/svnroot/jpos/trunk/jpos6/ jpos-1.6.9

donde jpos-1.6.9 es el nombre del directorio donde lo vamos a alojar (el nombre puede ser cualquiera)

Una vez finalizado el proceso de descarga, procedemos a compilar vía ant (todo esto dentro del directorio donde alojamos el proyecto jpos)

moo@rcx01:~/jpos-1.6.9$ ant
Buildfile: build.xml
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.52.17
[mkdir] Created dir: /home/moo/jpos-1.6.9/build
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/src
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/lib
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/lib/test
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/bin
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/doc
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/cfg
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/modules
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/deploy
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/deploy/lib
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/webapps/root
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/classes
[mkdir] Created dir: /home/moo/jpos-1.6.9/dist
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/log
copy-lib:
[copy] Copying 7 files to /home/moo/jpos-1.6.9/build/lib
modules:
[copy] Copying 620 files to /home/moo/jpos-1.6.9/build/modules
[copy] Copying 2 files to /home/moo/jpos-1.6.9/build/deploy
[copy] Copying 2 files to /home/moo/jpos-1.6.9/build/lib
[copy] Copying 592 files to /home/moo/jpos-1.6.9/build
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.52.17
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
[subant] No sub-builds to iterate on
[subant] No sub-builds to iterate on
copy-bin:
[copy] Copying 3 files to /home/moo/jpos-1.6.9/build/bin
manifest:
main:
[javac] Compiling 465 source files to /home/moo/jpos-1.6.9/build/classes
[javac] Note: Some input files use or override a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[rmic] RMI Compiling 2 classes to /home/moo/jpos-1.6.9/build/classes
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
jar:
[jar] Building jar: /home/moo/jpos-1.6.9/build/jpos.jar
compile:
BUILD SUCCESSFUL
Total time: 12 seconds
moo@rcx01:~/jpos-1.6.9$
Para ejecutar nuestro Jpos, procedemos:
moo@rcx01:~/jpos-1.6.9$ ant run
Buildfile: build.xml
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.56.47
copy-lib:
modules:
[copy] Copying 2 files to /home/moo/jpos-1.6.9/build/modules
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.56.47
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
[subant] No sub-builds to iterate on
[subant] No sub-builds to iterate on
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
copy-bin:
manifest:
main:
jar:
[jar] Building jar: /home/moo/jpos-1.6.9/build/jpos.jar
run:
[java] <log realm=”Q2.system” at=”Thu Aug 19 15:56:51 CLT 2010.282″>
[java]   <info>
[java]     Q2 started, deployDir=/home/moo/jpos-1.6.9/build/deploy
[java]   </info>
[java] </log>
[java] <log realm=”Q2.system” at=”Thu Aug 19 15:56:51 CLT 2010.340″>
[java]   <info>
[java]     new classloader [22c95b] has been created
[java]   </info>
[java] </log>
[java] <log realm=”Q2.system” at=”Thu Aug 19 15:56:51 CLT 2010.342″>
[java]   <info>
[java]     deploy:/home/moo/jpos-1.6.9/build/deploy/99_sysmon.xml
[java]   </info>
[java] </log>
[java] <log realm=”org.jpos.q2.qbean.SystemMonitor” at=”Thu Aug 19 15:56:51 CLT 2010.357″>
[java]   <info>
[java]     Starting SystemMonitor
[java]   </info>
[java] </log>
[java] <log realm=”org.jpos.q2.qbean.SystemMonitor” at=”Thu Aug 19 15:56:51 CLT 2010.361″>
[java]   <info>
[java]     <release>jPOS 1.6.9 r2962</release>
[java]     <instance>c669c33b-d2c1-43c8-a1ef-83dc517c4018</instance>
[java]     <uptime>00:00:00.409</uptime>
[java]     <memory>
[java]        freeMemory=7206848
[java]       totalMemory=7995392
[java]       inUseMemory=788544
[java]     </memory>
[java]     <threads>
[java]             delay=0 ms
[java]           threads=4
[java]             Thread[Reference Handler,10,system]
[java]             Thread[Finalizer,8,system]
[java]             Thread[Signal Dispatcher,9,system]
[java]             Thread[Q2-c669c33b-d2c1-43c8-a1ef-83dc517c4018,5,main]
[java]             Thread[DestroyJavaVM,5,main]
[java]             Thread[Timer-0,5,main]
[java]             Thread[SystemMonitor,5,main]
[java]     </threads>
[java]     — name-registrar —
[java]       logger.Q2: org.jpos.util.Logger
[java]       logger.Q2.buffered: org.jpos.util.BufferedLogListener
[java]   </info>
[java] </log>
Ahí una forma muy básica de instalar jpos en un ubuntu (para windows es bastante similar)