Envío de señales de titularidad SAML autoemitidas utilizando las API WSS

Puede crear señales SAML autoemitidas con el método de confirmación de sujetos bearer (portador) y, a continuación, enviar esas señales con mensajes de solicitud de servicios web utilizando la API Java™ para el modelo de programación de servicios web basados en XML (JAX-WS) y las API de seguridad de servicios web (API de WSS).

Antes de empezar

En esta tarea se presupone que está familiarizado con el modelo de programación JAX-WS, las interfaces de las API de WSS, los conceptos de SAML y el uso de conjuntos de políticas para configurar y administrar los valores de servicios web.

Acerca de esta tarea

Puede crear el cliente de servicios web para utilizar señales de SAML con el método de confirmación de sujeto bearer en los mensajes de solicitud SOAP utilizando las interfaces de programación de seguridad de servicios Web. El uso de interfaces de programación en un cliente de servicios web para especificar el uso de señales SAML con la confirmación de sujeto bearer es un enfoque alternativo al uso de los conjuntos de políticas y las configuraciones de enlace.

Puede crear una señal SAML autoemitida y, a continuación, enviar la señal SAML en los mensajes de solicitud de servicios web de un cliente de servicios web. El cliente de aplicaciones de servicios web que se utiliza en esta tarea es una versión modificada del código de cliente contenido en la aplicación de ejemplo JaxWSServicesSamples que está disponible para la descarga. Los fragmentos de código del ejemplo se describen en el apartado sobre procedimiento, aunque se proporciona un ejemplo de cliente de servicios Web completo y listo para utilizarse en el apartado de ejemplo.

