Mostrando entradas con la etiqueta UserName Token. Mostrar todas las entradas
Mostrando entradas con la etiqueta UserName Token. Mostrar todas las entradas

jueves, 5 de enero de 2017

Axis2: Seguridad en WSO2 AS 5.3.0

image

Ayer revisando StackOverflow me he topado con una pregunta sobre como establecer la seguridad para un servicio axis2 desplegado en el WSO2 AS 5.3.0 y la verdad es que desconocía que esta funcionalidad, muy buena por cierto, había sido removida de la interfaz web.
Realmente no me ha gustado que se removiera, pues de una manera muy fácil permitía a los desarrolladores definir la seguridad para los servicios axis2, pero son cosas de la compañía WSO2 que habría que revisar los pro y los contras.

La respuesta a la pregunta está en el enlace que puse más arriba pero lleva un trabajo adicional a lo que se hacía antes a través de la UI. Se necesita:
  • Identificar el XML que define la política que queremos usar. En mi respuesta usé la más sencilla, UsernameToken over HTTPs.
  • Incluir en el fichero services.xml del servicio axis2, que está dentro del fichero .aar la referencia al módulo de rampart. Que es el que define la seguridad para el framework axis2.
  • Definir cómo se vinculará la política con las distintas operaciones del servicio y donde será adjuntada.
  • Definir algunas configuraciones propias de rampart dentro de la política para la encriptación y uso de los usuarios del WSO2 AS y también una configuración extra para el carbon definiendo los roles que tendrán permiso de acceso al servicio.
Una vez que se tiene un ejemplo resulta más fácil establecer la seguridad para cualquier servicio axis2 pero para aquellos que no dominan el framework puede llevarle horas o días dar con la configuración correcta. De ahí que me decidiera a compartir un ejemplo sencillo que les sirva a los que se enfrente a este pequeño problema.

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.

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.

viernes, 24 de mayo de 2013

Consumiendo un servicio seguro con UserNameToken desde JAVA usando WSO2.

En esta entrada implementaremos el siguiente escenario.


Si al servicio que implementamos, desplegamos y consumimos en las entradas anteriores quisiéramos consumirlo nuevamente pero de forma segura deberíamos de hacer algunos cambios en su diseño.

Esto no lo hicimos desde el inicio para dar pie a esta entrada :-D pero la idea es que de los bindings del servicio que ya tenemos que son el HTTP, SOAP11 y SOAP12 pues tengamos 2 puertos por cada uno de ellos. Uno seguro y el otro inseguro. Ya tenemos los inseguros así que debemos crear los seguros.


Vean que cuando se usa el estándar SOAP versión 1.2 se usa el namespace referenciado por soap12 y que al inicio del WSDL podrán encontrar xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"

Una vez hecha la modificación la imagen gráfica del WSDL visto con el eclipse tendría esta forma.



El código en la vista XML del WSDL de uno de estos puertos sería algo como esto:
    <wsdl:port name="HolamundoHttpsSoap12Endpoint"
                binding="ns:HolamundoSoap12Binding">
                <soap12:address location="https://www.example.org/" />
    </wsdl:port>



Lo importante es que el nombre del puerto lleva una s detrás del http para indicar que se usará un canal encriptado https. Y lo otro es que la dirección usa https en vez de http.

Si vuelven a revisar el WSDL que muestra el Application Server verán lo siguiente:

A partir de aquí deberíamos volver a redesplegar el servicio y probarlo a consumir de forma insegura como ya expliqué en otras entradas.
Una vez que comprueben que los cambios introducidos no han afectado el consumo inseguro pues implementaremos los siguientes pasos:

Paso 1:  iremos al dashboard del servicio y le asignaremos el menor nivel de seguridad. En el caso de la suite de wso2 es el uso del UserNameToken. O sea encriptar el canal de comunicación y usar HTTPS y enviar un token que contenga el usuario y la contraseña, ambos en texto plano, de quien desee consumir el servicio. Este usuario debe ser uno de los que están en alguno de los almacenes de usuario que tiene configurada la herramienta.

Paso 2:  usando la funcionalidad del “Try it” consumiremos el servicio seguro especificando el usuario/contraseña del admin del Application Server, que es el único usuario que tenemos hasta el momento en la herramienta.

