Comprender las especificaciones de servicios web, Parte 5: WS-Policy

Los servicios web pueden ser caóticos sin una definición clara de cómo utilizarlos. Este tutorial, la Parte 5 de la serie “Understanding web services”, explica los conceptos que yacen detrás de WS-Policy y las normas relacionadas, como por ejemplo WS-SecurityPolicy, que brinda un medio para especificar posibles configuraciones de un servicio web, y también para aplicar seguridad y autenticación definidas.

Tyler Anderson, Consultant, Stexar Corp.

Tyler Anderson recibió su título en Ciencias Informáticas en 2004 y su máster en Ingeniería Eléctrica e Informática en 2005 de la Universidad Brigham Young. Tyler trabajó con Stexar Corporation como Ingeniero de diseño, I&D, de mayo de 2005 a agosto de 2006. Desde que Backstop Media LLC lo descubrió a principios de 2005, Tyler ha escrito y codificado muchos artículos y tutoriales para IBM developerWorks y DevX.



08-08-2011

Antes de comenzar

En este tutorial aprenderá sobre Web Services Policy, o WS-Policy. Este estándar es para desarrolladores que desean exponer sus propios servicios en un entorno y utilizar s que definen la manera en que a estos servicios web se les permite interactuar con otros clientes y servicios. El término WS-Policy se refiere a un marco que define el gobierno, como por ejemplo el método de transporte y la seguridad, como por ejemplo el nivel de cifrado.

Para seguir este tutorial debe tener una comprensión básica de SOAP que puede lograr leyendo la Parte 1 de esta serie (por extensión, también necesita una comprensión básica de XML). SOAP es agnóstico de lenguaje de programación. Sin embargo, las muestras en este tutorial utilizan Java™ y el proyecto Apache Axis2, a pesar de que los conceptos se aplican a cualquier entorno y lenguaje de programación.

Acerca de esta serie

Esta serie tutorial enseña los conceptos básicos de los servicios web siguiendo las hazañas del periódico ficticio, Daily Moon, mientras el personal utiliza servicios web para crear un sistema de flujo de trabajo para incrementar la productividad en este entorno competitivo.

La Parte 1 empieza simplemente explicando los conceptos básicos de los servicios web y mostrándole cómo utilizar SOAP, la especificación que subyace en la mayoría de lo que vendrá, y conecta el departamento de clasificados con el Sistema de Gestión de Contenido.

La Parte 2 lleva las cosas un poco más allá, al explicar cómo utilizar Web Services Description Language (WSDL) para definir los mensajes producidos como se espera por el servicio web, lo que le permite al equipo crear servicios y a los clientes que se conectan a ellos con más facilidad.

La Parte 3 encuentra al equipo con una cantidad de servicios implementados y un deseo de ubicarlos con facilidad. En respuesta, Universal Description, Discovery and Integration (UDDI) brinda un registro que permite realizar búsquedas de servicios disponibles a una manera de publicitar sus propios servicios a otros.

En la Parte 4, Rudy, editor del Daily Moon, decide que el periódico necesita implementar mejores procedimientos de seguridad para servicios web que acceden a sus sistemas internos.

En esta Parte 5, WS-Policy, se ven los cambios que deben hacer los equipos para acceder a esos servicios recientemente protegidos.

La Parte 6 se concentra en la interoperabilidad, ya que se debe acceder a servicios de varias distintas implementaciones desde un sistema único. La Parte 6 cubre los requisitos y las pruebas que involucra la certificación WS-I.

Finalmente, la Parte 7 muestra cómo utilizar Business Process Execution Language (WS-BPEL) para crear aplicaciones complejas desde servicios individuales.

Acerca de este tutorial

En este tutorial vea como el equipo del periódico Daily Moon utiliza la especificación WS-Policy para especificar las directivas que deben cumplir los servicios web para utilizar los servicios web de la compañía.

En el transcurso de este tutorial, usted:

  • Aprenderá la sintaxis para la creación de documentos de directivas, y también cómo crear sus propias directivas, y cómo usar otras aserciones ya existentes.
  • Verá cómo puede manipular documentos de Directivas utilizando propiedades matemáticas de construcciones XML subyacentes.
  • Utilizará Apache Neethi, la implementación de WS-Policy incompleta de Axis2 que permite a los usuarios de Axis2 manipular y combinar documentos de directivas.
  • Aprenderá a utilizar WS-Policy y WSDL juntos, y aprenderá a escribir WSDL que solicite que los puertos respeten una directiva definida.

Necesitará unas herramientas para comenzar.

Prerrequisitos

Gran parte de este tutorial es conceptual, pero para seguir el código que utiliza Apache Neethi para trabajar con documentos WS-Policy, necesita tener instalado el siguiente software:

Java 2 Standard Edition versión 1.4.2 o superior - Todas estas herramientas están basadas en Java, al igual que los servicios y clientes que construirá en este tutorial:

Apache Neethi - Apache Neethi es lo que utiliza Axis2 para crear una representación de tiempo de ejecución de los documentos de directivas, y para realizar operaciones de normalización, combinación e intersección en documentos de directivas.


Generalidades

Antes de entrar en la especificación de directivas para servicios web, revise el escenario de muestra hasta este punto en la serie.

La historia hasta ahora

