viernes, 24 de julio de 2015

WSO2 ESB v4.9.0: Un cambio a tener en cuenta.

image 

Revisando una beta snapshot del WSO2 ESB v4.9.0 me he dado cuenta de que desde la consola web ha sido eliminada la funcionalidad de agregarle seguridad a un servicio proxy. Algo que podía realizarse dando par de clic ahora ya no se puede.


image

En su lista de desarrollo aparece el correo siguiente:
=======================================================================
Hi ESB team,
Since Applying QOS is moved completely to developer studio from ESB 4.9.0 release (no UI support in ESB), do we have a way to migrate services that has QOS applied (secured proxy services etc..)?
We can't just copy those artifacts to ESB 4.9.0. I tried but it's not supported (Issue reported at [1]). Is there some workaround or are we going to fix it?
[1] https://wso2.org/jira/browse/ESBJAVA-3909
=======================================================================
Y luego la respuesta que le dan:
=======================================================================
I've used following way to enable security to the proxy service from Dev Studio project. I think this will help you.
1. Create the policy
  1. Create a proxy service from ESB management console. (lets say passthroughProxy)
  2. Apply security (Username token) from management console
  3. Go to the source view of passthroughProxy and you may see something like follows is added to that.
  <parameter name="ScenarioID">scenario1</parameter>
   <enableSec/>
   <policy key="conf:/repository/axis2/service-groups/passthrough/services/passthrough/policies/UTOverTransport"/>
2. Browse the registry from management console to locate the /repository/axis2/service-groups/passthrough/services/passthrough/policies/ and download the UTOverTransport file and rename it as UTOverTransport.xml
3. Create a registry resource from policy
  1. Create a registry resource project from devstudio
  2. Create a registry resource and choose “import from file system” in the wizard and point to the UTOverTransport.xml which we have downloaded in 4.
4. Apply security to your proxy service.
  1. Create a ESB project and proxy service if you don’t have already.
  2. Go to the proxy service properties as in[1] and configure securtyEnable=true and policyKey. When setting policy key you have to point to the registry resource we created in 2.2
  3. Additionally add the following parameter in ServiceParameters section.
property name=allowRoles value= admin
5. Once you configured you will see the source of your proxy config as follows
        <proxy xmlns="http://ws.apache.org/ns/synapse" name="LoopBackProxy" transports="http https" startOnLoad="true" trace="disable">
    <target>
        <inSequence>
            <log level="full"/>
            <respond/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </target>
    <policy key="conf:custom/UTOverTransport.xml"/>
    <parameter name="allowRoles">admin</parameter>
    <enableSec/>
</proxy>
6. Deploy
  1. Create a composite application project
  2. Tick (check) your proxy from ESB project and UTOverTransport from Registry project to include them to the project. When adding use server role as EnterpriseServiceBus for both proxy and policy since we are going to deploy both in ESB
  3. Right click on created composite project and select “Export as Deployable archive”
=======================================================================

Que opinan de este cambio?

miércoles, 22 de julio de 2015

WSO2 ESB: Seguridad UT.

image

En las entradas anteriores hemos visto como se le ha aplicado la seguridad a un servicio desplegado en el WSO2 AS y como se han desarrollado clientes en axis2, cxf y metro para consumirlo.

En esta entrada quisiera realizar una actualización de este escenario un poco más cercana a la realidad y me explico:

En algunas empresas los sistemas BE están bien protegidos en las redes empresariales por lo que no se requiere que se le asigne protección a cada recurso en particular. Esto se traduce en que los servicios desplegados en un WSO2 AS podrían están en una red privada por lo cual tendrían cero seguridad.

En un escenario como este existirían clientes implementados en la lógica de las aplicaciones que consumirían de estos servicios inseguros y hasta ahí no existe problema, pero….. qué pasa cuando se desea exponer la funcionalidad de determinados servicios inseguros a un ambiente también inseguro y se requiere proteger el acceso.

Es en estas situaciones donde un ESB excelente, ligero y libre de costo como el de WSO2 puede entrar en acción.

