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 that follows.
//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();
}
}
}