Esta serie sigue al personal del periódico ficticio Daily Moon mientras traslada muchas de sus operaciones diarias a un sistema basado en servicios web. En la Parte 1, el Departamento Clasificados aprendió sobre SOAP al interactuar con el Sistema de Gestión de Contenido, y en la Parte 2, crearon su propio servicio, y lo definieron utilizando Web Services Description Language (WSDL). Luego en la Parte 3, aprendieron cómo interactuar con un registro UDDI, y también cómo encontrar datos dentro de uno, lo que finalmente los condujo a crear uno para le compañía a fin de permitir a otras organizaciones interactuar con el Daily Moon. Debido a que Rudy insistió en que sus colegas Gene y Francis brindaran una manera de evitar el acceso no autorizado a sus sistemas en la Parte 4, Gene y Francis tuvieron que implementar WS-Security para sus servicios web.

Ahora Rudy se acaba de dar cuenta de que los clientes que acceden a sus servicios web no necesariamente están usando los nuevos servicios web que él requiere. Por ende, debe definir directivas para los servicios web que indiquen cómo y de qué manera se pueden utilizar. En otras palabras, Rudy desea hacer que los clientes que accedan a los servicios web del Daily Moon lo hagan de manera indicada, garantizando la seguridad que se incorporó en la Parte 4 de esta serie. ¡Encargó a Gene y a Francis que se ocuparan de la tarea!

Por qué utilizar WS-Policy

Web Services Policy Framework, o WS-Policy, es una especificación que permite a un servicio web tener un conjunto de reglas que se deben cumplir, o consumir. Los autores de clientes que consumen servicios web deben estudiar la información de directivas para ver si pueden o no respetarlas. Por ende, no se puede escribir un cliente para que simplemente acceda a un servicio web que requiera que todos los mensajes sean cifrados o firmados de cierta manera. Un cliente tampoco accedería a un servicio web que tiene una directiva que requiere una marca de tiempo y enviar un mensaje que no la tenga. Y ese es el objetivo de WS-Policy: especificar información de directivas que deben respetar los consumidores del servicio web.

Cuando Gene se sienta a implementar WS-Policy, descubre un problema. Axis2 todavía no soporta completamente WS-Policy. El componente Apache Neethi, que controla WS-Policy, lee y comprende directivas, pero Axis2 no brinda una manera de que el servicio llegue a esa información… todavía.

Sin embargo, ese es el plan. Así que Gene y Francis deciden seguir como si el soporte ya estuviera implementado, para estar bien versados en el tema y listos cuando se disponga del soporte. Rudy está de acuerdo en que el tiempo estará bien invertido, debido a la importancia de WS-Policy en el mundo próximo de SOA sobre el que ha estado leyendo.

Cómo se ve una directiva

¡Debe estar ansioso por ver cómo es una directiva! Bien, aquí está. Primero empieza con un simple documento de directiva, como se muestra en el Listado 1.

Listado 1. El primer documento de directiva que ha visto
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sec="http://schemas.xmlsoap.org/ws/2002/12/secext" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sec:SecurityToken>
        <sec:TokenType>sec:X509v3</sec:TokenType>

      </sec:SecurityToken>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Básicamente, un servicio web que utiliza este archivo de directivas tiene un requisito para los clientes que operan con él: un token de seguridad de tipo X509v3 (para obtener más información sobre tokens de seguridad, ver Recursos). A continuación, verá cómo contra con una directiva o un conjunto de directivas refuerza WS-Security.

Cómo WS-Policy refuerza WS-Security

WS-Policy y WS-Security van de la mano. De hecho, la especificación hay una WS-SecurityPolicy que contiene varias aserciones que se pueden incluir en documentos WS-Policy, porque hay varios medios y métodos para implementar seguridad, y por ende debe existir una directiva para esos tipos a fin de que puedan incluirse en las directivas. Crear directivas que requieren ciertos tipos de cifrado, firmado o que requieren una marca de tiempo ayuda a fortalecer la seguridad de un servicio web porque ningún mensaje entrante puede obtener una respuesta deseada de un servicio web protegido con directivas definidas a menos que los clientes respeten las directivas que da el servicio web. A Francis le encanta esta idea. ¿Qué resultado daría todo ese trabajo arduo si no hubiera manera de aplicarlo? ¡Hurra por WS-Policy!

¡Excelente! Súmese a Gene y Francis, comenzando con cómo crear documentos de directivas.


Construir documentos WS-Policy

En el Listado 1 vio que un documento de directivas es XML al igual que la mayoría de los otros documentos de servicios web, y en esta sección puede aprender cómo construir el suyo al aprender la sintaxis y las aserciones que están disponibles para usted.

Terminología

He aquí unas cuantas palabras de vocabulario que deben saber todos los gurúes de WS-Policy, inclusive Francis y Gene:

Directiva
Una lista de alternativas de directivas.
Alternativa de directivas
Contiene aserciones de directivas. En forma normal, una política contiene una lista de alternativas de directivas especificada en wsp:All tags, lo que significa que un cliente que sigue la directiva puede escoger seguir cualquiera de las alternativas de directivas disponibles. Puede elegir cuál, pero debe seguir todas las directivas con una alternativa. Verá más detalles de su funcionamiento en esta sección.
Aserción de directiva
Representa un requisito o capacidad. Por ejemplo, una aserción de directiva podría requerir que se utilice cierto tipo de cifrado en el cifrado de los datos transmitidos. En forma normal, las aserciones de directivas se incluyen dentro de una alternativa de directiva.
Tipo de aserción de directiva
Una clase de aserciones de directivas. Por ejemplo, <sec:SecurityToken> en el Listado 1 es un ejemplo de un tipo de aserción de directiva.
Expresión de directiva
La representación XML de una directiva, como se muestra en el Listado 1, en forma normal o compacta.
Sujeto de directiva
Una entidad u objeto al cual se puede aplicar una directiva.
Alcance de la directiva
El conjunto de objetos al cual se puede aplicar una directiva.
Adjunto de directiva
La manera en que las directivas se relacionan a uno o más alcances de directivas.