Procedimiento

  1. Identifique y obtenga el cliente de servicios web que desea utilizar para invocar un proveedor de servicios web.

    Utilice este cliente para insertar las señales SAML en los mensajes de solicitud SOAP mediante programación con las API de WSS.

    El cliente de servicios web que se utiliza en este procedimiento es una versión modificada del código de cliente contenido en la aplicación de ejemplo de servicios web JaxWSServicesSamples.

    Para obtener y modificar el cliente de servicios web de ejemplo a fin de añadir la API de seguridad de servicios Web para pasar señales SAML en los mensajes de solicitud SOAP mediante programación con las API de WSS, siga estos pasos:

    1. Descargue la aplicación de ejemplo JaxWSServicesSamples. El ejemplo JaxWSServicesSamples no está instalado de forma predeterminada.
    2. Obtenga el código de cliente de JaxWSServicesSamples.

      En el ejemplo, este procedimiento utiliza una versión modificada del ejemplo de cliente ligero Echo que se incluye en el ejemplo JaxWSServicesSamples. El archivo de ejemplo de cliente ligero Echo de servicios web, SampleClient.java, se encuentra en el directorio src\SampleClientSei\src\com\ibm\was\wssample\sei\cli. El archivo de clase de ejemplo está incluido en el archivo WSSampleClientSei.jar.

      La aplicación empresarial JaxWSServicesSamples.ear y los archivos Java (JAR) se encuentran en el directorio installableApps en la aplicación de ejemplo JaxWSServicesSamples.

    3. Despliegue el archivo JaxWSServicesSamples.ear en el servidor de aplicaciones. Tras desplegar el archivo JaxWSServicesSamples.ear, ya está preparado para probar el código de cliente de servicios web de ejemplo en la aplicación de ejemplo.

    En lugar de utilizar el ejemplo de cliente de servicios web, puede optar por añadir los fragmentos de código para pasar señales SAML en los mensajes de solicitud SOAP mediante programación con las API de WSS en su propia aplicación cliente de servicios web. El ejemplo de este procedimiento utiliza un cliente ligero de servicios Web JAX-WS; no obstante, también puede utilizar un cliente gestionado.

  2. Adjunte el conjunto de políticas predeterminado SAML20 Bearer WSHTTPS al proveedor de servicios web. Este conjunto de políticas se utiliza para proteger los mensajes mediante transporte HTTPS. Consulte la información sobre la configuración de enlaces de cliente y proveedor para la señal SAML bearer para obtener detalles sobre cómo adjuntar el conjunto de políticas predeterminado SAML20 Bearer WSHTTPS al proveedor de servicios Web. El ejemplo de este procedimiento utiliza señales SAML autoemitidas. Cuando se configuran enlaces de proveedor, la configuración de almacén de confianza y el certificado deben coincidir con la clave firmante de la señal autoemitida.
  3. Asigne los enlaces generales predeterminados del ejemplo SAML Bearer Provider al proveedor de servicios web. Consulte la información sobre configuración de enlaces de cliente y proveedor para la señal SAML bearer a fin de obtener detalles sobre la asignación de los enlaces generales predeterminados del ejemplo SAML Bearer Provider a la aplicación de servicios web.
  4. Cree la señal SAML autoemitida. El fragmento de código siguiente ilustra la creación de la señal SAML:
    // Crear la señal SAML.
    HashMap<Object, Object> map = new HashMap<Object, Object>();
    map.put(SamlConstants.CONFIRMATION_METHOD, "Bearer");
    map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
    map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
    map.put(SamlConstants.SIGNATURE_REQUIRED, "true");			
    SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);				            
    callbackHandler.setWSSGenerationContextForTrustClient(gencont);
    SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");
    
    System.out.println("SAMLToken id = " + samlToken.getId());
    1. Utilice el método CallService() para especificar los parámetros de configuración de seguridad de servicios Web que son necesarios para invocar un proveedor de servicios web de destino utilizando una señal SAML autoemitida.

      El método CallService() establece los parámetros de configuración necesarios para el entorno de ejecución de seguridad de servicios Web mediante la propiedad personalizada com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext para generar una señal SAML autoemitida.

      Consulte la información sobre cómo configurar una señal SAML durante la creación de señales para obtener más información sobre cómo se pueden especificar las propiedades de configuración para controlar cómo se configura la señal.

    2. Añada el archivo JAR del cliente ligero para JAX-WS a la variable class. Añada el archivo raíz_servidor_aplicaciones/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar a la variable class. Consulte la información sobre cómo probar los clientes habilitados para servicios web para obtener más detalles sobre la adición de este archivo JAR a la variable class.
    3. Utilice el método newSecurityToken de WSSFactory para especificar cómo crear la señal SAML.
      Especifique el método siguiente para crear la señal SAML:
      WSSFactory  newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml")
      La creación de una señal SAML exige el permiso de seguridad Java wssapi.SAMLTokenFactory.newSAMLToken. Utilice PolicyTool para añadir la sentencia de política siguiente al archivo de política de seguridad Java o al archivo was.policy de aplicación:
      permission java.security.SecurityPermission "wssapi.SAMLTokenFactory.newSAMLToken

      El parámetro SAMLToken.class especifica el tipo de señal de seguridad que se debe crear.

      El objeto callbackHandler contiene parámetros que definen las características de la señal SAML que va a crear. Este objeto apunta a un objeto SAMLGenerateCallbackHandler que especifica los parámetros de configuración que se describen en la tabla siguiente:
      Tabla 1. Propiedades de SAMLGenerateCallbackHandler. En esta tabla se describen los parámetros de configuración para el objeto SAMLGenerateCallbackHandler que utilizan el método de confirmación bearer.
      Propiedad Descripción Required
      SamlConstants.CONFIRMATION_METHOD Especifica que se utiliza el método de confirmación Bearer.
      SamlConstants.TOKEN_TYPE

      Utiliza el valor constante, WSSConstants.SAML.SAML20_VALUE_TYPE, para especificar un tipo de señal SAML 2.0.

      Cuando un cliente de servicios web tiene adjuntos de conjunto de políticas, el entorno de ejecución de seguridad de servicios Web no utiliza esta propiedad. En esta situación de ejemplo, especifique el tipo de valor de señal mediante el atributo valueType de la configuración de enlace tokenGenerator.

      El ejemplo de este procedimiento utiliza una señal SAML 2.0; sin embargo, también puede utilizar el valor WSSConstants.SAML.SAML11_VALUE_TYPE.

      SamlConstants.SAML_NAME_IDENTIFIER

      Especifica una identidad de usuario como puede ser myname como valor de NameID en la señal SAML.

      Si no define este parámetro cuando se utiliza el cliente ligero para JAX-WS, el valor de NameID no contiene información útil.

      Si va a utilizar un cliente gestionado de servicios web, como una aplicación Java 2 Platform, Enterprise Edition (Java) que realice una invocación de solicitud de servicios web, el entorno de ejecución de servicios Web intenta extraer la información de seguridad del usuario del contexto de seguridad. De forma similar, si no define este parámetro para un cliente de servicios web gestionado, el valor de NameID contiene un identificador de nombre UNAUTHENTICATED.

      Esta propiedad no se utiliza si el cliente de servicios web tiene adjuntos de conjunto de políticas. Consulte la información sobre cómo enviar señales SAML para obtener más detalles sobre el envío de la identidad y los atributos de las señales SAML.

      No
      SamlConstants.SIGNATURE_REQUIRED

      Especifica si el emisor es obligatorio para firmar digitalmente la señal símbolo SAML.

      El valor true especifica que el emisor es obligatorio para firmar digitalmente la señal SAML. Este valor es el predeterminado.

      No
      El parámetro system.wss.generate.saml especifica el LoginModule Java Authentication and Authorization Service (JAAS) que se utiliza para crear la señal SAML. Debe especificar una propiedad de JVM para definir un archivo de configuración JAAS que contenga la configuración de inicio de sesión JAAS necesaria; por ejemplo:
      -Djava.security.auth.login.config=raíz_perfil/properties/wsjaas_client.conf 
      Como alternativa, puede especificar un archivo de configuración de inicio de sesión JAAS estableciendo una propiedad del sistema Java en el código de cliente de ejemplo; por ejemplo:
      System.setProperty("java.security.auth.login.config", "raíz_perfil/properties/wsjaas_client.conf ");
    4. Obtenga el identificador de la señal SAML creada.
      Utilice la siguiente sentencia como prueba simple para la señal SAML que ha creado:
      System.out.println("SAMLToken id = " + samlToken.getId())
  5. Añada la señal SAML a la cabecera de seguridad SOAP de los mensajes de solicitud de servicios Web.
    1. Inicialice el cliente de servicios web y configure las propiedades SOAPAction. El fragmento de código siguiente ilustra estas acciones:
      // Inicializar cliente de servicios web
      EchoService12PortProxy echo = new EchoService12PortProxy();
      echo._getDescriptor().setEndpoint(endpointURL);
      
      // Configurar propiedades SOAPAction 
      BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
      Map<String, Object> requestContext = bp.getRequestContext();
      requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
      requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY,	Boolean.TRUE);
      requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");
      			
    2. Inicialice WSSGenerationContext. El siguiente fragmento de código ilustra el uso de la interfaz WSSGenerationContext para inicializar un contexto de generación y que pueda insertar la SAMLToken en un mensaje de solicitud de servicios web:
      // Inicializar WSSGenerationContext
      WSSGenerationContext gencont = factory.newWSSGenerationContext();
      gencont.add(samlToken);	
      Concretamente, la llamada al método gencont.add(samlToken) especifica que se coloque la señal SAML en un mensaje de solicitud. Utilice PolicyTool para añadir la sentencia de política siguiente al archivo de política de seguridad Java o al archivo was.policy de aplicación:
       “permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
    3. Añada el elemento timestamp en la cabecera de seguridad de mensajes SOAP. El conjunto de políticas predeterminado SAML20 Bearer WSHTTPS exige solicitudes de servicios web y mensajes de respuesta para transportar un elemento timestamp en la cabecera de seguridad de mensajes SOAP. En el siguiente fragmento de código, el método factory.newWSSTimestamp() genera la indicación de fecha y hora y la llamada de método gencont.add(timestamp) especifica la indicación de fecha y hora que se debe colocar en un mensaje de solicitud:
      // Añadir una indicación de fecha y hora al mensaje de solicitud. 
      WSSTimestamp timestamp = factory.newWSSTimestamp();
      gencont.add(timestamp);
      	        
      gencont.process(requestContext);
    4. Adjunte el objeto WSSGenerationContext al objeto RequestContext de servicios Web. El objeto WSSGenerationContext ahora contiene toda la información de seguridad necesaria para dar formato a un mensaje de solicitud. La llamada al método gencont.process(requestContext) adjunta el objeto WSSGenerationContext al objeto RequestContext de servicios Web para permitir que el entorno de ejecución de seguridad de servicios Web dé formato a la cabecera de seguridad SOAP necesaria; por ejemplo:
      // Adjunta el objeto WSSGenerationContext al objeto RequestContext de servicios Web. 
      gencont.process(requestContext);
    5. Especifique la protección de mensajes de nivel de transporte SSL utilizando propiedades de JVM.
      El conjunto de políticas predeterminado SAML20 Bearer WSHTTPS exige la protección de mensajes de nivel de transporte mediante SSL. Especifique la protección de mensajes de nivel de transporte utilizando la propiedad de JVM siguiente:
      -Dcom.ibm.SSL.ConfigURL=file:raíz_perfil\properties\ssl.client.props
      Como alternativa, puede definir el archivo de configuración SSL para que utilice una propiedad del sistema Java en el código de cliente de ejemplo; por ejemplo:
      System.setProperty("com.ibm.SSL.ConfigURL", "file:raíz_perfil/properties/ssl.client.props");

