您可以从外部安全性令牌服务 (STS) 请求认证令牌,然后使用 Java™ API
for XML-Based Web Services (JAX-WS) 编程模型和 Web Service 安全 API (WSS API) 以消息或传输级别保护来发送令牌以及 Web service 请求消息。
开始之前
本任务假设您熟悉 JAX-WS 编程模型、WSS API 接口、WebSphere® web service 安全通用安全性令牌登录模块、SSL 传输保护、消息级别保护以及策略集的使用以配置和管理 Web service 设置。
关于此任务
在此任务中使用的 Web service 客户机应用程序是可供下载的 JaxWSServicesSamples 样本应用程序中包含的客户机代码的已修改版本。在过程中描述了来自样本的代码示例,且提供完整的准备使用的 Web service 客户机样本。
完成以下步骤以从外部 STS 请求 SAML 不记名认证令牌然后发送该令牌:
过程
- 识别并包含您要用于调用 Web service 提供程序的 Web service 客户机。 使用此客户机来请求以及利用 WSS API 将认证令牌以编程方式插入 SOAP 请求消息。在此过程中使用的 Web service 客户机是 JaxWSServicesSamples Web service 样本应用程序中包含的客户机代码的已修改版本。
完成以下步骤以获取和修改 Web service 客户机样本来添加 Web Service 安全 API,从而使用 WSS API 以编程方式在 SOAP 请求消息中传递安全性令牌:
- 下载 JaxWSServicesSamples 样本应用程序。 缺省情况下,未安装 JaxWSServicesSamples 样本。
- 获取 JaxWSServicesSamples 客户机代码。 为了此示例,此过程使用 JaxWSServicesSamples 样本中包含的 Echo 瘦客户机样本的修改版本。
Web service Echo 瘦客户机样本文件 SampleClient.java 位于 src\SampleClientSei\src\com\ibm\was\wssample\sei\cli 目录中。
样本类文件包含在 WSSampleClientSei.jar 文件中。
JaxWSServicesSamples.ear 企业应用程序和支持
Java 归档 (JAR)
文件位于 JaxWSServicesSamples 样本应用程序内的 installableApps 目录中。
- 将 JaxWSServicesSamples.ear 文件部署到应用程序服务器上。 在部署 JaxWSServicesSamples.ear 文件之后,您准备好针对样本应用程序测试样本 Web service 客户机代码。
您可以选择添加代码片段以利用自己的 Web service 客户机应用程序中的 WSS API 用编程方式传递 SOAP 请求消息中的认证令牌,而不是使用 PolicySet 来保护 web service 客户机样本。此过程中的示例使用 JAX-WS web service 瘦客户机;但是,您还可以使用受管客户机。
- 将 SAML11 Bearer WSHTTPS default 策略集附加到 Web service 提供程序。 此策略集用于使用 HTTPS 传输来保护消息。阅读关于配置 SAML 不记名令牌的客户机和提供程序绑定的信息以了解如何将 SAML11 Bearer WSHTTPS default 策略集附加到 Web service 提供程序的详细信息。
- 将 SAML Bearer 提供程序样本缺省常规绑定分配到样本 Web Service 提供程序。 阅读关于配置 SAML 不记名令牌的客户机和提供程序绑定的信息,以了解关于将 SAML Bearer 提供程序样本缺省常规绑定分配到 Web service 应用程序的详细信息。
- 验证 trustStoreType、trustStorePassword 和 trustStorePath 定制属性是否对应于包含 STS 签署者证书的信任库。 使用管理控制台来完成以下步骤:
- 单击。
- 单击“认证令牌”表中的 con_saml11token。
- 单击回调处理程序。
- 在“定制属性”部分中,确保 trustStoreType、trustStorePassword 和 trustStorePath 定制属性对应于包含 STS 签署者证书的信任库。
- 如果您使用 SSL 传输级别保护来保护 web service 请求或 WS-Trust 请求,请使用以下 Java 虚拟机 (JVM) 属性来设置 SSL 配置。
-Dcom.ibm.SSL.ConfigURL=file:<profile_root>\properties\ssl.client.props
或者,您可以使用样本客户机代码中的 Java 系统属性来定义 SSL 配置文件:
System.setProperty("com.ibm.SSL.ConfigURL", "file:profile_root/properties/ssl.client.props");
- 将 JAX-WS 瘦客户机的 JAR 文件添加到类路径:app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar。 请参阅测试支持 Web Service 的客户机信息以了解关于将此 JAR 文件添加到类路径的更多信息。
- 从外部 STS 请求认证令牌。 以下代码片段说明如何请求要用于 WebSphere 常规
SecurityToken 登录模块的认证令牌,并假设已配置外部 STS 将 Username 令牌接受为认证令牌,以及发布 SAML 1.1 令牌。
//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.
GenericIssuedTokenGenerateCallbackHandler 对象包含定义您请求的安全性令牌的特征的参数,以及访问 STS 和获取安全性令牌所需的其他参数。GenericIssuedTokenGenerateCallbackHandler 对象指定下表中描述的配置参数:
表 1. GenericIssuedTokenGenerateCallbackHandler 属性. 该表描述 GenericIssuedTokenGenerateCallbackHandler 对象的配置参数,并指定是否需要该属性。属性 |
描述 |
必需 |
IssuedTokenConfigConstants.STS_ADDRESS |
指定 STS 的 HTTP 地址。 使用 SSL 来保护对 STS 的通信时,您必须设置 -Dcom.ibm.SSL.ConfigURL 属性。
使用 https:// 地址前缀来指示到 STS 的 SSL 连接。
|
是 |
IssuedTokenConfigConstants.APPLIES_TO |
指定您要使用令牌的目标服务地址。 |
否 |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
指定从 STS 请求包括在 RequestSecurityToken (RST) 元素中的单个令牌还是请求包括在单个 RequestSecurityTokenCollection (RSTC) 元素中的 RST 元素集合中的多个令牌。 缺省行为是从 STS 请求包含在 RequestSecurityToken (RST) 元素中的单个令牌。
为该属性指定 True 值将指示从 STS 请求包含在单个 RequestSecurityTokenCollection (RSTC) 元素中的 RST 元素集合中的多个令牌。
缺省值为 false。
|
否 |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
指定包含在 WS 信任请求中的 WS 信任名称空间。 缺省值是 WSTrust 1.3。
|
否 |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
指定您是否希望 WS-Security 使用来自 RunAs 主体集的令牌通过使用 WS-Trust 验证来首先交换请求的令牌。如果设置为 False,那么 WS-Security 将使用 WS-Trust 发布来请求令牌。 缺省值为 true。
|
否 |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
指定您是否不希望 WS-Security 使用 WS-Trust 发布到请求的令牌(如果令牌交换失败)。 缺省值为 false。
|
否 |
IssuedTokenConfigConstants.USE_TOKEN |
使用该值来从 RunAs 主体集选择令牌以交换请求的令牌。 缺省值是请求的令牌的 ValueType。
|
否 |
WSSGenerationContext 实例和 WSSConsumingContext 实例也在 GenericIssuedTokenGenerateCallbackHandler 对象中设置。
在此示例中,WSSGenerationContext 实例包含 UNTGenerateCallbackHandler 对象,其具有创建您要发送到 STS 的 UsernameToken 所需的信息。
system.wss.generate.issuedToken 参数指定 Java 认证和授权服务 (JAAS) 登录模块,该模块用于创建通用安全性令牌。您必须指定 JVM 属性以定义 JAAS 配置文件,其包含所需的 JAAS 登录配置;例如:
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
或者,您可以通过在样本客户机代码中设置 Java 系统属性来指定 JAAS 登录配置文件;例如:
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf");
- 将请求的认证令牌从 STS 添加到 Web service 请求消息的 SOAP 安全头。
- 初始化 web service 客户机并配置 SOAPAction 属性。 以下代码说明这些操作:
// 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);
- 初始化 WSSGenerationContext 对象。 以下代码说明如何使用 WSSFactory.newWSSGenerationContext 方法来获取 WSSGenerationContext 对象。然后,使用 WSSGenerationContext 对象将该令牌插入 web service 请求消息:
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
WSSGenerationContext.add 方法要求客户机代码具有以下 Java 2 安全许可权:permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- 为消息保护添加 X.509 令牌(如果仅使用 SSL 传输级别保护来保护 web service,那么跳过这一步)。 以下样本代码使用 dsig-sender.ks 密钥文件和 SOAPRequester 样本密钥。您不得在生产环境中使用样本密钥。以下代码说明如何添加 X.509 令牌来进行消息保护:
// 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);
- 使用 X.509 令牌创建 WSSSignature 对象。 以下代码行使用 X.509 令牌创建 WSSSignature 对象:
WSSSignature sig = factory.newWSSSignature(x509);
- 添加要用于消息保护的已签名部分。 以下代码行指定将 WSSSignature.BODY 添加为已签名部分:
sig.addSignPart(WSSSignature.BODY);
- 在 SOAP 安全头中添加 Timestamp 元素。 SAML20 SenderVouches WSHTTPS 和 SAML11
SenderVouches WSHTTPS 策略集合要求 web service 请求和响应将 Timestamp 元素包含在 SOAP 安全头中。在以下代码中,WSSFactory.newWSSTimestamp() 方法生成 Timestamp 元素,然后 WSSGenerationContext.add(timestamp) 方法将 Timestamp 元素添加到请求消息:
// Add Timestamp element
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- 如果无需令牌签名,请跳过这一步。如果请求的安全性令牌需要使用 STR 取消引用变换引用选项来签名,请遵循步骤 1。否则,遵循步骤 2。STR 取消引用变换引用选项通常称为 STR 变换。
步骤 1:某些令牌(包括 SAML 令牌)无法以数字方式直接签名。您必须使用 STR 变换来签署令牌。
为了使用 STR 变换来签署令牌,它必须由 <wsse:Security> 头块中的 <wsse:SecurityTokenReference> 元素引用。为了使用 STR 变换来签署安全性令牌,将创建单独的 WSSSignPart 来使用 WSSSignPart.TRANSFORM_STRT10 属性表示的变换算法指定 SecurityTokenReference。
该属性使 WS-Security 运行时环境可以生成 SecurityTokenReference 元素来引用令牌,以及使用 STR 取消引用引用选项以数字方式签署令牌。以下代码说明 WSSSignPart.TRANSFORM_STRT10 属性的用法:
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
步骤 2:如果请求的签署令牌不是 SAML 令牌,或者没有使用 STR 变换,请使用以下代码:sig.addSignPart(token);
- 将 WSSGenerationContext 对象附加到 web service RequestContext 对象。 WSSGenerationContext 对象现在包含格式化请求消息所需的所有安全信息。WSSGenerationContext.process(requestContext) 方法将 WSSGenerationContext 对象附加到 web service RequestContext 对象以使 WS-Security 运行时环境来格式化必需的 SOAP 安全头;例如:
// Attaches the WSSGenerationContext object to the web service RequestContext object.
gencont.process(requestContext);
- 如果提供程序策略要求以数字方式对响应消息签名,请使用 X.509 令牌来验证响应消息的数字签名和完整性。 如果使用 SSL 传输级别保护,请跳过此步骤。
- 以信任库和证书路径对象的 List 来初始化 X509ConsumeCallbackHandler 对象以验证响应消息中的数字签名。 以下代码以 dsig-receiver.ks 信任库和称为 certList 的证书路径对象初始化 X509ConsumeCallbackHandler 对象:
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"));
- 创建了 WSSVerification 对象且消息主体添加到验证对象,以便 WS-Security 运行时环境验证数字签名。 以下代码用于初始化 WSSVerification 对象:
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
WSSConsumingContext 对象现在包含格式化请求消息所需的所有安全信息。WSSConsumingContext.process(requestContext) 方法将 WSSConsumingContext 对象附加到响应方法;例如:// Attaches the WSSConsumingContext object to the web service RequestContext object.
concont.process(requestContext);
结果
您从外部 STS 请求了安全性令牌。
获取令牌之后,您使用 JAX-WS 编程模型和 WSS API 以消息级别保护将令牌随 Web service 请求消息一起发送。
示例
以下代码示例是一个 Web service 客户机应用程序,其演示如何从外部 STS 请求 SAML 不记名令牌以及在 Web service 请求消息中发送该 SAML 令牌。如果您的使用方案需要 SAML 令牌,但是不要求您的应用程序使用 Web service 消息传递 SAML 令牌,那么您只需使用以下样本代码的第一部分,直到
// Initialize web service client 部分。
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();
}
}
}