Paso 3: implementaremos un cliente de este servicio en JAVA usando para ello el Developer Studio de WSO2.

Así que manos a la obra.

Para implementar el paso 1 nos vamos al dashboard de servicio que luce como sigue en la parte de “Quality of Service Configuration”:
Damos clic en Security y  se nos mostrará la interrogante de si habilitamos la seguridad, y seleccionamos Yes. Automáticamente se despliega el listado de posibles escenarios de seguridad. Solo les mostraré los básicos pero son 16.


Como ven marcamos el de UsernameToken y vamos al final de la página para darle al botón Next.

Luego de dar Next se nos pide especificar los grupos que tendrán permiso de acceso al servicio. Una autenticación básica para poder validar el usuario y la contraseña que se introduzcan.
Y por último damos Finish.
Y eso es todo, ya tenemos un servicio seguro sin tocar su implementación.

Cuando volvemos al Dashboard del servicio vemos que ahora solo el servicio está exponiendo un único endpoint, el seguro.
Ahora vamos a realizar el paso 2.
Le damos clic a “Try it” y veremos lo que nos sale.
En mi caso el firefox me dice que la conexión está cifrada pero no verificada, es que no confía en el certificado auto firmado que viene por defecto con la herramienta.

Luego de dar en que entendemos los riesgos y añadir la excepción vemos lo siguiente:

Como ven ya el Try it detectó la seguridad y nos da la opción de que podamos añadir el usuario y la contraseña. Introducimos admin y admin que son los valores por defecto y asignamos un nombre y un apellido y la respuesta no se hace esperar.



Ahora funciona, pero realmente funciona? Una manera de comprobarlo es ver los mensajes que se intercambian. Aquellos que sepan usar el TCPMon los invito a hacerlo pero al estar el canal encriptado poco podrán hacer a no ser que realicen una configuración y usando el par de llaves asimétricas del servidor puedan ver dentro del canal cifrado, pero a aquellos que quieran ver la estructura de los mensajes sin complicarse tanto los invito entonces a usar otra funcionalidad de la suite de WSO2 y de su framework CARBON y por lo tanto incluida en todas  las herramientas: el SOAP TRACER.

Para usarlo nos vamos a la pestaña Monitor del menú:

Y pinchamos en SOAP Tracer.
Se nos pregunta si queremos habilitar el soap tracer y le damos que YES. Veremos lo siguiente:

Ahora volvemos al  try it y consumimos de nuevo el servicio. Y cuando regresamos al soap tracer tendremos lo siguiente:

O sea el soap tracer ha capturado los mensajes, nos muestra la hora de consumo del servicio y los mensajes tanto de entrada como de salida. Es imposible mostrarlos completamente pero en el mensaje request vean como se ha añadido un encabezado “Security” y dentro del mismo un timestamp para evitar que el mensaje sea usado, reenviado, fuera de ese rango de tiempo como una medida de proteccion. También verán que hay un token Username que tiene el usuario y el password introducidos por el usuario. Cada uno de los mensajes pueden visualizarlo a pantalla completa si lo desean y ver su contenido adecuadamente.

Para finalizar esta entrada que ya se ha extendido vamos al paso 3. Consumiremos el servicio asegurado con usernametoken.

Los invito a probar el cliente creado en la otra entrada, les resultará imposible porque el endpoint que usábamos ya no existe. Si lo cambian por  el que existe ahora recibirán varios errores relacionados con el certificado que deberían tener y que no tienen. Aun.

Creamos un proyecto siguiendo los mismos pasos que vimos en la otra entrada para generar las clases del stub.
Luego de implementar el cliente y añadir las dependencias tal y como hicimos para el consumo del servicio inseguro nos sigue dando un error y está claro porque no hemos hecho nada con la seguridad.

Hasta  el momento mi implementación luce así:
package org.blogs.ejemplos.serviciosaxis2;

import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.blogs.ejemplos.serviciosaxis2.HolamundoWSDLStub.Holaati;
import org.blogs.ejemplos.serviciosaxis2.HolamundoWSDLStub.HolaatiResponse;
import org.blogs.ejemplos.serviciosaxis2.HolamundoWSDLStub.Persona;