Resultados

Ha creado una señal SAML autoemitida con el método de confirmación de temas de titularidad y, a continuación, se ha enviado esta señal con mensajes de solicitud de servicios web mediante el modelo de programación JAX-WS y las API de WSS.

Ejemplo

El código de ejemplo siguiente es una aplicación de cliente de servicios web que muestra cómo crear una señal SAML autoemitida y enviar dicha señal SAML en los mensajes de solicitud de servicios web. Si su situación de uso exige señales SAML, pero no exige que la aplicación pase señales SAML utilizando mensajes de servicios web, sólo tiene que utilizar la primera parte del código de ejemplo siguiente, hasta la sección // Inicializar cliente de servicios web.

/**
 * El código fuente siguiente es código de ejemplo creado por IBM Corporation.
 * Este código de ejemplo se proporciona exclusivamente como ayuda para utilizar
 * la tecnología.  El código se proporciona 'TAL CUAL', sin garantía ni condición de
 * ningún tipo.  IBM no se hará responsable de los daños derivados del uso del
 * código de ejemplo, aunque IBM haya advertido de la posibilidad de tales daños.
 */

package com.ibm.was.wssample.sei.cli;

import com.ibm.was.wssample.sei.echo.EchoService12PortProxy;
import com.ibm.was.wssample.sei.echo.EchoStringInput;