Ver Recursos para leer un artículo de generalidades que cubre WS-Policy. Ahora verá cómo crear documentos de directivas en forma normal.

Forma normal

La expresión de directiva en forma normal es la sintaxis definida en la especificación WS-Policy. El documento de directivas más simple es el vacío: <wsp:Policy />

Sin embargo, esto no es muy útil. A continuación, agrándelo mientras lo mantiene vacío (ver Listado 2).

Listado 2. Un documento de directivas vacío en forma normal
<wsp:Policy ...>
  <wsp:ExactlyOne>
    <wsp:All>
    </wsp:All>
    <wsp:All>
    </wsp:All>

  </wsp:ExactlyOne>
</wsp:Policy>

El documento de directivas que figura en el Listado 2 especifica una directiva con dos alternativas de directivas que no contienen aserciones de directivas. Ahora vuelva a mirar el Listado 1, que contiene una única aserción de política.

Observe que las aserciones de directivas del Listado 1 no son válidas, pero se muestran aquí como ejemplo. Este documento contiene dos alternativas de directivas: una con una única aserción de directivas, y la otra con dos aserciones de directivas. Por ende, otro cliente que llame al periódico puede escoger respetar la alternativa de directivas que contiene la única aserción de directivas, DummyAssertion1, o la otra alternativa de directivas que contiene dos aserciones de políticas, DummyAssertion1 y DummyAssertion2.

A continuación verá cómo referenciar aserciones de directivas definidas en la especificación WS-SecurityPolicy.

WS-SecurityPolicy

La especificación WS-SecurityPolicy contiene varias aserciones de directivas y varios tipos de aserciones de directivas. Hay varias aserciones especificadas en la especificación, e incluyen las siguientes:

SignedParts
Especifica qué parte de un mensaje, como por ejemplo el encabezado, el cuerpo, etc., se debe firmar.
SignedElements
Especifica qué elementos dentro de un mensaje se debe firmar.
EncryptedParts
Igual que SignedParts, excepto que requiere cifrado.
EncryptedElements
Igual que SignedElements, excepto que requiere cifrado.
Token assertions
En el documento WS-SecurityPolicy se incluyen varias aserciones de token (ver Recursos para obtener un enlace) que definen qué tipo de token incluir en los mensajes.
Propiedades
También se pueden establecer varias propiedades, como por ejemplo algoritmos de cifrado, o un requisito de marca de tiempo.

Ahora, Gene y Francis pueden crear un documento de directivas relevante para sus proyectos de servicios web que utiliza especificación WS-SecurityPolicy.

Construir una directiva utilizando la especificación WS-SecurityPolicy

Ahora, a construir una directiva para el Daily Moon. Francis comenzó con una directiva pequeña, como se muestra en el Listado 3.

Listado 3. Construir una directiva para el periódico
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Este documento contiene una única aserción de directiva que requiere la inclusión de cierto token de seguridad. Si esta política estuviera adjunta a un servicio web, los clientes que quisieran operar con ese servicio web están obligados a enviar tokens de seguridad del tipo especificado en la directiva, X509v3 en este caso. Gene desea agregar a la directiva especificando aserciones de directivas de firmado, el cifrado, la marca de tiempo y token de usuario (ver Listado 4).

Listado 4. Agregar a la directiva del periódico
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" >
...
      </sp:SecurityToken>
      <sp:UsernameToken /> 
      <sp:SignedParts />
      <sp:EncryptedParts>
        <sp:Body />

      </sp:EncryptedParts>
      <sp:TransportBinding>
        <sp:IncludeTimeStamp />
      </sp:TransportBinding>
    </wsp:All>
  </wsp:ExactlyOne>

</wsp:Policy>

La línea que contiene sp:WssUsernameToken11 requiere un token de usuario. <sp:SignedParts />requiere que se firme todo el mensaje. La construcción XMLsp:EncryptedPartscontiene una etiqueta <sp:Body />, lo que significa que solo el cuerpo debe cifrarse. Finalmente, la construcción XML sp:TransportBinding contiene la etiqueta sp:IncludeTimeStamp, que requiere la inclusión de una marca de tiempo en los mensajes.

Ahí está: un archivo de directivas terminado, gracias a Gene and Francis. A continuación verá como redactar una directiva de manera compacta al referenciar una que ya existe en vez de duplicarla.

Referenciar un documento de directivas dentro de una directiva

Comience con la directiva del Listado 4. Ahora, transfórmela en la siguiente, como se muestra en el Listado 5.

Listado 5. Referenciar una directiva dentro de una directiva
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext"
xmlns:wsu=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity
-utility-1.0.xsd >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>

      <wsp:Policy wsu:Id="myPolicy">
        <sp:UsernameToken /> 
        <sp:SignedParts />
        <sp:EncryptedParts>
          <sp:Body />

        </sp:EncryptedParts>
      </wsp:Policy>

      <sp:TransportBinding>
        <sp:IncludeTimeStamp />
      </sp:TransportBinding>
    </wsp:All>

    <wsp:PolicyReference URI="#myPolicy" />
  </wsp:ExactlyOne>