public class Cliente {

                /**

                * @param args

                */
                public static void main(String[] args) {

                               try {
                                               HolamundoWSDLStub stub = new HolamundoWSDLStub();

                                               Holaati holaati = new Holaati();
                                               Persona param = new Persona();
                                               param.setNombre("nombre1");
                                               param.setApellidos("apellido1");
                                               holaati.setPersona(param);

                                               HolaatiResponse respuesta = stub.holaati(holaati);
                                               System.out.println("La respuesta es:   " 
              + respuesta.get_return().getSaludo());

                               } catch (AxisFault e) {
                                               e.printStackTrace();
                               } catch (RemoteException e) {
                                               e.printStackTrace();
                               }
                }
}




Luego de realizar los cambios necesarios en el código nos queda la siguiente implementación con los comentario de las cosas nuevas incluidos. Pruébenlo y me dicen.
import java.rmi.RemoteException;

import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyEngine;
import org.apache.rampart.RampartMessageData;
import org.blogs.ejemplos.serviciosaxis2.HolamundoWSDLStub.Holaati;
import org.blogs.ejemplos.serviciosaxis2.HolamundoWSDLStub.HolaatiResponse;
import org.blogs.ejemplos.serviciosaxis2.HolamundoWSDLStub.Persona;

public class Cliente {