import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;

import java.util.Map;
import java.util.HashMap;

import javax.xml.ws.BindingProvider;

/**
 * Punto de entrada principal de
 * punto de entrada principal de ejemplo JAR de cliente ligero
 * y clase de trabajo para comunicarse con los servicios
 */
public class SampleClient {

  private String urlHost = "localhost";
  private String urlPort = "9443";
  private static final String CONTEXT_BASE = "/WSSampleSei/";
  private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
  private String message = "HELLO";
  private String uriString = "https://" + urlHost + ":" + urlPort;
  private String endpointURL = uriString + ECHO_CONTEXT12;
  private String input = message;

  /**
   * main()
   * 
   * consulte printusage() para conocer los argumentos de línea de mandatos
   * 
   * @param args
   */
  public static void main(String[] args) {
    SampleClient sample = new SampleClient();
    sample.CallService();
  }

  /**
   * Los CallService Parms ya se han leído. Ahora se debe llamar a las clases de proxy de servicio.
   * 
   */
  void CallService() {
    String response = "ERROR!:";
             try {
      System.setProperty("java.security.auth.login.config", "raíz_perfil/properties/wsjaas_client.conf ");
      System.setProperty("com.ibm.SSL.ConfigURL", "file:raíz_perfil/properties/ssl.client.props");

      // Inicializar el objeto WSSFactory
      WSSFactory factory = WSSFactory.getInstance();
      // Inicializar WSSGenerationContext
      WSSGenerationContext gencont = factory.newWSSGenerationContext();
      // Inicializar la configuración del emisor de SAML mediante propiedades personalizadas
      HashMap<Object, Object> customProps = new HashMap<Object,Object>();

      customProps.put(SamlConstants.ISSUER_URI_PROP, "example.com");
      customProps.put(SamlConstants.TTL_PROP, "3600000");
      customProps.put(SamlConstants.KS_PATH_PROP, "keystores/saml-provider.jceks");
      customProps.put(SamlConstants.KS_TYPE_PROP, "JCEKS");
      customProps.put(SamlConstants.KS_PW_PROP, "{xor}LCswLTovPiws");
      customProps.put(SamlConstants.KEY_ALIAS_PROP, "samlissuer");
      customProps.put(SamlConstants.KEY_NAME_PROP, "CN=SAMLIssuer, O=EXAMPLE");
      customProps.put(SamlConstants.KEY_PW_PROP, "{xor}NDomLz4sLA==");
      customProps.put(SamlConstants.TS_PATH_PROP, "keystores/saml-provider.jceks");
      customProps.put(SamlConstants.TS_TYPE_PROP, "JCEKS");
      customProps.put(SamlConstants.TS_PW_PROP, "{xor}LCswLTovPiws");
      gencont.add(customProps); //Añadir propiedades personalizadas

      // Crear SAMLToken
      HashMap<Object, Object> map = new HashMap<Object, Object>();
      map.put(SamlConstants.CONFIRMATION_METHOD, "Bearer");
      map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
      map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
      map.put(SamlConstants.SIGNATURE_REQUIRED, "true");
      SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);

      SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");

      System.out.println("SAMLToken id = " + samlToken.getId());

      // Inicializar cliente de servicios web
      EchoService12PortProxy echo = new EchoService12PortProxy();
      echo._getDescriptor().setEndpoint(endpointURL);

      // Configurar propiedades SOAPAction 
      BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
      Map<String, Object> requestContext = bp.getRequestContext();
      requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
      requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY,	Boolean.TRUE);
      requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");