</wsp:Policy>

Observe que se colocan tres aserciones de directivas dentro wsp:Policy, y una ID se relaciona con ella (myPolicy). La instrucción wsp:PolicyReference básicamente copia y pega la construcción de directivas a la ubicación especificada. Gene cree que es excelente para crear expresiones de directivas compactas.

En la próxima sección aprenderá sobre operadores de directivas y cómo manipular documentos de directivas utilizando las propiedades matemáticas de los operadores de directivas.


Utilizar operadores de directivas

Las construcciones que conforman una directiva, como por ejemplo las aserciones de directivas y las alternativas de directivas, tienen ciertas propiedades matemáticas. Conocer estas propiedades le permite redactar directivas complejas de la manera más compacta. En esta sección, aprenderá estas propiedades y cómo aplicarlas a los documentos de directivas.

Generalidades de las construcciones

Las construcciones que se aplican al resto de esta sección al expresar directivas complejas en la manera más compacta, son wsp:Policy,wsp:All y wsp:ExactlyOne. Para ayudar a redactar directivas complejas, estas tres construcciones se pueden anidar dentro de cada una. Las siguientes reglas se aplican al transformar una expresión compacta (con la menor cantidad de expresiones posible) en una expresión de forma normal (no se desperdicia ninguna línea; toda la expresión se redacta en la forma más detallada):

  • Equivalencia
  • Vacía
  • Asociativa
  • Conmutativa
  • Distributiva

Verá cómo utilizar cada una de estas reglas en el resto de esta sección.

Equivalencia

Esta regla, equivalencia, especifica que wsp:Policy es equivalente a wsp:All. Debido a que wsp:All especifica una alternativa de directiva, wsp:Policy también especifica una alternativa de directiva.

Vacía

Tanto una directiva como una alternativa de directiva pueden estar vacías. Si una directiva está vacía, como por ejemplo <wsp:ExactlyOne />, entonces la directiva tiene cero alternativas de directivas. De igual manera, si una alternativa de directivas está vacía, como por ejemplo <wsp:All /> o <wsp:Policy />, entonces la directiva tiene cero aserciones de directivas.

Asociativa

Los operadores wsp:ExactlyOne y wsp:All también son asociativos. Esto significa que, utilizandowsp:ExactlyOne como se define en el Listado 6 (donde <!-- assertion a --> y <!-- assertion b --> son cualquier aserción), la directiva es equivalente a la directiva del Listado 4.

Listado 6.wsp:ExactlyOne que muestra asociación
<wsp:ExactlyOne>
  <!-- assertion a -->
  <wsp:ExactlyOne> <!-- assertion b --> </wsp:ExactlyOne>
</wsp:ExactlyOne>

La directiva equivalente a wsp:ExactlyOne se muestra en el Listado 7 utilizando asociación.

Listado 7. Directiva equivalente
<wsp:ExactlyOne>
  <!-- assertion a --> <!-- assertion b -->
</wsp:ExactlyOne>

Y la directiva que utiliza wsp:All, en el Listado 8 es equivalente a la directiva del Listado 9.

Listado 8.wsp:Allmuestra asociación
<wsp:All>
  <!-- assertion a -->
  <wsp:All> <!-- assertion b --> </wsp:All>
</wsp:All>

La directiva equivalente, que utiliza la asociación de wsp:All, se muestra en el Listado 9.

Listado 9. Política equivalente
<wsp:All>
  <!-- assertion a --> <!-- assertion b -->
</wsp:All>

A continuación verá cómo los dos operadores también son conmutativos.

Commutative

Los operadores wsp:ExactlyOne y wsp:All también son conmutativos. Esto significa que cuando dos o más aserciones de directivas se anidan dentro de cada operador, su orden no importa. Por ejemplo, la instrucción en el Listado 10 que utiliza wsp:All es equivalente a la directiva del Listado 11.

Listado 10.<wsp:All> muestra operadores conmutativos
<wsp:All>
  <!-- assertion a --> <!-- assertion b -->
</wsp:All>

La directiva equivalente a wsp:ExactlyOne se muestra en el Listado 11 utilizando operadores conmutativos.

Listado 11. Instrucción equivalente
<wsp:All>
  <!-- assertion b --> <!-- assertion a -->
</wsp: All>

Lo mismo se aplica al operador wsp:ExactlyOne que se muestra en el Listado 12 y el Listado 13.

Listado 12. wsp:ExactlyOne operador que muestra operadores conmutativos
<wsp:ExactlyOne>
  <!-- assertion a --> <!-- assertion b -->
</wsp:ExactlyOne>

La directiva equivalente, utilizando el operador conmutativo de wsp:ExactlyOne, se muestra en el Listado 13.

Listado 13. Instrucción equivalente
<wsp:ExactlyOne>
  <!-- assertion b --> <!-- assertion a -->
</wsp:ExactlyOne>

A continuación verá cómo los operadores también son distributivos.

Distributivo

Tanto wsp:ExactlyOne como wsp:All son distributivos. A continuación están los ejemplos que muestran esto en el espacio de expresión de directivas (ver el Listado 14).

