Puede solicitar una señal de autenticación de un Servicio de señales de seguridad (STS) externo y, a continuación, enviar la señal con mensajes de solicitud de servicio 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), con protección de nivel de mensajes o transporte.
Antes de empezar
En esta tarea se presupone que está familiarizado con el modelo de programación JAX-WS, las interfaces API de WSS, los módulos de inicio de sesión de señal de seguridad genérico de servicio web de WebSphere, la protección de transporte SSL, la protección de nivel de mensaje y el uso de conjuntos de políticas para configurar y administrar valores de servicios web.
Acerca de esta tarea
La aplicación cliente 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. Ejemplos de código del ejemplo se describen en el procedimiento, y se proporciona un completo y listo ejemplo de cliente de servicios web.
Complete los pasos siguientes para solicitar una señal de autenticación de portador SAML desde un STS externo y enviar la señal:
Procedimiento
- Identifique y obtenga el cliente de servicios web que desea utilizar para
invocar un proveedor de servicios web. Utilice este cliente para solicitar e insertar señales de autenticación en los mensajes de solicitud SOAP de forma programática mediante API de WSS. El cliente de servicio 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 servicio JaxWSServicesSamples.
Complete los pasos siguientes para obtener y modificar el cliente de servicio web de ejemplo a fin de añadir la API de seguridad de servicios web para pasar una señal de seguridad en el mensaje de solicitud SOAP mediante programación con las api de WSS:
- Descargue la aplicación de ejemplo JaxWSServicesSamples. El ejemplo JaxWSServicesSamples no está instalado de forma predeterminada.
- 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 servicio 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.
- 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 servicio
web de ejemplo en la aplicación de ejemplo.
En lugar de utilizar PolicySet para la protección del ejemplo de cliente de servicio web, puede optar por añadir los fragmentos de código para pasar señales de autenticación en el mensaje de solicitud SOAP mediante programación con las API de WSS en su propia aplicación cliente de servicio web. El ejemplo de este procedimiento utiliza un cliente
ligero de servicios web JAX-WS; no obstante, también puede utilizar un cliente gestionado.
- Adjunte el conjunto de políticas predeterminadas WSHTTPS de portador SAML11 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
SAML11 Bearer WSHTTPS al proveedor de servicios web.
- 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.
- Compruebe que las propiedades personalizadas trustStoreType, trustStorePassword y trustStorePath se corresponden con el almacén de confianza que contiene el certificado de firmante STS. Complete los pasos siguientes mediante la consola administrativa:
- Pulse .
- Pulse con_saml11token en la tabla Señales de autenticación.
- Pulse Manejador de retorno de llamada.
- En la sección Propiedades personalizadas, compruebe que las propiedades personalizadas trustStoreType, trustStorePassword y trustStorePath se corresponden con el almacén de confianza que contiene el certificado de firmante STS.
- Si está utilizando la protección de nivel de transporte SSL para proteger la solicitud de servicios web o la solicitud WS-Trust, utilice la propiedad siguiente de la máquina virtual Java (JVM) para establecer la configuración SSL.
-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:
System.setProperty("com.ibm.SSL.ConfigURL", "file:raíz_perfil/properties/ssl.client.props");
- Añada el archivo JAR del cliente ligero JAX-WS a la vía de acceso de clases: raíz_servidor_aplic/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar. 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.
- Solicite la señal de authentication de un STS externo. El fragmento de código siguiente ilustra cómo solicitar la señal de autenticación que debe utilizarse con el módulo de inicio de sesión SecurityToken genérico de WebSphere y se presupone que un STS externo está configurado para aceptar una señal Username como señal de autenticación, y para emitir una señal SAML 1.1.
//SecurityToken de solicitud de STS externo:
WSSFactory factory = WSSFactory.getInstance();
//URL de STS que emite la señal solicitada
String STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
//Punto final de servicios web que recibe la señal emitida
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
//Empezar código de ejemplo 1 (utilizando la emisión de WS-Trust para solicitar la señal del
//STS en el que se envía la señal de autenticación por la cabecera WS-Security):
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//La propiedad siguientes especifica que la solicitud ws-trust sea conforme
//con la especificación WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//Esta solicitud se realiza con la emisión WS-TRust solamente (sin el uso de
//la validación de WS-Trust)
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Crear el objeto de contexto de la solicitud WS-Trust:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Utilizar la autenticación de solicitud de confianza
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Fin del código de ejemplo 1.
//Empezar código de ejemplo 2 (mediante la validación WS-Trust para solicitar una señal
//intercambiando una señal en el sujeto RunAs).
//Si el cliente de servicio web tiene el asunto RunAs, por ejemplo un
//servidor intermedio autenticado actúa como cliente para invocar al
//servicio descendente, puede programar el cliente para utilizar la señal del
//sujeto RunAs para intercambiar con el STS mediante la validación WS-Trust.
//Para hacerlo, sustituya el código de ejemplo 1 con lo siguiente:
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//Esta solicitud se realiza con WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//añada la línea siguiente si no desea el repliegue de la emisión WS-Trust si
//el intercambio de señales falla.
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY, "true");
//añada la línea de texto siguiente para especificar el tipo de señal en el sujeto RunAs que
//se utilizará para intercambiar la señal solicitada. Por ejemplo, utilice
//la señal LTPA para intercambiar una señal SAML. Si la señal intercambiada
//en el sujeto RunAs tiene el mismo tipo de valor que la señal solicitada,
//el valor IssuedTokenConfigConstants.USE_TOKEN no será necesario.
cbackMap1.put(IssuedTokenConfigConstants.USE_TOKEN, LTPAToken.ValueType);
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Los códigos siguientes se añaden si la señal de autenticación de la cabecera ws-security
//o la protección de seguridad de nivel de mensaje son necesarias. Si no hay
//ninguna protección de nivel de mensaje ni señal de autenticación adicional para la
//validación WS-Trust, no cree el objeto de contexto que se muestra a continuación.
//Objeto de contexto de la solicitud WS-Trust:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Utilizar la autenticación de solicitud de confianza
UNTGenerateCallbackHandler utCallbackHandler =
new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Fin del código de ejemplo 2.
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
//El siguiente paso para establecer ValueType es necesario..
//El parámetro siempre es el QName del valueType de la señal solicitada.
//QName de SAML1.1:
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//Incluye definiciones QName para SAML11, SAML20, TAM
//y la señal de tíquet Pass.
//QName de SAML 2.0:
QName Saml20ValueType = new QName(WSSConstants.SAML.SAML20_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//QName de la señal TAM:
QName TamValueType = new QName("http://ibm.com/2004/01/itfim/ivcred");
//QName de la señal PassTicket:
QName PassTicketValueType = new QName("http://docs.oasis-open.org/wss/
2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
//Puede utilizar la interfaz de señal para obtener el QName de ValueType de señal de
//todas las demás señales. Por ejemplo, el QName de una señal de Username es //UsernameToken.ValueType.
El objeto GenericIssuedTokenGenerateCallbackHandler contiene parámetros que definen las características de la señal de seguridad que está solicitando, así como otros parámetros necesarios para alcanzar el STS y para obtener la señal de seguridad. El objeto GenericIssuedTokenGenerateCallbackHandler especifica los parámetros de configuración que se describen en la tabla siguiente:
Tabla 1. Propiedades de GenericIssuedTokenGenerateCallbackHandler. En esta tabla se describen los parámetros de configuración del objeto GenericIssuedTokenGenerateCallbackHandler
y se especifica si la propiedad es necesaria o no. Propiedad |
Descripción |
Required |
IssuedTokenConfigConstants.STS_ADDRESS |
Especifica la dirección http del STS. Cuando la comunicación con el STS está protegida con SSL, debe establecer la propiedad -Dcom.ibm.SSL.ConfigURL. La conexión SSL con el STS se indica con un prefijo de direcciones https://.
|
Sí |
IssuedTokenConfigConstants.APPLIES_TO |
Especifica la dirección de servicio de destino para la que desea utilizar la señal. |
No |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
Especifica si se debe solicitar un único símbolo del STS que esté incluido en un elemento RequestSecurityToken (RST) o varios símbolos en una colección de elementos RST que están incluidos en un solo elemento RequestSecurityTokenCollection (RSTC). El comportamiento predeterminado es solicitar una señal simple que está incluida en un elemento RequestSecurityToken (RST) del STS.
La especificación de un valor true para esta propiedad indica una solicitud de varios símbolos en una colección de elementos RST que están incluidos en un solo elemento RequestSecurityTokenCollection (RSTC) del STS.
El valor predeterminado es false.
|
No |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
Especifica el espacio de nombres WS-Trust que se incluye en la solicitud WS-Trust. El valor predeterminado es
WSTrust 1.3.
|
No |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
Especifique si desea que WS-Security utilice la señal del sujeto RunAs para intercambiar la señal solicitada primero utilizando la validación WS-Trust. Si se establece en false, WS-Security utilizará la emisión de WS-Trust para solicitar la señal. El valor predeterminado es true.
|
No |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
Especifique si no desea que WS-Security utilice la emisión de WS-Trust para la señal solicitada si el intercambio de señales falla. El valor predeterminado es false.
|
No |
IssuedTokenConfigConstants.USE_TOKEN |
Utilice este valor para elegir una señal del sujeto RunAs para intercambiar la señal solicitada. El valor predeterminado es ValueType de la señal solicitada.
|
No |
Una instancia de WSSGenerationContext y una instancia de WSSConsumingContext también se han establecido en el objeto GenericIssuedTokenGenerateCallbackHandler . En este ejemplo, la instancia WSSGenerationContext contiene un objeto UNTGenerateCallbackHandler con la información para crear el UsernameToken que desea enviar al STS.
El parámetro
system.wss.generate.issuedToken especifica el LoginModule Java
Authentication and Authorization Service (JAAS) que se utiliza para
crear la señal de seguridad genérica. 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=profile_root/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 ");
- Añada la señal de autenticación solicitada a la cabecera de seguridad SOAP de los mensajes de solicitud de servicios web.
- Inicialice el cliente de servicio web y configure las propiedades SOAPAction. El 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");
// Inicializar WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
- Inicialice el objeto WSSGenerationContext. En el código siguiente se muestra la utilización del método WSSFactory.newWSSGenerationContext para obtener un objeto WSSGenerationContext . El objeto WSSGenerationContext se utiliza para insertar la señal en un mensaje de solicitud de servicio web:
// Inicializar WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
El método WSSGenerationContext.add exige que el código de cliente tenga el siguiente permiso de seguridad Java 2:
permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- Añada una señal X.509 para la protección de mensajes (omita este paso si el servicio web sólo está protegido con la protección de nivel de transporte SSL). El siguiente código de ejemplo utiliza el archivo de claves dsig-sender y la clave de ejemplo SOAPRequester . No debe utilizar la clave de ejemplo en un entorno
de producción. En el código siguiente se muestra la adición de una señal X.509 para la protección de mensajes:
//Añadir una señal X.509 para la protección de mensajes.
X509GenerateCallbackHandler x509callbackHandler = new X509GenerateCallbackHandler(
null,
"profile_root/etc/ws-security/samples/dsig-sender.ks",
"JKS",
"client".toCharArray(),
"soaprequester",
"client".toCharArray(),
"CN=SOAPRequester, OU=TRL, O=IBM, ST=Kanagawa, C=JP", null);
SecurityToken x509 = factory.newSecurityToken(X509Token.class,
x509callbackHandler, "system.wss.generate.x509");
WSSSignature sig = factory.newWSSSignature(x509);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
- Cree un objeto WSSSignature con la señal X.509. La línea de código siguiente crea un objeto WSSSignature con la señal X.509:
WSSSignature sig = factory.newWSSSignature(x509);
- Añada la parte firmada que se debe utilizar para la protección de mensajes. La línea de código siguiente especifica la adición de WSSSignature.BODY como parte firmada:
sig.addSignPart(WSSSignature.BODY);
- Añada el elemento Timestamp en la cabecera de seguridad SOAP. Los conjuntos de políticas SAML20 SenderVouches WSHTTPS y SAML11 SenderVouches WSHTTPS requieren que las peticiones y respuestas de servicios web contenga un elemento Timestamp en la cabecera de seguridad SOAP. En el código siguiente, el método WSSFactory.newWSSTimestamp() genera un elemento Timestamp, y el método WSSGenerationContext.add(timestamp) añade el elemento Timestamp al mensaje de solicitud:
// Añadir elemento Timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- Omita este paso si la firma de señal no es necesaria. Si la señal de seguridad solicitada debe estar firmada con la opción de referencia STR Dereference Transform, siga el paso 1. De lo contrario, siga el paso 2. La referencia STR Dereference Transform se conoce comúnmente como STR-Transform.
Paso 1: Algunas señales, incluidas las SAML, no se puede firmar digitalmente directamente. Debe firmar la señal utilizando STR-Transform. Para que un símbolo que se firme con STR-Transform, debe estar referenciado por un elemento <wsse:SecurityTokenReference> en el bloque de cabecera <wsse:Security> . Para firmar una señal de seguridad con STR-Transform, se crea un WSSSignPart independiente para especificar el SecurityTokenReference con un algoritmo de transformación que se representa mediante el atributo WSSSignPart.TRANSFORM_STRT10 .
Este atributo permite al entorno de tiempo de ejecución de WS-Security generar un elemento SecurityTokenReference para hacer referencia a la señal y para firmar digitalmente la señal utilizando la opción de referencia STR Dereference. En el código siguiente se muestra la utilización del atributo WSSSignPart.TRANSFORM_STRT10 :
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
Paso 2: Si la señal firmada solicitada no es una señal SAML, o no se utiliza STR-Transform, utilice el código siguiente en su lugar:
sig.addSignPart(token);
- Adjunte el objeto WSSGenerationContext en el objeto RequestContext del servicio web. El objeto WSSGenerationContext ahora contiene toda la información de seguridad necesaria para dar formato a un mensaje de solicitud. El método WSSGenerationContext.process(requestContext) adjunta el objeto WSSGenerationContext en el objeto RequestContext del servicio web para permitir que el entorno de tiempo de ejecución WS-Security dé formato a la cabecera de seguridad SOAP necesaria; por ejemplo:
// Adjunta el objeto WSSGenerationContext al objeto RequestContext de servicios web. gencont.process(requestContext);
- Utilice la señal X.509 para validar la firma digital y la integridad del mensaje de respuesta si la política del proveedor exige que el mensaje de respuesta se firme digitalmente. Omita este paso si utiliza la protección de nivel de transporte SSL.
- Un objeto X509ConsumeCallbackHandler se inicializa con un almacén de confianza y una Lista de objetos de vía de acceso de certificado para validar la firma digital en un mensaje de respuesta. El código siguiente inicializa el objeto X509ConsumeCallbackHandler con el almacén de confianza dsig-ks y un objeto de vía de acceso de certificado llamado certList:
ArrayList certList = new ArrayList();
java.security.cert.CertStore certStore = java.security.cert.CertStore.getDefaultType();
certList.add(certStore);
X509ConsumeCallbackHandler callbackHandlerVer = new
X509ConsumeCallbackHandler("profile_root/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
- Un objeto WSSVerification se crea y el cuerpo del mensaje se añade al objeto de verificación para que el entorno de ejecución de WS-Security valide la firma digital. La línea siguiente de código se utiliza para inicializar el
objeto WSSVerification:
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
El objeto WSSConsumingContext ahora contiene toda la información de seguridad necesaria para dar
formato a un mensaje de solicitud. El método WSSConsumingContext.process(requestContext) adjunta el objeto WSSConsumingContext al método de respuesta; por ejemplo:
//Adjunta el objeto WSSConsumingContext al objeto RequestContext de servicios web.
concont.process(requestContext);
Resultados
Ha solicitado una señal de seguridad de un STS externo. Tras obtener la señal, envíe la señal con mensajes de solicitud de servicios web utilizando la protección de nivel de mensajes mediante el modelo de programación JAX-WS y las API de WSS.
Ejemplo
El ejemplo de código siguiente es una aplicación de cliente de servicio web que muestra cómo solicitar una señal de titular SAML de un STS externo y enviar dicha señal SAML en un mensaje de solicitud de servicio 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.
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.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.core.config.IssuedTokenConfigConstants;
import com.ibm.websphere.wssecurity.callbackhandler.GenericIssuedTokenGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityToken;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.BindingProvider;
public class SampleSamlSVClient {
private String urlHost = "yourhost";
private String urlPort = "9444";
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) {
SampleSamlSVClient sample = new SampleSamlSVClient();
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",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/wsjaas_client.conf ");
System.setProperty("com.ibm.SSL.ConfigURL",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/ssl.client.props");
//Solicitar la señal SAML desde un STS externo
WSSFactory factory = WSSFactory.getInstance();
String STS_URI = "https://yourhost:9443/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9081/WSSampleSei/EchoService12";
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Objeto de contexto de la solicitud WS-Trust:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Utilizar la autenticación de solicitud de confianza
UNTGenerateCallbackHandler utCallbackHandler = new
UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//obtener señal de seguridad genérica
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
System.out.println("SAMLToken id = " + token.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");
// Inicializar WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
// 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();
}
}
}