      gencont.add(samlToken);

      // Añadir indicación de fecha y hora
      WSSTimestamp timestamp = factory.newWSSTimestamp();
      gencont.add(timestamp);

      gencont.process(requestContext);

      // Crear el objeto de entrada
      EchoStringInput echoParm = 
        new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
      echoParm.setEchoInput(input);
      System.out.println(">> CLIENT: SEI Echo to " + endpointURL);

      // Preparar para la consumición de indicación de fecha y hora en mensaje de respuesta.
      WSSConsumingContext concont = factory.newWSSConsumingContext();
      concont.add(WSSConsumingContext.TIMESTAMP); 
      concont.process(requestContext);

      // Llamar al servicio
      response = echo.echoOperation(echoParm).getEchoResponse();

      System.out.println(">> CLIENT: SEI Echo invocation complete.");
      System.out.println(">> CLIENT: SEI Echo response is: " + response);
    } catch(Exception e) {
      System.out.println(">> CLIENT: ERROR: SEI Echo EXCEPTION.");
      e.printStackTrace();
    }
  }
}
Cuando este ejemplo de aplicación de cliente de servicios web se ejecute correctamente, recibirá mensajes como los siguientes:
SAMLToken id = _191EBC44865015D9AB1270745072344
Recuperando documento en 'file:raíz_perfil/.../wsdl/'.
>> CLIENT: SEI Echo to https://localhost:9443/WSSampleSei/EchoService12
>> CLIENT: SEI Echo invocation complete.
>> CLIENT: SEI Echo response is: SOAP12==>>HELLO

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_configsamlbearer_usingwssapi
File name: twbs_configsamlbearer_usingwssapi.html