La solución pasa por:
  1. Implementar un proxy que haga un Pass Through del servicio desplegado en el AS e incorporarle un nivel de seguridad, dígamos que el UserNameToken. Este sería el proxy expuesto al exterior inseguro.
  2. Implementar un proxy que haga un Pass Through del servicio desplegado en el AS que no tenga seguridad, pero que pueda filtrarse su uso mediante las facilidades que brinda el ESB, ej: filtrado por IP. De esta manera los clientes sin seguridad podrían seguir usando el servicio sin aplicar cambios con excepción del endpoint, pero el uso del servicio podría ser monitorizado a través del ESB.
  3. Implementar un cliente, algo que ya vimos en las entradas anteriores, que consuma del servicio del punto 1, que tiene seguridad.
En esta entrada nos enfocaremos en el punto 1 y en el ajuste al cliente en el punto 3.
Para el escenario hemos iniciado las siguientes herramientas:
  • WSO2 AS 5.2.1 con el offset en 2.
  • WSO2 ESB 4.8.1 con el offset en 1.

Paso 1: Creación del proxy
Se ha creado un proxy con la siguiente configuración, tener en cuenta que ya aquí tiene añadida la seguridad:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="HolamundoPS"
       transports="https"
       startOnLoad="true"
       trace="disable">
   <description/>
   <target faultSequence="fault">
      <endpoint>
         <address uri="http://localhost:9765/services/HolamundoWSDL">
            <timeout>
               <duration>200</duration>
               <responseAction>fault</responseAction>
            </timeout>
         </address>
      </endpoint>
      <inSequence>
         <log level="full"/>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <publishWSDL key="gov:/wsdl/HolamundoWSDL.wsdl"/>
   <policy key="conf:/repository/axis2/service-groups/HolamundoPS/services/HolamundoPS/policies/UTOverTransport"/>
   <parameter name="ScenarioID">scenario1</parameter>
   <enableSec/>
</proxy>


Se puede apreciar que el proxy es realmente sencillo, tiene definido el endpoint del servicio en el WSO2 AS, a donde debe dirigir los mensajes, con un timeout de 200 milisegundos. La secuencia de entrada solo hace un log del mensaje en consola y la secuencia de salida manda el mensaje al cliente.


El WSDL usado es el del servicio en el WSO2 AS, almacenado en el registro del ESB y se le aplicó la política UserNameToken.


Paso 2: Ajuste al cliente.


En el caso del cliente lo hemos modificado para usar el WSDL expuesto por el ESB, algo que no era necesario realizar, pues un simple cambio de endpoint bastaba pero quisimos hacerlo para mostrar lo fácil que se hace generar un cliente.


El código queda como sigue:


package com.chakray.samples.jaxws.jaxwsSecureClient;

import javax.xml.ws.BindingProvider;

import org.blogs.ejemplos.serviciosaxis2.HolamundoPS;
import org.blogs.ejemplos.serviciosaxis2.HolamundoPSPortType;
import org.blogs.ejemplos.serviciosaxis2.Persona;
import org.blogs.ejemplos.serviciosaxis2.PersonaRespuesta;

@SuppressWarnings("restriction")
public class SecureClienteJAXWS {

 static String ENDPOINT_ESB = "https://localhost:8244/services/HolamundoPS";

 public static void main(String[] args) {

  String trustStore = null;
  trustStore = "wso2carbon.jks";
  System.setProperty("javax.net.ssl.trustStore", trustStore);
  System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");

  HolamundoPS service = new HolamundoPS();
  HolamundoPSPortType port = service.getHolamundoPSHttpsSoap12Endpoint();
  BindingProvider bp = (BindingProvider) port;
  bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
    ENDPOINT_ESB);

  Persona persona = new Persona();
  persona.setNombre("Jorge");
  persona.setApellidos("Infante Osorio");

