En entornos de servicio web simples, los clientes se conectan directamente a los servidores y los servidores ejecutan directamente todos los procesos necesarios para la solicitud. Como usted aprendió en el último artículo de esta serie, las conexiones seguras SSL pueden proporcionar una excelente seguridad para más propósitos en este tipo de entorno. Pero entornos más complejos son cada vez más comunes, donde múltiples capas de servidores son envueltas en el proceso de una solicitud. La idea completa de orquestación del servicio, cada vez más popular en muchos entornos empresariales, está basada en este enfoque, como es el concepto de arquitectura orientada a servicios (SOA). En esos tipos de entornos, es necesaria la alternativa más potente de WS-Security.
El WS-Security viene con un costo de rendimiento pesado, como lo discutido en el último artículo. Una manera de reducir ese costo es establecer el WS-SecurityPolicy apropiado para cada operación individual o hasta un mensaje definido por un servicio, en vez de aplicar un WS-SecurityPolicy único al servicio completo. La utilización granular del WS-Security necesita más consideración que el enfoque global, pero cuando es aplicado de manera apropiada puede reducir la sobrecarga del rendimiento para operaciones utilizadas comúnmente sin debilitar la seguridad de operaciones que la necesitan.
La aplicación de muestra utilizada para este artículo es la misma utilizada en "Fundamentos del Axis2 WS-Security" y en "Encriptación y firma del Axis2 WS-Security" — un servicio simple de gestión de la biblioteca. (Ver Descargar para obtener el código de origen completo para este artículo.) Este servicio define tres operaciones:
getBookpara recuperar los detalles de un libro en particular identificado por International Standard Book Number (ISBN).getBooksByTypepara recuperar los detalles para todos los libros de un tipo en particularaddBookpara añadir un libro nuevo a la biblioteca.
Para entregar una variedad interesante en el uso de la seguridad, este artículo supone que:
- La operación
getBookpuede ser expuesta de manera segura para cualquier persona (sin seguridad). - El
getBooksByTypenecesita autorización (entonces necesita unUsernameToken). - La operación
addBooknecesita un seguimiento de auditoría para rastrear a quien añadió cada libro (implementado por la firma de los mensajes de solicitud).
En los artículos anteriores, usted vio cómo configurar el Axis2/Rampart al adjuntar un documento WS-SecurityPolicy a la instancia org.apache.axis2.client.ServiceClient (en el componente del cliente) o incorporando el documento de política en la configuración del servicio services.xml (en la parte del servidor). Este enfoque funciona y puede ser útil en la prueba, pero para producción el uso de WS-SecurityPolicy está mejor asociado directamente con una definición de servicio al ser incorporado dentro de un documento WSDL. El WS-Policy y el WS-SecurityPolicy están diseñados para soportar este tipo de incorporaciones con referencias desde las definiciones <wsdl:binding>, <wsdl:binding>/<wsdl:operation>, o <wsdl:binding>/<wsdl:operation>/<wsdl:message> utilizadas para identificar la política apropiada para aplicar a ese enlace, operación o mensaje. Axis2 1.4.1 implementó de manera preliminar el manejo para políticas incorporadas en WSDL y la implementación mejoró en el código de release Axis2 1.5 actual. Para demostrar el uso de la política en WSDL, este artículo utiliza el código de release Axis2 1.5 en combinación con el código Rampart actual sin release hasta ahora (que debería finalmente ser divulgado como Rampart 1.5).
El listado 1 muestra el WSDL para la aplicación de ejemplo con política incorporada y referenciada desde las ubicaciones apropiadas. (El listado 1 está editado para longitud y anchura; el WSDL completo está disponible como library.wsdl en la descarga de código.) Cada política define un valor de Id que es entonces referenciado desde la operación apropiada (en el caso de la política UsernameToken) o el mensaje (en el caso de la política de firma), todo lo mostrado en negrito.
Listado 1. WSDL con políticas de seguridad granular
<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"
xmlns:wns="http://ws.sosnoski.com/library/wsdl"
xmlns:tns="http://ws.sosnoski.com/library/types"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">
<!++ Policy for signing message, with certificate from client included in each
message to server ++>
<wsp:Policy wsu:Id="SignOnly" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken=".../IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:InitiatorToken>
...
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:SignedParts
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<sp:Body/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<!++ Policy for UsernameToken with plaintext password, sent from client to
server only ++>
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken=".../IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
...
<wsdl:binding name="LibrarySoapBinding" type="wns:Library">
<wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getBook">
<wsdlsoap:operation soapAction="urn:getBook"/>
<wsdl:input name="getBookRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getBookResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getBooksByType">
<wsp:PolicyReference
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
URI="#UsernameToken"/>
<wsdlsoap:operation soapAction="urn:getBooksByType"/>
<wsdl:input name="getBooksByTypeRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getBooksByTypeResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="addBook">
<wsdlsoap:operation soapAction="urn:addBook"/>
<wsdl:input name="addBookRequest">
<wsp:PolicyReference
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
URI="#SignOnly"/>
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addBookResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="library-granular">
...
</wsdl:service>
</wsdl:definitions> |
Las políticas del listado 1 y WSDL son tomadas desde los artículos previos, aunque sin previa fusión en esta forma. Usted podría notar una diferencia importante en las políticas, aunque: todas las versiones previas incluían la información de configuración de Rampart, que era específica para el cliente o para el servidor. Ahora que la política está incorporada en el WSDL, no es práctico incluir la configuración de Rampart directamente. (Usted necesitaría editar el WSDL para incluir su información de configuración de Rampart de cliente y regenerar el código cada vez que esté cambiado y en el servidor su configuración de Rampart estaría expuesta a cualquier persona que acceda al WSDL). Entonces el código de ejemplo establece esta información de configuración en forma separada. Para hacerlo, utiliza variaciones de las mismas técnicas previamente utilizadas para las políticas con la configuración de Rampart incluida.
Utilización de los componentes del cliente
Desde la perspectiva del usuario generar un código desde el WSDL funciona igual, ya sea que el WS-Policy esté incluido o no. Si usted mira en el resguardo del cliente generado desde un WSDL que contiene el WS-Policy, usted verá que la política está adjunta directamente para los componentes de la descripción de servicio mientras está siendo construida, pero esto está oculto en la implementación y no afecta los métodos de la interfaz que su código de cliente utiliza.
Para hacer uso de la configuración del WS-SecurityPolicy en el cliente, usted necesita tomar algunas resoluciones en su código de cliente. Como mínimo, usted debe interconectar el módulo de Rampart en elorg.apache.axis2.client.ServiceClient asociado con su instancia de resguardo. Este paso es necesario aún si usted incluye su información de configuración de Rampart en el WSDL. Desafortunadamente, no aparece ningún modo para realizar la interconexión de Rampart en la operación o en el nivel de mensaje en el código actual, por lo tanto parte del beneficio del WS-Security granular se pierde en el presente cuando es utilizado con un cliente de Axis2.
Si usted mantiene su configuración de Rampart separada desde el WDSL, como lo recomendado, también necesita aplicar esa configuración a la descripción del servicio. El listado 2 muestra el código de cliente utilizado para este propósito en la aplicación de muestra. Llama al método applyPolicy() para añadir la política que contiene la configuración de Rampart a la definición de servicio.
Listado 2. Configurando las operaciones del componente del cliente
// create the client stub
String target = args[0] + "://" + args[1] + ":" + args[2] + args[3];
System.out.println("Connecting to " + target);
LibraryGranularStub stub = new LibraryGranularStub(target);
// configure and engage rampart module
ServiceClient client = stub._getServiceClient();
client.getAxisService().applyPolicy(loadPolicy("rampart-client-policy.xml"));
client.engageModule("rampart");
// set the username and password for requests which use them
Options options = client.getOptions();
options.setUserName("libuser");
options.setPassword("books");
|
El código del Listado 2 establece el nombre de usuario y la contraseña en las opciones ServiceClient, lo que significa que están definidos para todas las operaciones utilizando ese servicio aunque ellos sean sólo utilizados por una operación única. A diferencia de la interconexión del módulo de Rampart para todas las operaciones, establecer el nombre de usuario y la contraseña de esta manera no daña — los valores utilizados sólo cuando los necesita Rampart para construir un UsernameToken, y por el contrario son ignorados.
El documento de política que contiene la configuración de Rampart es mostrado en el Listado 3. Esta es la misma política utilizada en "Encriptación y firma del Axis2 WS-Security," ahora extraída en un documento político separado.
Listado 3. Política de configuración de cliente de Rampart
<wsp:Policy xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>clientkey</ramp:user>
<ramp:passwordCallbackClass
>com.sosnoski.ws.library.adb.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type"
>JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file"
>client.keystore</ramp:property>
<ramp:property
name="org.apache.ws.security.crypto.merlin.keystore.password"
>nosecret</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy> |
El Ant build.xml incluido en el código descarga manejadores generando el código de cliente y de servidor desde el WSDL, compilando el código y generando el archivo AAR de servicio. También copia la política de configuración de Rampart (suministrada en la descarga como rampart-client-policy.xml, en el directorio raíz) en la ruta de acceso de clases del cliente, junto con rendir algún manejo de política complementaria de servidor tratado en la siguiente sección.
Utilización de las partes del servidor
Si usted quiere mantener su configuración de Rampart de las partes del servidor fuera del WSDL (¡generalmente una muy buena idea!) usted necesita incluirla en el archivo services.xml. En artículos previos, usted vio esto realizado para una completa configuración WS-SecurityPolicy, incluyendo la configuración de Rampart y aplicada al servicio en su totalidad. En esta ocasión, la política de configuración de Rampart es el único componente añadido al services.xml, y es realizada en el nivel de operación.
El documento de política que contiene la configuración de Rampart es mostrado en el Listado 4. Así como el componente equivalente del cliente, ésta es la misma política utilizada en "Encriptación y firma del Axis2 WS-Security", ahora extraída en un documento de política separado.
Listado 4. Política de configuración del servidor de Rampart
<wsp:Policy xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>serverkey</ramp:user>
<ramp:passwordCallbackClass
>com.sosnoski.ws.library.adb.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type"
>JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file"
>server.keystore</ramp:property>
<ramp:property
name="org.apache.ws.security.crypto.merlin.keystore.password"
>nosecret</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy> |
El Ant build.xml utiliza un programa PolicyTool incluido en la descarga de código para fusionar la política del Listado 4 (suministrada en la descarga como ampart-server-policy.xml, en el directorio raíz) en el services.xml. El services.xml modificado es mostrado en el Listado 5 (editado para ancho y longitud):
Listado 5. el services.xml después de las adiciones
<serviceGroup>
<service name="library-granular">
<messageReceivers>
<messageReceiver class=
"com.sosnoski.ws.library.adb.LibraryGranularMessageReceiverInOut"
mep="http://www.w3.org/ns/wsdl/in-out"/>
</messageReceivers>
<parameter name="ServiceClass"
>com.sosnoski.ws.library.adb.LibraryGranularImpl</parameter>
<parameter name="useOriginalwsdl">true</parameter>
<parameter name="modifyUserWSDLPortAddress">true</parameter>
<operation mep="http://www.w3.org/ns/wsdl/in-out" name="getBook"
namespace="http://ws.sosnoski.com/library/wsdl">
<actionMapping>urn:getBook</actionMapping>
<outputActionMapping>.../getBookResponse</outputActionMapping>
</operation>
<operation mep="http://www.w3.org/ns/wsdl/in-out" name="getBooksByType"
namespace="http://ws.sosnoski.com/library/wsdl">
<actionMapping>urn:getBooksByType</actionMapping>
<outputActionMapping>.../getBooksByTypeResponse</outputActionMapping>
<module ref="rampart"/>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>serverkey</ramp:user>
...
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</operation>
<operation mep="http://www.w3.org/ns/wsdl/in-out" name="addBook"
namespace="http://ws.sosnoski.com/library/wsdl">
<actionMapping>urn:addBook</actionMapping>
<outputActionMapping>
http://ws.sosnoski.com/library/wsdl/Library/addBookResponse
</outputActionMapping>
<module ref="rampart"/>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>serverkey</ramp:user>
...
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</operation>
</service>
</serviceGroup> |
En el Listado 5, usted puede ver que una referencia de módulo de Rampart y una copia de la política de configuración del servidor fueron añadidas a las definiciones de las dos operaciones utilizando WS-Security, getBooksByType, y addBook. Estos cambios configuran el servicio para interconectar el Rampart sólo para esas dos operaciones y para utilizar los valores suministrados para la clave y para el acceso de certificado de Rampart.
Si usted compila y despliega el archivo AAR generado a una instalación de servidor Axis2, usted puede ver el efecto de esto en la página de Servicios de Administración/Disponible, donde los módulos interconectados para cada operación definida en el servidor, son enumerados. Si usted ejecuta el código de cliente y supervisa el intercambio de mensaje (utilizando una herramienta como el TCPMon, descrito en "Fundamentos del Axis2 WS-Security"), usted verá que la manipulación de seguridad funciona como lo deseado, con:
- Sin cabeceras WS-Security en los
mensajesgetBook - Una cabecera WS-Security con un
UsernameTokenen elmensaje de solicitudgetBooksByType - Una cabecera WS-Security con firmas en el mensaje de solicitud
addBook(pero no la respuesta)
El Axis2 y Rampart son actualmente (esto es, con el release de Axis2 1.5 y una compilación nocturna de Rampart actual) capaz de manejar configuraciones básicas de WS-SecurityPolicy intercaladas en WSDL, incluyendo políticas granulares definidas a nivel de operación o de mensaje. Sin embargo, algunas de las configuraciones probadas para este artículo no funcionarían con Axis2/Rampart. Por ejemplo, intentar establecer la política UsernameToken para la operación addBook (además de la política de firma en el mensaje de entrada) resultó en un error, al parecer relacionado con el cifrado en el código Rampart (aunque ningún cifrado fue utilizado). Juzgando desde esta experiencia y desde algunos de los informes de problemas, parece que la manipulación de Axis2/Rampart WS-SecurityPolicy es buena para configuraciones simples, reflejando casos de uso común, pero propensas a fallar cuando se aplican a combinaciones inusuales.
Otro problema es que la sobrecarga de interconectar Rampart en el servidor siempre se producirá en la manipulación de la solicitud y en la respuesta, aún si usted utiliza el WS-Security sólo para uno de los mensajes (como lo discutido en "El alto costo de (WS-)Security"). Por parte del cliente, la situación es aún peor — porque interconectar el Rampart al cliente es actualmente una proposición de todo o nada, si usted utiliza el WS-Security en cualquier operación, tendrá que vivir con la sobrecarga de Rampart en cada operación.
Finalmente, la manipulación actual de Axis2/Rampart WS-Policy no soporta alternativas de política. Las alternativas son un dispositivo muy importante del diseño de WS-Policy, permitiendo que los servicios dejen que los clientes elijan cuál de dos o más configuraciones aceptables son para utilizarlas cuando ellos acceden al servicio. La implementación de la política de Axis2/Rampart no soporta este dispositivo, en lugar de eso ignora todo, excepto la primera alternativa.
Con este artículo y los tres anteriores, la serie servicios Java Web ha cubierto todos los aspectos más importantes de la manipulación de WS-Security y WS-SecurityPolicy en el Axis2/Rampart, incluyendo problemas de rendimiento. En episodios futuros, usted verá cómo otras infraestructuras de servicios web de Java funcionan con WS-Security y WS-SecurityPolicy, pero primero hay un par de otros aspectos de Axis2 que observar.
Un tema muy importante para muchas organizaciones, es el soporte para Java Architecture para XML Binding (JAXB) 2.X. JAXB 2.X es el estándar de Java oficial para el enlace de datos XML, y aunque las alternativas de origen abierto ofrecen sus propios beneficios, algunas organizaciones quieren adherirse al estándar. En el próximo artículo, usted verá cómo puede utilizar el enlace de datos de JAXB 2.X con Axis2, y aprender cómo se compara a las otras alternativas de enlace de datos soportadas por Axis2.
| Descripción | Nombre | tamaño | Metodo de descarga |
|---|---|---|---|
| Source code for this article | j-jws7.zip | 29KB | HTTP |
Información sobre métodos de descarga
Aprender
-
Apache Axis2/Java: Encuentre información en desarrollo y estado de Axis2 junto con enlaces para listas de correo, seguimiento de problemas y descargas.
-
Rampart: Aprenda más sobre el módulo de Rampart WS-Security para Axis2.
-
"Servicios web y arquitectura Axis2 " (Eran Chinthaka, developerWorks, Noviembre 2006): Aprenda cómo los módulos como Rampart extienden Axis2.
-
Comprendiendo las especificaciones de Web Services: Esta serie de tutoriales introduce muchos de los importantes estándares de servicios web, incluyendo:
- "Comprendiendo las especificaciones de Web Services: Web Services Description Language (WSDL)" (Nicholas Chase, developerWorks, Julio de 2006)
- "Comprendiendo las especificaciones de Web Services: WS-Security" (Nicholas Chase, developerWorks, Agosto de 2006)
- "Comprendiendo las especificaciones de Web Services: WS-Policy" (Tyler Anderson, developerWorks, Febrero de 2007).
-
OASIS Web Services Security (WSS) TC: Esta es la organización responsable por la especificación de WS-Security y perfiles de señal. Usted puede encontrar enlaces aquí y todas las versiones de estos estándares.
-
The W3C Web Services Policy Working Group: Este grupo define la especificación de WS-Policy.
-
OASIS Web Services Security (WSS) TC: Esta organización es responsable por las especificaciones de WS-Trust, WS-SecureConversation y de WS-SecurityPolicy.
-
Examine la librería tecnológica para obtener libros acerca de estos y otros temas técnicos.
-
Área de tecnología de Java de developerWorks: Encuentre cientos de artículos sobre cada aspecto de la programación de Java.
Obtener los productos y tecnologías
-
Apache Axis2: Descargue el último release de Axis2.
-
Rampart: Descargue el módulo de Rampart para Axis2.
- Descargue las versiones de evaluación del producto de IBM o explore los procesos en línea en el IBM SOA Sandbox y capacítese en herramientas de despliegue de aplicación y productos de middleware desde el DB2®, Lotus®, Rational®, Tivoli®, y WebSphere®.
Comentar
- Participe en la comunidad My developerWorks.

Dennis Sosnoski es un consultor y entrenador especializado en servicios web y XML basados en Java. Su experiencia en el desarrollo de software profesional abarca más de 30 años, con los últimos 10 enfocados a tecnologías XML y Java ejecutadas en el servidor. Dennis es el desarrollador principal de la infraestructura JiBX XML Data Binding de fuente abierta y de la infraestructura de servicios web JiBX/WS asociada, así como también un delegado en la infraestructura de servicio web Apache Axis2. También fue uno de los miembros de Grupo Experto para las especificaciones KAX-WS 2.0 y JAXB 2.0. El material para la serie de servicios web de Java está basado en las clases de capacitación de Dennis.