You can request an authentication token from an external Security
Token Service (STS), and then send the token with web service
request messages using the Java API
for XML-Based Web Services (JAX-WS) programming model and Web Services
Security APIs (WSS API), with message or transport level protection.
Before you begin
This task assumes that you are familiar with the JAX-WS programming
model, the WSS API interfaces, WebSphere® web
service security generic security token login modules, SSL transport
protection, message level protection, and the use of policy sets to
configure and administer web services settings.
About this task
The web service client application used in this task is
a modified version of the client code that is contained in the JaxWSServicesSamples
sample application that is available for download. Code examples from
the sample are described in the procedure, and a complete, ready-to-use
web service client sample is provided.
Complete the following
steps to request a SAML Bearer authentication token from an external
STS and send the token:
Procedure
- Identify and obtain the web service client that you want
to use to invoke a web service provider. Use this client
to request and to insert authentication tokens in the SOAP request
messages programmatically using WSS APIs. The web service client used
in this procedure is a modified version of the client code that is
contained in the JaxWSServicesSamples web service sample application.
Complete
the following steps to obtain and modify the sample web service client
to add the Web Services Security API to pass a security token in the
SOAP request message programmatically using WSS APIs:
- Download the JaxWSServicesSamples sample application. The JaxWSServicesSamples sample is not installed by default.
- Obtain the JaxWSServicesSamples client code. For
the purpose of this example, the procedure uses a modified version
of the Echo thin client sample that is included in the JaxWSServicesSamples
sample. The web service Echo thin client sample file, SampleClient.java,
is located in the src\SampleClientSei\src\com\ibm\was\wssample\sei\cli directory.
The sample class file is included in the WSSampleClientSei.jar file.
The JaxWSServicesSamples.ear enterprise
application and supporting Java archives
(JAR) files are located in the installableApps directory
within the JaxWSServicesSamples sample application.
- Deploy the JaxWSServicesSamples.ear file
onto the application server. After you deploy the JaxWSServicesSamples.ear file,
you are ready to test the sample web service client code against the
sample application.
Instead of using the PolicySet for the protection
of the web service client sample, you can choose to add the code snippets
to pass authentication tokens in the SOAP request message programmatically
using WSS APIs in your own web service client application. The example
in this procedure uses a JAX-WS web service thin client; however,
you can also use a managed client.
- Attach the SAML11 Bearer WSHTTPS default policy set
to the web services provider. This policy set is used to
protect messages using HTTPS transport. Read about configuring client
and provider bindings for the SAML Bearer token for details on how
to attach the SAML11 Bearer WSHTTPS default policy set to the web
services provider.
- Assign the SAML Bearer Provider sample default general
bindings to the sample web services provider. Read about
configuring client and provider bindings for the SAML bearer token
for details on assigning the SAML Bearer Provider sample default general
bindings to your web services application.
- Verify that the trustStoreType, trustStorePassword and
trustStorePath custom properties correspond to the trust store containing
the STS signer certificate. Complete the following steps
by using the administrative console:
- Click .
- Click con_saml11token in the Authentication
tokens table.
- Click Callback handler.
- In the Custom Properties section, ensure that the trustStoreType,
trustStorePassword and trustStorePath custom properties correspond
to the trust store containing the STS signer certificate.
- If you are using SSL Transport-level protection to protect
the web service request or the WS-Trust request, use the following Java virtual machine (JVM) property
to set up the SSL configuration.
-Dcom.ibm.SSL.ConfigURL=file:<profile_root>\properties\ssl.client.props
Alternatively,
you can define the SSL configuration file using a Java system property in the sample client code:
System.setProperty("com.ibm.SSL.ConfigURL", "file:profile_root/properties/ssl.client.props");
- Add the JAR file for the JAX-WS thin client to the class
path: app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar. See the testing web service-enabled clients information for
more information about adding this JAR file to the class path.
- Request the authentication token from an external STS. The following code snippet illustrates how to request the authentication
token to be used with WebSphere generic
SecurityToken login module, and assumes that an external STS is configured
to accept a Username token as authentication token, and to issue a
SAML 1.1 token.
//Request SecurityToken from external STS:
WSSFactory factory = WSSFactory.getInstance();
//STS URL that issues the requested token
String STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
//Web services endpoint that receives the issued token
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
//Begin sample code 1 (Using WS-Trust Issue to request the token from
//the STS in which authentication token is send over WS-Security head):
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//The following property specifies that the ws-trust request should be
//compliance with WS-Trust 1.3 spec
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");
//This request is made with WS-TRust Issue only (without the use of
//WS-Trust Validate)
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Create the context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//End of sample code 1.
//Begin sample code 2 (using WS-Trust Validate to request a token by
//exchanging a token in RunAs Subject).
//If web service client has RunAs Subject , for example an
//authenticated intermediate server acts as a client to invoke the
//downstream service, you can program the client to use the token from
//the RunAs subject to exchange with the STS by using WS-Trust validate.
//To do so, you replace sample code 1 with the following:
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//This request is made with 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");
//add the next line if you do not want to fallback to WS-Trust Issue if
//token exchange fails.
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY, "true");
//add the next line to specify the token type in the RunAs subject that
//will be used to exchange the requested token. For example, you use
//the LTPA token to exchange for a SAML token. If the exchanged token
//in the RunAs subject has the same value type as the requested token,
//setting IssuedTokenConfigConstants.USE_TOKEN is not required.
cbackMap1.put(IssuedTokenConfigConstants.USE_TOKEN, LTPAToken.ValueType);
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//The following codes are added if Authentication token in ws-security
//head or Message level security protection is required. If there is no
//Message level protection or additional authentication token for
//WS-Trust Validate, do not create the context object shown below.
//Context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler =
new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//End of sample code 2.
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
//The following step to set the ValueType is required..
//The parameter is always the QName of the requested token's valueType.
//QName for SAML1.1:
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//Includes QName definitions for SAML11, SAML20, TAM
//token, and Pass ticket token.
//QName for SAML 2.0:
QName Saml20ValueType = new QName(WSSConstants.SAML.SAML20_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//QName for TAM token:
QName TamValueType = new QName("http://ibm.com/2004/01/itfim/ivcred");
//QName for PassTicket token:
QName PassTicketValueType = new QName("http://docs.oasis-open.org/wss/
2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
//You can use the Token interface to get the token ValueType QName for
//all other tokens. For example, a Username Token's QName is //UsernameToken.ValueType.
The GenericIssuedTokenGenerateCallbackHandler object
contains parameters that define the characteristics of the security
token that you are requesting, as well as other parameters required
to reach the STS and to obtain the security token. The GenericIssuedTokenGenerateCallbackHandler object
specifies the configuration parameters described in the following
table:
Table 1. GenericIssuedTokenGenerateCallbackHandler properties. This table describes the configuration parameters for the GenericIssuedTokenGenerateCallbackHandler object,
and specifies whether or not the property is required.Property |
Description |
Required |
IssuedTokenConfigConstants.STS_ADDRESS |
Specifies the http address of the STS. When
communication to the STS is protected with SSL, you must set the -Dcom.ibm.SSL.ConfigURL property.
SSL connection to the STS is indicated with an https:// address
prefix.
|
Yes |
IssuedTokenConfigConstants.APPLIES_TO |
Specifies the target service address for where
you want to use the token. |
No |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
Specifies whether to request a single token
from the STS that is enclosed in a RequestSecurityToken (RST) element
or multiple tokens in a collection of RST elements that are enclosed
in a single RequestSecurityTokenCollection (RSTC) element.
The default behavior is to request a single token that is enclosed
in a RequestSecurityToken (RST) element from the
STS.
Specifying a true value for this
property indicates a request for multiple tokens in a collection of
RST elements that are enclosed in a single RequestSecurityTokenCollection
(RSTC) element from the STS.
The default value is false.
|
No |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
Specifies the WS-Trust namespace that is included
in the WS-Trust request. The default value is WSTrust 1.3.
|
No |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
Specify if you want WS-Security to use the token
from the RunAs subject to exchange the requested token first by using
WS-Trust Validate. If set to false, WS-Security
will use WS-Trust Issue to request the token. The default value
is true.
|
No |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
Specify if you do not want WS-Security to use
WS-Trust Issue to the requested token if token exchange fails. The
default value is false.
|
No |
IssuedTokenConfigConstants.USE_TOKEN |
Use this value to choose a token from the RunAs
subject to exchange the requested token. The default value is the
requested token's ValueType.
|
No |
A WSSGenerationContext instance and a WSSConsumingContext instance
are also set in the GenericIssuedTokenGenerateCallbackHandler object.
In this example, the WSSGenerationContext instance
contains a UNTGenerateCallbackHandler object with
the information to create the UsernameToken that
you want to send to the STS.
The
system.wss.generate.issuedToken parameter
specifies the Java Authentication
and Authorization Service (JAAS) login module that is used to create
the generic security token. You must specify a JVM property to define
a JAAS configuration file that contains the required JAAS login configuration;
for example:
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
Alternatively,
you can specify a JAAS login configuration file by setting a Java system property in the sample
client code; for example:
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf");
- Add the requested authentication token from the STS to
the SOAP security header of web services request messages.
- Initialize the web service client and configure the SOAPAction properties. The following code illustrates these actions:
// Initialize web service client
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configure SOAPAction properties
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");
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
- Initialize the WSSGenerationContext object. The following code illustrates using the WSSFactory.newWSSGenerationContext method
to obtain a WSSGenerationContext object. The WSSGenerationContext object
is then used to insert the token into a web service request message:
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
The WSSGenerationContext.add method
requires the client code to have the following Java 2 Security permission:permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- Add an X.509 token for message protection (skip this step
if the web service is protected with SSL Transport level protection
only). The following sample code uses the dsig-sender.ks key
file and the SOAPRequester sample key. You must not
use the sample key in a production environment. The following code
illustrates adding an X.509 token for message protection:
//Add an X.509 Token for message protection
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);
- Create a WSSSignature object with the
X.509 token. The following line of code creates a WSSSignature object
with the X.509 token:
WSSSignature sig = factory.newWSSSignature(x509);
- Add the signed part to use for message protection. The following line of code specifies to add WSSSignature.BODY as
the signed part:
sig.addSignPart(WSSSignature.BODY);
- Add the Timestamp element in the SOAP
Security header. The SAML20 SenderVouches WSHTTPS and SAML11
SenderVouches WSHTTPS policy sets require web service requests
and responses to contain a Timestamp element in the
SOAP Security header. In the following code, the WSSFactory.newWSSTimestamp() method
generates a Timestamp element, and the WSSGenerationContext.add(timestamp) method
adds the Timestamp element to the request message:
// Add Timestamp element
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- Skip this step if token signature is not required. If
the requested security token needs to be signed with the STR
Dereference Transform reference option, follow step 1. Otherwise,
follow step 2. The STR Dereference Transform reference
option is commonly known as STR-Transform.
Step
1: Some tokens, including SAML Tokens, cannot be digitally signed
directly. You must sign the token using STR-Transform.
In order for a token to be signed with STR-Transform,
it must be referenced by a <wsse:SecurityTokenReference> element
in the <wsse:Security> header block. To sign
a security token with STR-Transform, a separate WSSSignPart is
created to specify the SecurityTokenReference with
a transformation algorithm that is represented by the WSSSignPart.TRANSFORM_STRT10 attribute.
This attribute enables the WS-Security runtime environment to generate
a SecurityTokenReference element to reference the
token, and to digitally sign the token using the STR Dereference reference
option. The following code illustrates the use of the WSSSignPart.TRANSFORM_STRT10 attribute:
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
Step
2: If the requested signed token is not a SAML token, or STR-Transform is
not used, use the following code instead:sig.addSignPart(token);
- Attach the WSSGenerationContext object
to the web service RequestContext object. The WSSGenerationContext object
now contains all of the security information required to format a
request message. The WSSGenerationContext.process(requestContext) method
attaches the WSSGenerationContext object to the web
service RequestContext object to enable the WS-Security
runtime environment to format the required SOAP Security header; for
example:
// Attaches the WSSGenerationContext object to the web service RequestContext object.
gencont.process(requestContext);
- Use the X.509 token to validate the digital signature and
the integrity of the response message if the provider policy requires
the response message to be digitally signed. Skip this
step if using SSL Transport level protection.
- An X509ConsumeCallbackHandler object
is initialized with a trust store and a List of certificate
path objects to validate the digital signature in a response message. The following code initializes the X509ConsumeCallbackHandler object
with dsig-receiver.ks trust store and a certificate
path object called 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"));
- A WSSVerification object is created
and the message body is added to the verification object so that the
WS-Security runtime environment validates the digital signature. The following code is used to initialize the WSSVerification object:
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
The WSSConsumingContext object
now contains all the security information that is required to format
a request message. The WSSConsumingContext.process(requestContext) method
attaches the WSSConsumingContext object to the response
method; for example:// Attaches the WSSConsumingContext object to the web service RequestContext object.
concont.process(requestContext);
Results
You have requested a security token from an external STS.
After obtaining the token, you sent the token with web services request
messages using message level protection using the JAX-WS programming
model and WSS APIs.
Example
The following code example is a web service client application
that demonstrates how to request a SAML Bearer token from an external
STS and send that SAML token in a web service request message. If
your usage scenario requires SAML tokens, but does not require your
application to pass the SAML tokens using web service messages, you
only need to use the first part of the following sample code, up through
the
// Initialize web service client section.
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()
*
* see printusage() for command-line arguments
*
* @param args
*/
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* CallService Parms were already read. Now call the service proxy classes
*
*/
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");
//Request the SAML Token from external STS
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);
//Context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler = new
UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//get generic security token
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());
// Initialize web services client
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configure SOAPAction properties
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");
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
// Add timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
gencont.process(requestContext);
// Build the input object
EchoStringInput echoParm =
new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
echoParm.setEchoInput(input);
System.out.println(">> CLIENT: SEI Echo to " + endpointURL);
// Prepare to consume timestamp in response message.
WSSConsumingContext concont = factory.newWSSConsumingContext();
concont.add(WSSConsumingContext.TIMESTAMP);
concont.process(requestContext);
// Call the service
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();
}
}
}