  PersonaRespuesta response;
  try {
   response = port.holaati(persona);
   System.out.println(response.getSaludo().toString());
  } catch (Exception e) {
   System.out.println("ERROR STARTUP: " + e.getMessage());
  }
 }
}


 A continuación les mostramos los mensajes intercambiados entre el cliente y el proxy y entre el proxy y el BE. Tengan en cuenta que en el código de arriba se ajustaron ya los puestos a los reales.


Usando el SOAPUI que viene con el WSO2 Developer Studio hemos configurado un proyecto para que capture los mensajes intercambiados entre el cliente y el servicio proxy, y se visualiza el header de seguridad con un timestamp y un token username incluidos.




También hemos capturado los mensajes intercambiados entre el WSO2 ESB y el WSO2 AS para que vean como se ha eliminado la seguridad. Para este caso se usó el TCPMon.



Y así de una manera muy fácil con practicamente cero codificación hemos actualizado un escenario que se presenta frecuentemente en muchas empresas cuando comienzan a exponer sus servicios al exterior.


Esperamos les sea de utilidad.

viernes, 17 de julio de 2015

Cliente JAX-WS con Metro para consumir servicios con seguridad UT.



En entradas anteriores hemos visto como implementar un cliente para un servicio web expuesto con seguridad UserNameToken en el WSO2 AS.

En especifico vimos como implementarlo con Axis2 y con CXF.

En esta entrada veremos como implementarlo usando la implementación de Metro a solicitud de Cesar desde el grupo de Linkedin "WSO2 en Español".

Les dejo el fuente aquí, pues ya las explicaciones han sido dadas en las entradas anteriores. Pueden probarlo desde la consola con el siguiente comando maven: mvn exec:exec

Espero les sea de utilidad.

jueves, 16 de julio de 2015

Cliente JAX-WS con CXF para consumir servicios con seguridad UT.


En la entrada anterior se compartió el código para generar un servicio Axis2 el cual debía ser desplegado en el AS y expuesto con seguridad UserNameToken y también el código para un cliente Axis2.

En esta entrada usaremos el mismo servicio conla misma seguridad pero el cliente será implementado usando JAX-WS con CXF.

Veamos primero las partes más interesantes del código.

La conexión HTTP se define de la misma manera:

image

Luego se crea un objeto service y a partir de este se optiene un puerto, concepto similar al del stub en Axis2.

image

Ambas clases son generadas una vez ejecutado el comando maven: mvn clean compile
Por último accedemos a las propiedades del puerto recién creado y especificamos un nuevo endpoint. En este caso en particular no es necesario pues el WSDL usando tiene bien definido el endpoint, pero en aquellos caso en que el endpoint del WSDL no sea el correcto si debe realizarse este ajuste.


image


Luego de este fragmento de código el consumo del servicio es similar a si no tuviera seguridad asociada.

Llegado a este punto no vemos por ningún lado ni la política de seguridad ni el user/pass ni nada que indique que estaremos usando UserNameToken y es que esta parte se realiza a nivel de configuración de algunos ficheros. Veamos cuales.
Primero para que se generen correctamente las clases a partir del WSDL se usa este fichero jaxb-bindings.xml

image

De no incluir el generateElementProperty=”false” veríamos como los atributos String tendrían un tipo JAXB asociado.

El otro fichero importante es cxf.xml que cuando está presente es cargado por el framework automáticamente, siempre que incluyamos la dependencia a “spring-context” en nuestro pom.xml

image

Aquí se definen 2 beans, el último apunta a una clase que se encarga de darnos la contraseña a utilizar dado un usuario en particular, mientras que el primer bean nos permite definir el usuario y la clase a utilizar para cargar la contraseña.

Llegados a este punto ya se aprecia como se determina la generación de las clases y como se setea el usuario y la contraseña, pero viene faltando la política y es que la política viene incluída en el WSDL usado para generar las clases y se referencia a nivel de binding como pueden ver en la línea marcada de azul.

image 

Con estos elementos en su lugar pueden darle al proyecto un mvn clean compile y se generarán las clases necesarias en target/generated-sources/cxf las cuales son necesarias para que el código implementado funcione. Un ejemplo de la salida por consola de este código es el siguiente:


image