Listado 14. wsp:All que se distribuye sobre wsp:ExactlyOne, parte 1
<wsp:All>
  <wsp:ExactlyOne>
    <!-- assertion a --> <!-- assertion b -->
  </wsp:ExactlyOne>
</wsp:All>

La directiva equivalente, que distribuye wsp:All sobre wsp:ExactlyOne, se muestra en el Listado 15.

Listado 15.wsp:All se distribuye sobre wsp:ExactlyOne, parte 2
<wsp:ExactlyOne>
  <wsp:All>
    <!-- assertion a -->
  </wsp:All>
  <wsp:All>
    <!-- assertion b -->

  </wsp:All>
</wsp:ExactlyOne>

Y aquí se incluye un ejemplo más complejo, Este es similar a multiplicar (x + a) por (y + z) en que se obtienen cuatro expresiones: xy + xz + ay + az (ver el Listado 16).

Listado 16. wsp:All que se distribuye sobre wsp:ExactlyOne, parte 3
<wsp:All>
  <wsp:ExactlyOne>
    <!-- assertion a --> <!-- assertion b -->
  </wsp:ExactlyOne>
  <wsp:ExactlyOne>

    <!-- assertion c --> <!-- assertion d -->
  </wsp:ExactlyOne>
</wsp:All>

La directiva equivalente, al distribuir wsp:All sobre wsp:ExactlyOne, se muestra en el Listado 17.

Listado 17. wsp:All que se distribuye sobre wsp:ExactlyOne, parte 4
<wsp:ExactlyOne>
  <wsp:All>
    <!-- assertion a --> <!-- assertion c -->
  </wsp:All>
  <wsp:All>

    <!-- assertion a --> <!-- assertion d -->
  </wsp:All>
  <wsp:All>
    <!-- assertion b --> <!-- assertion c -->
  </wsp:All>

  <wsp:All>	
    <!-- assertion b --> <!-- assertion d -->
  </wsp:All>
</wsp:ExactlyOne>

Observe que distribuir wsp:All sobre una wsp:ExactlyOne vacía da como resultado ninguna alternativa (<wsp:ExactlyOne />), porque es casi lo mismo que multiplicarla por cero. Esto también da el mismo resultado que si cualquiera de las expresiones wsp:ExactlyOne en el Listado 15 están vacías: el resultado es una directiva sin alternativas.

Idempotent

Los operadores también son idempotent, lo que significa que todo valor que tenga la propiedad idempotent multiplicada por ese mismo valor permanece sin cambios. Los ejemplos de los Listados18-21 muestran esta propiedad.

Listado 18.wsp:All que muestra idempotence
<wsp:All>
  <wsp:All> <!-- assert a --> <!-- assert b --> </wsp:All>
</wsp:All>

La directiva equivalente, que utiliza la idempotence de wsp:All, se muestra en el Listado 19.

Listado 19. Listado equivalente
<wsp:All>
  <!-- assertion a --> <!-- assertion b -->
</wsp:All>

El Listado 20 y el Listado 21 muestran que wsp:ExactlyOne es idempotent.

Listado 20. wsp:ExactlyOne que muestra idempotence
<wsp:ExactlyOne>
  <wsp:ExactlyOne>
    <!-- assert a --> <!-- assert b -->
  </wsp:ExactlyOne>
</wsp:ExactlyOne>

La directiva equivalente, que utiliza la idempotence de wsp:ExactlyOne, se muestra en el Listado 21.

Listado 21. Equivalent Listado
<wsp:ExactlyOne>
  <!-- assert a --> <!-- assert b --> 
</wsp:ExactlyOne>

Básicamente una wsp:All anidada dentro de un wsp:All, o un wsp:ExactlyOne anidada dentro de un wsp:ExactlyOne, es redundante, lo que significa que puede eliminar una de los operadores wsp:All o wsp:ExactlyOne de la expresión. Es lo mismo que multiplicar lo que sea por 1: el valor no cambia. Las propiedades matemáticas de esto operadores son importantes para entender cuando se aprende sobre manipular y normalizar documentos de directivas que utilizan Apache Neethi en la siguiente sección.


Utilizar Apache Neethi para trabajar con documentos de directivas

El proyecto Apache Neethi es lo que utiliza Axis2 como su representación en tiempo de ejecución de los documentos de directivas. En esta sección usted instalará Apache Neethi; cargará algunos documentos de directivas; normalizará, combinará y los cruzará; y luego verá los documentos de directivas normalizados resultantes. Ahora es un buen momento para descargar el código de muestra de la sección Descargas. Descomprímalo, y lea el archivo readme.

Leer documentos de directivas

Antes de poder hacer algo útil usando WS-Policy, debe poder leer y escribir directivas. A Francis le parece genial. Ansía Cruzar dos documentos de directivas. Ver el Listado 22 para ver el lector de directivas.

Listado 22. Leer un documento de directivas
public static Policy readPolicy(String file){
        Policy policy = null;
        try{
            PolicyReader reader =
                PolicyFactory.getPolicyReader
                    (PolicyFactory.DOM_POLICY_READER);
            FileInputStream fis =
                new FileInputStream(file);
            policy = reader.readPolicy(fis);
        } catch(Exception e) {
            System.out.println("Exception occurred: " + e);
            e.printStackTrace();
        }
        return policy;
    }