 private static Policy loadPolicy(String xmlPath) throws Exception {
  StAXOMBuilder builder = new StAXOMBuilder(xmlPath);
  return PolicyEngine.getPolicy(builder.getDocumentElement());
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  try {

   String trustStore = null;

   // ubicación del almace de llaves que contiene el certificado del
   // servidor AS
   trustStore = "c:\\keys\\cliente.jks";

   // ubicacción de la política que usa el servicio para la seguridad.
   String policyFilePath = "d:\\UTOverTransport.xml";
   // se definen las propiedades para encriptar el canal de comuncación
   // especificando el almacen de certificados de donde se extraerá el
   // certificado correspondiente al servidor
   System.setProperty("javax.net.ssl.trustStore", trustStore);
   System.setProperty("javax.net.ssl.trustStorePassword", "cliente");

   // aqui especificamos el endpoint seguro
   HolamundoWSDLStub stub = new HolamundoWSDLStub(
     "https://192.168.0.224:9445/services/HolamundoWSDL/");

   // optenemos las opciones del servicio
   Options options = stub._getServiceClient().getOptions();
   // enganchamos el modulo de rampart para la seguridad en el flujo de
   // los mensajes.
   stub._getServiceClient().engageModule("rampart");

   // pasamos el usuario y la contraseña
   options.setUserName("admin");
   options.setPassword("admin");
   // asignamos la política de servicio a las opciones del stub.
   options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,
     loadPolicy(policyFilePath));
   stub._getServiceClient().setOptions(options);

   Holaati holaati = new Holaati();
   Persona param = new Persona();
   param.setNombre("nombre1");
   param.setApellidos("apellido1");
   holaati.setPersona(param);

   HolaatiResponse respuesta = stub.holaati(holaati);

   System.out.println("La respuesta es:   "
     + respuesta.get_return().getSaludo());

  } catch (AxisFault e) {
   e.printStackTrace();
  } catch (RemoteException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}




Las librerías que usé fueron las siguientes(tengan en cuenta que las versiones pueden variar):

axiom-1.2.11.wso2v1.jar
axis2-1.6.1.wso2v1.jar
commons-codec-1.3.0.wso2v1.jar
commons-httpclient-3.1.0.wso2v1.jar
commons-io-2.0.0.wso2v1.jar
geronimo-stax-api_1.0_spec-1.0.1.wso2v1.jar
httpcore-4.1.0.wso2v1.jar
neethi-2.0.4.wso2v3.jar
opensaml2-2.0.0.alpha1-wso2v1.jar
org.wso2.carbon.addressing-3.2.0.jar
org.wso2.carbon.logging-3.2.0.jar
org.wso2.securevault-1.0.0.jar
rampart-core-1.6.1.wso2v1.jar
rampart-policy-1.6.1.wso2v1.jar
rampart-trust-1.6.1.wso2v1.jar
woden-1.0.0.M8-wso2v1.jar
wsdl4j-1.6.2.wso2v2.jar
wss4j-1.5.11.wso2v1.jar
XmlSchema-1.4.7.wso2v1.jar

Luego de implementar un ciclo sencillo para consumir varias veces el servicio pueden ver las siguientes estadísticas en su dashboard.


En otras entradas estaremos viendo cómo usar el SOAPUI para consumir un servicio y hacer pruebas de carga y estrés.

jueves, 9 de mayo de 2013

Un problema real que debemos tener en cuenta cuando aseguramos las comunicaciones encriptando el canal de comunicación es que en los puntos inicial y final de ese canal la información está desprotegida. O sea, cuando se envía un información desde el cliente al servidor, al llegar al servidor esta llega completamente en texto plano. En el caso de las herramientas de la suite de WSO2, un pedido constante era poder autenticarse en las herramientas usando las credenciales de un dominio empresarial. El problema con esta petición es que si usamos nuestro user/pass del dominio para por ejemplo en un escenario de seguridad donde se envía tanto el usuario como la contraseña, ambos elementos serán visibles en el servidor, usando la funcionalidad SOAP TRACER de las herramientas, como pueden ver a continuación en este mensaje que llega al servidor:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
   <s:Header>
      <wsa:To>https://192.168.0.247:9445/services/HelloService.HelloServiceHttpsSoap12Endpoint/</wsa:To>
      <wsa:ReplyTo>
                         <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
      </wsa:ReplyTo>
      <wsa:MessageID>http://identifiers.wso2.com/messageid/1337556301686/4284633972</wsa:MessageID>
      <wsa:Action>urn:greet</wsa:Action>
      <o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" s:mustUnderstand="1">
         <u:Timestamp u:Id="uuid-c3cdb38b-e4aa-4467-9d0e-dd30f081e08d-5">
            <u:Created>2012-05-20T23:25:01.686Z</u:Created>
            <u:Expires>2012-05-20T23:30:01.686Z</u:Expires>
         </u:Timestamp>
        <o:UsernameToken u:Id="Me">
            <o:Username>admin</o:Username>
            <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">admin</o:Password>
         </o:UsernameToken>
      </o:Security>
   </s:Header>
   <s:Body>
      <p:greet xmlns:p="http://www.wso2.org/types">
         <!--0 to 1 occurrence-->
            <name>Jorge Infante Osorio</name>
         </p:greet>
      </s:Body>
   </s:Envelope>
Si se fijan podrán ver el Username y el Password, ambos en texto plano. Nuestra primera solución es eliminar el plugin SOAP TRACER así que ya no se podrán ver los mensajes, pero un administrador del sistema puede instalarlo otra vez violando la seguridad. Para solucionar este problema hemos diseñado una política que encripta toda esta parte del Header con lo que garantizamos no solo la protección durante su viaje por la red, si no también cuando llegue al servidor, ya que se verá algo como lo siguiente:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true">
         <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-1">
            <wsu:Created>2012-05-20T22:29:51.959Z</wsu:Created>
            <wsu:Expires>2012-05-20T22:34:51.959Z</wsu:Expires>
         </wsu:Timestamp>
         <xenc:EncryptedKey Id="EncKeyId-1CC54EC6DFFC9D597313375529921542">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
               <wsse:SecurityTokenReference>
                  <wsse:KeyIdentifier EncodingType= "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">a/jhNus21KVuoFx65LmkW2O/l10=</wsse:KeyIdentifier>
               </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
               <xenc:CipherValue>FcR0SVZmCGUpeqMBe+rI/eq/R3teITOFmWpWXbxTkdNL4euIrNEJfY0UZqGKFsui+22/AKvc5I2tWeqozKXXNMSqIEvcoKuoxn1iL6ehI4qFjIlkBHhUhUQ0m6WDQDP1M0sn0jS9xTUaWNNXkeRZlPbIxVl+FjjzrCHG5OzVxaY=</xenc:CipherValue>
            </xenc:CipherData>
         </xenc:EncryptedKey>
         <xenc:ReferenceList>
            <xenc:DataReference URI="#EncDataId-4" />
         </xenc:ReferenceList>
        <xenc:EncryptedData Id="EncDataId-4" Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
               <wsse:SecurityTokenReference>
                  <wsse:Reference URI="#EncKeyId-1CC54EC6DFFC9D597313375529921542" />
               </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
               <xenc:CipherValue>Ub10LNwm6Meaw/QblOLByMpullS2I23aet1rY4eWXCYKUtMgtWJj3q2Ib8rYa71hXzq4/bq2P1Y2GW5iFWt6dS/Z2r0x9UvhW0IhSXJLkh6olAXWpy5seOrW3Uy9PDyqUc1RQ0hpcxtUIKisxQ/aSEtFypoW9dChjdl92HmSy2iSP2TOmcHB1xWLfssyzYnQeTGYqd1s4Wzlv3vIl2RUtzLTQ9jczcxI6ygFE/36vQFbGsfVBdekYHDx3VhNAJjdLgQEuxZEgBOqJP4Qp0mKgtJh4aAEjvpuGjl3ekp48yTNgZ7tClCakS7X2sIZ/GEnQiNxo7FaH2ApUsUWfg6trHZgXwlHdYY2Q50sJLpKYqPk0G0AA2cj+ver+QTGFYL9554fS4Yeba+Lol7gupUcfaltyZEVGgS8lmGIn6qje+HW7KjtQkmhOMsi2t7RRvfXr53mfJt5VSRLfmYg0dO5oGQhdVB30vHnF1CC0y3XA0W8GvJm7OfR+RmMGMCK/dxOdhqyRxZ4j1zUfFaqKL7Vu8+x9mNmqtPAac6dy1RWzKZasbPOOaAFtOCFaC+DHkCegjj5ZDFt6R12AQAQMsNHjXrrs363+kR67zbF6/JkLOXboYAeWkbXTWievo+Bb8mt030gw3DUxlk+xU65bKGnCnRAvdWAwnXo5qmqkOltJ838AYFd+bQvtSnLup+04dDCCgx7g2a20MJ/OyehjtLm4aOAWdauA5jM0QolVwQmQCc=</xenc:CipherValue>
            </xenc:CipherData>
         </xenc:EncryptedData>
         <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-3">
            <ds:SignedInfo>
               <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
               <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
               <ds:Reference URI="#Timestamp-1">
                  <ds:Transforms>
                     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                  </ds:Transforms>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                  <ds:DigestValue>y4ELOvBsDE18NDrEI0fSf+bThJw=</ds:DigestValue>
               </ds:Reference>
               <ds:Reference URI="#UsernameToken-2">
                  <ds:Transforms>
                     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                  </ds:Transforms>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                  <ds:DigestValue>d/j2dlFN+yFvdSCmvoZ1p0fJFzE=</ds:DigestValue>
               </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>Lg++XtBfdh5BkAQml51/b7bI08M=</ds:SignatureValue>
            <ds:KeyInfo Id="KeyId-1CC54EC6DFFC9D597313375529921923">
               <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-1CC54EC6DFFC9D597313375529921924">
                  <wsse:Reference URI="#EncKeyId-1CC54EC6DFFC9D597313375529921542" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
               </wsse:SecurityTokenReference>
            </ds:KeyInfo>
         </ds:Signature>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <ns2:echoString xmlns:ns2="http://echo.services.core.carbon.wso2.org">
         <in>jorge infante osorio</in>
      </ns2:echoString>
   </soapenv:Body>
</soapenv:Envelope>
Lo malo es que el tamaño del mensaje crece, así como su complejidad, pero como estamos haciendo una encriptación asimétrica, el rendimiento no se afecta significativamente. Lo bueno es que podemos proteger de esa manera información sensible. Ejemplificando el efecto de este cambio en el rendimiento, una prueba sencilla con SOAPUI nos muestra lo siguiente:
El payload del mensaje, o sea su carga útil era de 10.5kb mientras que el mensaje completo pesaba 13.5kb, pueden dividir los bytes entre cnt, o sea la parte de firma y encriptación agregaba 3kb a la carga útil. El máximo tiempo de respuesta no superó 1s y el promedio rondó los 145ms. Basándonos en esto y en un primer momento, creemos que esta solución es válida para proteger las credenciales de los usuarios cuando esto sea requerido por los clientes.