Sin más les dejo el enlace al repo en github para el proyecto maven.

Espero les sea de utilidad.

miércoles, 15 de julio de 2015

WSO2 y la seguridad UserNameToken.Recapitulando.

image006-713660

En una entrada de hace poco más de un año había mostrado cómo trabajar con la seguridad a nivel de UserNameToken, usando el WSO2 Application Server e implementado el cliente con Axis2. En ese momento no compartí el código y es generó varias preguntas enviadas a mi buzón de correo y por el propio post.

Ahora volviendo al mismo tema y apoyándome en una excelente entrada de Roger Carhuatocto veremos un poco más en detalle el código empleado.

Al revisar el código una de las primeras cosas que podemos notar son las líneas encargadas de establecer una conexión HTTPS usando un almacén de llaves del tipo JKS. En este caso en particular usamos el mismo del WSO2 AS que tiene como contraseña wso2carbon.

image

Otro segmento de código importante es el que usamos para acceder a las opciones del stub para poder engancharle el módulo de rampart, encargado de la seguridad en axis2. También con el stub podemos, usando las opciones, setear el usuario y la contraseña y por último cargar en una propiedad la política de seguridad que tenemos almacenada en un fichero con formato XML.

image

A partir de este segmento de código la implementación es la misma que si el servicio fuera inseguro. Y ahora apoyandonos en el post de Roger explicaremos el por qué de estos ajustes.

Roger nos comentaba en su entrada que en la política de seguridad definida por defecto para el escenario UserNameToken se especifica que:
  1. Se requiere HTTPS en vez de HTTP. Este último ya no está disponible cuando le asignamos la seguridad al servicio.Esto implica que el canal de seguridad está encriptado razón por la cual debemos especificar el almacén de certificados para la conexión SSL.
  2. Se debe enviar las credenciales de autenticación del usuario, usuario y contraseña, en el mensaje que viaja por el canal encriptado. De ahí que debamos especificar en las opciones del stub el usuario y la contraseña.
  3. El UserNameToken debe ir firmado, para evitar que se alteren los datos de autenticación.

Y para lograr especificar todo esto es que se crea una política de seguridad que es cargada como una propiedad más en el stub.

Sin más les dejo el enlace a los  repositorios en github donde he puesto el código de:
  • Proyecto que genera el aar del servicio a desplegar en el WSO2 AS.
  • Proyecto que contiene la implementación del cliente seguro que consume el servicio del punto anterior, una vez asegurado con UserNameToken.

Para generar el aar deben ejecutar el comando: mvn clean package en el primer proyecto.
En el caso del segundo proyecto basta con el comando: mvn clean compile para que compilen las dos clases, el stub, y el cliente y puedan ejecutar el main de ejemplo.
Quedamos al tanto de cualquier situación que se les presente y espero que puedan consumir servicios seguros sin problema.

jueves, 9 de julio de 2015

Historia de WSO2 IS y de sus desarrolladores.



Les dejo este enlace del blog de Prabath Siriwardena donde se cuenta la historia detrás del desarrollo de WSO2 Identity Server y su evolución desde el lejano 2007. Una herramienta indispensable cuando se habla de seguridad en soluciones SOA.

Resulta muy interesante ver como ha evolucionado la herramienta y su equipo de desarrollo y como se va afianzando en escenarios de seguridad cada día más complicados y siempre sale airosa.

Espero les resulte interesante.

lunes, 6 de julio de 2015

Aquí les dejo un enlace de una nueva entrada que acabo de publicar en la que se demuestra como hacer transformaciones a la respuesta del consumo del API REST del Redmine haciendo uso del mediador Script del WSO2 ESB.

Espero les sea útil.

miércoles, 1 de julio de 2015

WSO2 AS: Exponiendo fuentes de datos como recursos JNDI.