Coloque el método readPolicy() en un archivo llamado PolicyUtility.java. Lo utilizará después para leer los archivos de directivas en su experimento con Apache Neethi. Este método simplemente lee un archivo de directivas especificado, lo coloca en una directiva nombrada por objeto, y lo devuelve. A continuación está el redactor de directivas.

Redactar documentos de directivas.

Redactar un documento de directivas le permite visualizar los resultados de sus manipulaciones de directivas. Ver el Listado 23 para ver el código del redactor de directivas.

Listado 23. Redactar un documento de directivas
public static void writePolicy(Policy w, String file){
        try{
            FileOutputStream fos =
                new FileOutputStream(file);

            PolicyWriter writer =
                PolicyFactory.getPolicyWriter
                    (PolicyFactory.StAX_POLICY_WRITER);

            writer.writePolicy(w, fos);
        } catch(Exception e) {
            System.out.println("Exception occurred: " + e);
            e.printStackTrace();
        }
    }

Coloque eso en el mismo archivo de clase que antes: PolicyUtility.java. Este método redacta el contenido de cierto documento de directivas en un nombre de archivo dado. A continuación, utilizará estos dos métodos de utilidad al experimentar con Apache Neethi.

Normalizar un documento de directivas

Cuando se normaliza un documento en Apache Neethi, se ordena en forma normal (no de manera compacta). En el código de muestra que viene con este tutorial (ver Descargas), verá tres archivos: normalize1.xml, normalize2.xml y normalize_output_final.xml. normalize1.xml, en el Listado 24, contiene un documento de directivas que referencia una directiva externa. normalize2.xml, que se muestra en Listado 25, es el documento al que se refiere normalize1.xml.

Listado 24. normalize1.xml
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>

      <wsp:Policy wsu:Id="#myPolicy">
        <sp:UsernameToken /> 
        <sp:SignedParts />
        <sp:EncryptedParts>
          <sp:Body />

        </sp:EncryptedParts>
      </wsp:Policy>

      <sp:TransportBinding>
        <sp:IncludeTimeStamp />
      </sp:TransportBinding>
    </wsp:All>

    <wsp:PolicyReference URI="#myPolicy" />
  </wsp:ExactlyOne>
</wsp:Policy>

La directiva referenciada más arriba, myPolicy, se muestra en el Listado 25.

Listado 25. normalize2.xml
<wsp:Policy wsu:Id="myPolicy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd" >
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:UsernameToken /> 
      <sp:SignedParts />
      <sp:EncryptedParts>

        <sp:Body />
      </sp:EncryptedParts>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

El código para normalizar la directiva del Listado 24 se muestra en el Listado 26.

Listado 26. Normalizar un documento de directivas
import org.apache.ws.policy.Policy;
import org.apache.ws.policy.util.PolicyRegistry;
import org.apache.ws.policy.util.PolicyReader;
import org.apache.ws.policy.util.PolicyWriter;
import org.apache.ws.policy.util.PolicyFactory;
import java.io.FileInputStream;
import java.io.FileOutputStream;

class PolicyUtility{