Como todos los desarrolladores JAVA conocen, JNDI o Java Naming and Directory Interface, es un API de Java que provee de funcionalidades para el descubrimiento de datos y objetos por su nombre. El WSO2 Application Server soporta JNDI a partir de extender la implementación brindada por Tomcat.
En esta entrada queremos mostrarles cómo hacer uso de esta API para exponer las fuentes de datos que hemos creado para nuestros servicios con el objetivo de que también sean accesibles desde las aplicaciones que despleguemos. Veamos cómo se hace.


Paso 1: Crear una fuente de datos.
En este caso usaremos una que ya se ha creado para un servicio de acceso a datos a una BD Oracle.

image

Como se puede apreciar se le ha hecho un test a la configuración para confirmar que se ha realizado de manera correcta.



Paso 2: Exponer esta fuente de datos como un recurso JNDI.
Este segundo paso es realmente sencillo, tal como se muestra en la siguiente imagen.
image

Definimos un nombre para nuestra configuración JNDI y listo. Si se desea que sea consumida desde el exterior debemos marcar la opción “Use Data Source Factory” tal y como se explica en la documentación de la herramienta. Ahora solo basta con salvar la configuración y vamos al paso 3.


Paso 3: Crearemos un servicio JAX-WS con CXF.
Abrimos el WSO2 Developer Studio y nos vamos a su Dashboard, donde seleccionamos la opción “Jax-WS Service Project”.

image


En la ventana que nos sale marcamos la opción de crear un servicio nuevo.

image


Y procedemos a llenar los datos del proyecto.

image


Añadimos la info solicitada para maven.

image  
Y damos Finish.

Por defecto se nos crea una clase con una implementación dummy la cual debemos modificar para ajustar a nuestros requerimientos.

image


Paso 4: Ajuste de la implementación del método.
En este caso creamos un método para obtener dado el nombre de un cliente sus datos. Veamos la siguiente imagen.

image

Como pueden apreciar, tenemos un método “obtenerCliente” al cual se le pasa el nombre como un String y devuelve un objeto de tipo Cliente.

Esta clase tiene un método getDataSource que devuelve un objeto de tipo DataSource que es usado para obtener la conexión a BD y que veremos su implementación en breve.
Luego se prepara la consulta, se ejecuta y se llena el objeto cliente con el resultado de la consulta.
El método para obtener la conexión se muestra a continuación.

image

Este método es sacado de la documentación de WSO2 Application Server, podemos ver como en la última línea especificamos el nombre del recurso JNDI creado en la fuente de datos al inicio de la entrada.

Paso 5: Despliegue en el servidor.
Como lo que hemos implementado es un servicio jax-ws pues debemos desplegarlo en el WSO2 AS, para ello damos clic derecho en el proyecto y seleccionamos la opción “Export Project As Deployable Archive”.
Aquí bien podemos guardar el archivo en alguna ubicación en nuestro filesystem para luego cargarlo desde la consola web del WSO2 AS o podemos copiarlo directamente en [AS_HOME]\repository\deployment\server\webapps tal y como se muestra en la siguiente imagen.

image

Una vez desplegado el servicio lo podemos buscar en la consola web en
“Home>Manage>Applications>List>Applications”

Y entrando a su Dashboard veremos lo siguiente:
image


Paso 6: Pruebas.
Para probar creamos un proyecto en el SOAPUI usando el WSDL 1.1 y le pasamos como nombre “Jorge” y podremos ver la respuesta del servicio.
image

Para aquellos interesados en el fuente, lo pueden descargar desde esta ubicación, clonando el repositorio.
Acá les dejo el enlace a un nuevo post que acabo de publicar en mi blog que puntualmente los temas que toca son:
  • Compilar y empaquetar el redmine-connector
  • Desplegar y activar un conector en el WSO2 ESB
  • Como importar un conector para el Developer Studio
  • Como implementar un Servicio Proxy en este caso usando el redmine-connector haciendo uso del DS
  • Como construir y desplegar un Composite Application Project desde el DS en el WSO2 ESB
  • Como realizar un test de un servicio Rest en nuestro caso haciendo uso del plugins RestClient del Mozilla Firefox y desde el SoapUI
Nos les adelanto nada más solo sigan este enlace:  http://wp.me/p5DCiP-10

Saludos