    public static void main(String argsv[]){
        Policy normalize1 = readPolicy("normalize1.xml");
        Policy normalize2 = readPolicy("normalize2.xml");
        PolicyRegistry pr = new PolicyRegistry();
        pr.register("#myPolicy", normalize2);
        normalize1 = (Policy)normalize1.normalize(pr);
        writePolicy(normalize1, "normalize_output.xml");

El resultado de la normalización se encuentra en normalize_output_final.xml (ver el Listado 27).

Listado 27. El normalize_output_final.xml resultante
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext">
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:UsernameToken>
      </sp:UsernameToken>
      <sp:SignedParts>
      </sp:SignedParts>
      <sp:EncryptedParts>

        <sp:Body>
        </sp:Body>
      </sp:EncryptedParts>
      <sp:TransportBinding>
        <sp:IncludeTimeStamp>
        </sp:IncludeTimeStamp>

      </sp:TransportBinding>
    </wsp:All>
    <wsp:All>
      <sp:UsernameToken xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext">
      </sp:UsernameToken>
      <sp:SignedParts>

      </sp:SignedParts>
      <sp:EncryptedParts>
        <sp:Body>
        </sp:Body>
      </sp:EncryptedParts>
    </wsp:All>

  </wsp:ExactlyOne>
</wsp:Policy>

Si ejecuta el programa siguiendo las instrucciones del archivo readme, el resultado se redacta en normalize_output.xml. Observe cómo PolicyReference en normalize1.xml se reemplaza con la alternativa de directivas en normalize2.xml. Modifique libremente los dos archivos para ver qué resultados obtiene al ejecutar otras normalizaciones. Luego combine dos documentos de directivas

Combinar dos documentos de directivas

La combinación permite que dos documentos de directivas combinen todas las alternativas de políticas de dos archivos individuales. Por ejemplo, si tiene dos archivos, cada uno con dos alternativas de directivas, puede terminar con un archivo con cuatro alternativas de directivas. Si un archivo tiene dos alternativas de directivas y el otro archivo tiene una alternativa de directivas, podría terminar con dos alternativas de directivas. Observe los dos archivos que puede combinar en los Listados 28 y 29.

Listado 28. merge1.xml
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:UsernameToken /> 
      <sp:EncryptedParts>
        <sp:Body />
      </sp:EncryptedParts>
      <sp:TransportBinding>

        <sp:IncludeTimeStamp />
      </sp:TransportBinding>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Puede combinar la directiva anterior, merge1.xml, con la directiva que se muestra en el Listado 29, merge2.xml.

Listado 29. merge2.xml
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:SignedParts />
      <sp:EncryptedParts />
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

La experiencia es la mejor manera de aprender este concepto. Así que el Listado 30 continúa la clase PolicyUtility.java que inició al implementar el código para combinar los dos documentos de directivas que se muestran en los Listados 28 y 29.

Listado 30. Combinar dos documentos de directivas
...
        normalize1 = (Policy)normalize1.normalize(pr);
        writePolicy(normalize1, "normalize_output.xml");

        Policy merge1 = readPolicy("merge1.xml");
        Policy merge2 = readPolicy("merge2.xml");
        merge1 = (Policy)merge1.merge(merge2);
        writePolicy(merge1, "merge_output.xml");
...

Aquí se leen y combinan dos documentos de directivas, y luego el resultado de la combinación se redacta en un archivo (ver Listado 31).

Listado 31. El merge_output_final.xml resultante
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext">
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:UsernameToken>
      </sp:UsernameToken>
      <sp:EncryptedParts>
        <sp:Body>
        </sp:Body>

      </sp:EncryptedParts>
      <sp:TransportBinding>
        <sp:IncludeTimeStamp>
        </sp:IncludeTimeStamp>
      </sp:TransportBinding>
      <sp:SecurityToken>

        <sp:TokenType>sp:X509v3</sp:TokenType>
      </sp:SecurityToken>
      <sp:SignedParts>
      </sp:SignedParts>
      <sp:EncryptedParts>

      </sp:EncryptedParts>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Regrese a los Listados 28 y 29, cada uno con alternativa de directivas, así que el documento resultante contiene una alternativa de directivas con todas las aserciones de directivas en ambas alternativas de directivas copiadas a una nueva. Mire los resultados en merge_output_final.xml, que se muestra en el Listado 31. Observe que todas las aserciones de directivas de la alternativa de directivas única de merge1.xml y todas las aserciones de directivas de la alternativa de directivas única merge2.xml se combinan en merge_output_final.xml para formar una única alternativa de directivas combinada.

Directivas y firmas

Debido a que las directivas contienen información crítica sobre cómo interactúan los servicios de web entre ellos, siempre asegúrese de que la directiva que recibió proviene en realidad de la entidad de la cual la solicitó. Es buena práctica firmar sus directivas para evitar el spoofing.

Cruzar dos documentos de directivas

La intersección es un concepto aún más importante. Básicamente, si dos servicios web van a interactuar, querrán hacerlo utilizando la alternativa de directivas que ambos soportan. Los servicios web deben cruzarse con los documentos de directivas del otro. El resultado es una combinación de las alternativas de directivas que coinciden. A Francis le gusta la idea así que, al llamar a otros servicios web con su código de cliente, puede cruzar las directivas disponibles del Daily Moon con las políticas del servicio web con el que desea interactuar (ver el Listado 32).

Listado 32. intersect1.xml
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:UsernameToken /> 
      <sp:SignedParts />
      <sp:EncryptedParts>
        <sp:Body />
      </sp:EncryptedParts>

      <sp:TransportBinding>
        <sp:IncludeTimeStamp />
      </sp:TransportBinding>
    </wsp:All>
    <wsp:All>
      <sp:SecurityToken>

        <sp:TokenType>sp:X509v3</sp:TokenType>
      </sp:SecurityToken>
      <sp:UsernameToken /> 
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Puede cruzar la directiva anterior, intersect1.xml, con la directiva que se muestra en el Listado 33, intersect2.xml.

Listado 33. intersect2.xml
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" >

  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:SignedParts />
      <sp:EncryptedParts />
    </wsp:All>
    <wsp:All>
      <sp:SecurityToken>

        <sp:TokenType>sp:X509v3</sp:TokenType>
      </sp:SecurityToken>
      <sp:UsernameToken /> 
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Observe el código para hacer la intersección de intersect1.xml e intersect2.xml que ocurre en el Listado 34.

Listado 34. Cruzar dos documentos de directivas
...
        merge1 = (Policy)merge1.merge(merge2).normalize();
        writePolicy(merge1, "merge_output.xml");

        Policy intersect1 = readPolicy("intersect1.xml");
        Policy intersect2 = readPolicy("intersect2.xml");
        intersect1 = (Policy)intersect1.merge(intersect2);
        writePolicy(intersect1, "intersect_output.xml");
...

Aquí, dos documentos de directivas se leen y cruzan, y luego el resultado de la intersección se escribe en un archivo. Observe los dos archivos en los Listados 32 y 33. Cada uno contiene dos alternativas de directivas, pero solo uno de cada archivo se combina (con una coincidencia, en este ejemplo). Ahora mire los resultados reales en merge_output_final.xml, que se muestra en el Listado 35.

Listado 35. El merge_output_final.xml resultante
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SecurityToken xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext">
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:UsernameToken>
      </sp:UsernameToken>
      <sp:SecurityToken>
        <sp:TokenType>sp:X509v3</sp:TokenType>

      </sp:SecurityToken>
      <sp:UsernameToken>
      </sp:UsernameToken>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

Observe que las alternativas de directivas coincidentes en cada archivo (las segundas alternativas de directivas en intersect1.xml e intersect2.xml) están fundamentalmente combinadas en la alternativa de directivas que se muestra en merge_output_final.xml. Eso completa su trabajo con Apache Neethi.

A continuación, explore el trabajar con los documentos de directivas en WSDL.


Trabajar con documentos de directivas en WSDL

La especificación WS-PolicyAttachment detalla cómo se adjuntan las directivas a los enlaces y fundamentalmente es el pegamento que hace que un servicio web respete una directiva. Esta sección cubre los objetivos de la especificación WS-PolicyAttachment y cómo le permite adjuntar directivas a su servicio web.

WS-PolicyAttachment

El objetivo de la especificación WS-PolicyAttachment es definir un medio para que los desarrolladores reverencien directivas de definiciones WSDL. También existen detalles en la especificación para relacionar directivas con entidades UDDI, que no se cubren en este tutorial. Ver la sección Recursos para obtener un enlace a la especificación WS-PolicyAttachment completa. El resto de esta sección muestra cómo seguir la especificación WS-PolicyAttachment para referenciar el documento de directivas Daily Moon a WSDL. A Gene le emociona esta tarea así que puede poner en marcha los servicios web en el Daily Moon lo más rápido posible.

Requerir WS-Policy

Hay una construcción para aplicar su WSDL para usar y referencias directivas. El Listado 36 muestra un ejemplo.

Listado 36. Requerir directivas en su WSDL
<wsdl:definitions...>

  <wsp:UsingPolicy wsdl:Required="true" />
...
</wsdl:definitions >

A continuación, agrega directivas alineadas con el WSDL.

Dónde colocar directivas

Coloque las directivas justo después de la línea de requisito wsp:UsingPolicy. Para el Daily Moon, puede hacer como hizo Gene, lo que se muestra en el Listado 37.

Listado 37. Definir directivas en WSDL
<wsdl:definitions 
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext"
xmlns:wsu=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd
...
>

  <wsp:UsingPolicy wsdl:Required="true" />
  <wsp:Policy wsu:Id="myPolicy">
    <wsp:ExactlyOne>

      <wsp:All>
        <sp:SecurityToken>
          <sp:TokenType>sp:X509v3</sp:TokenType>
        </sp:SecurityToken>
        <sp:UsernameToken /> 
        <sp:SignedParts />

        <sp:EncryptedParts>
          <sp:Body />
        </sp:EncryptedParts>
        <sp:TransportBinding>
          <sp:IncludeTimeStamp />
        </sp:TransportBinding>

      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
...
</wsdl:definitions >

¡Listo! La directiva está dentro del WSDL. Ahora solo tiene que relacionarlo con un enlace, lo que puede hacer a continuación.

Adjuntar directivas a enlaces

Ahora que se ha redactado una directiva, no será útil a menos que la asocie a un enlace de puerto. Si se definió un enlace, el Listado 38 le muestra cómo adjuntar la directiva del Daily Moon al enlace.

Listado 38. Relacionar una directiva a un enlace: hacer cumplir la directiva
<wsdl:definitions 
...
>

  <wsp:UsingPolicy wsdl:Required="true" />
  <wsp:Policy wsu:Id="myPolicy">
...
  </wsp:Policy>
  <wsdl:binding name="myBinding"
                type="tns:myPortType">

    <soap:binding 
      transport="http://schemas.xmlsoap.org/soap/http"
      style="document" />
    <wsp:PolicyReference URI="#myPolicy"
                         wsdl:required="true" />
    <wsdl:operation name="myOperation" >
...
    </wsdl:operation>
  </wsdl:binding>

</wsdl:definitions >

Observe la manera en que Gene redactó el WSDL. En el enlace de puertos, observe la etiqueta wsp:PolicyReference que se refiere a la directiva, myPolicy. Esta etiqueta especifica que la operación del servicio web (myOperation) que se une (utilizando myBinding) al portType especificado (myPortType) debe hacer que todos los mensajes entrantes respeten la directiva, como se define en la directiva con wsu:Id="#myPolicy". ¡Eso es todo! Si Axis2actuar con el servicio web del Daily Moon No podría realizar operaciones exitosas con él a menos que respete todas las aserciones de una de las alternativas a la directiva.


Resumen

Para que los servicios web sean verdaderamente útiles en el entorno empresarial, deben tener una configuración y directivas de seguridad adecuadas. WS-Policy resuelve este problema permitiendo que las definiciones de directivas se unan a los servicios web. Estas definiciones de directivas definen la manera en que ocurrirá la operación, y pueden solicitar varias cosas para contar con un entorno más seguro para operar.

Al hacer cumplir cierto nivel de cifrado y firmas digitales, puede proteger la información durante su transporte y limitar el acceso a organizaciones o individuos autorizados, y luego verificar que esa información no se haya modificado en tránsito. Hacer que la directiva requiera una marca de tiempo (y firmarla) le permite evitar que los mensajes sean capturados y reproducidos.

En este tutorial, el personal del Daily Moon aplicó seguridad para los servicios web que creó y protegió en partes anteriores de esta serie. A continuación, en la Parte 6, aplicarán WS-I, o WS-Interoperability, a los servicios web.


Descargar

DescripciónNombretamaño
Part 5 source codewspolicycode.zip5KB

Recursos

Aprender

Obtener los productos y tecnologías

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=SOA y servicios web
ArticleID=660824
ArticleTitle=Comprender las especificaciones de servicios web, Parte 5: WS-Policy
publish-date=08082011