使用 WSS API 配置生成者安全性令牌

可使用 Web Service 安全性 API 取代策略集来保护 SOAP 消息。要在生成者端配置令牌,请使用 Web Services Security API (WSS API)。生成者安全性令牌是 com.ibm.websphere.wssecurity.wssapi.token 接口包的一部分。

开始之前

WebSphere® Application Server 中的可插入令牌框架已重新设计,以便可以复用 WSS API 中的同一框架。可以对 Web Services Security 运行时和 WSS API 应用程序代码使用创建和验证安全性令牌操作的同一实现。重新设计的框架还简化了 SPI 编程模型,从而简化了添加安全性令牌类型的过程。

可以使用 WSS API,或者通过管理控制台来配置令牌。要配置令牌,必须完成下列令牌任务:

  • 配置生成者令牌。
  • 配置使用者令牌。

关于此任务

JAAS CallbackHandler 和 JAAS LoginModule 负责在生成者端创建安全性令牌。

在生成者端,令牌通过使用 JAAS LoginModule 创建,并使用 JAAS CallbackHandler 来传递认证数据。然后,JAAS LoginModule 创建 securityToken 对象(例如 UsernameToken)并将其传递给 Web Service 安全性运行时。

在使用者端,XML 格式被传递到 JAAS LoginModule 以进行验证或认证。 然后,将使用 JAAS CallbackHandler 将认证数据从 Web Service 安全运行时传递到 LoginModule。对令牌进行认证后,将创建安全性令牌对象,并将令牌与对象一起传递至 Web Service 安全运行时。

使用 WSS API 进行生成者令牌创建时,将出现某些缺省行为。使用 WSS API 的最简单方法是使用缺省行为(请参阅示例代码)。WSS API 对令牌类型、令牌值和 JAAS 确认名称提供缺省值。缺省令牌行为包括:

表 1. 令牌决策和缺省行为. 缺省情况下,已配置若干令牌特征。
生成者令牌决定 缺省行为
要使用的令牌类型

令牌类型指定要对消息完整性、消息机密性或消息真实性使用的令牌类型。

WebSphere Application Server 提供了以下预配置的生成者令牌类型来确保消息完整性和消息机密性:
  • 派生密钥令牌
  • X509 令牌
还可以根据需要创建定制令牌类型。

WebSphere Application Server 还提供了以下预配置的生成者令牌类型来确保消息真实性:

  • 用户名令牌
  • LTPA 令牌
  • X509 令牌

还可以根据需要创建定制令牌类型。

要指定的 JAAS 登录配置名称

JAAS 登录配置名称指定要使用的 JAAS 登录配置名称。

要使用的配置类型 JAAS 登录模块指定配置类型。只能将预先配置的生成者配置类型用于生成者令牌类型。

SecurityToken 类 (com.ibm.websphere.wssecurity.wssapi.token.SecurityToken) 是通用令牌类,并且表示具有获取标识、XML 格式和密钥的方法的安全性令牌。使用 SecurityToken 类可以将签名和加密应用于 SOAP 消息。但是,要应用两者,必须具有两个 SecurityToken 对象,分别用于签名和加密。

下列令牌类型是通用安全性令牌类的子类:

表 2. SecurityToken 的子类. 使用子类来表示安全性令牌。
令牌类型 JAAS 登录配置名称
用户名令牌 system.wss.generate.unt
安全上下文令牌 system.wss.generate.sct
派生密钥令牌 system.wss.generate.dkt

下列令牌类型是二进制安全性令牌类的子类:

表 3. BinarySecurityToken 的子类. 使用子类来表示二进制安全性令牌。
令牌类型 JAAS 登录配置名称
LTPA 令牌 system.wss.generate.ltpa
LTPA 传播令牌 system.wss.generate.ltpaProp
X.509 令牌 system.wss.generate.x509
X.509 PKI 路径令牌 system.wss.generate.pkiPath
X.509 PKCS7 令牌 system.wss.generate.pkcs7
注:
  • 对于每个 JAAS 登录令牌生成者配置名称,分别具有一个令牌使用者配置名称。例如,对于用户名令牌,单独的令牌使用者配置名称是 system.wss.consume.unt。
  • LTPA 和 LTPA 传播令牌仅适用于正在作为基于服务器的客户机来运行的请求者。Java™ SE 6 或 Java EE 应用程序客户机不支持 LTPA 和 LTPA 传播令牌。

过程

  1. 要配置 securityToken 包 com.ibm.websphere.wssecurity.wssapi.token,请首先确保安装了应用程序服务器。
  2. 使用 Web Services Security 令牌生成者过程来配置令牌。 对于每个令牌类型,此过程类似于以下演示 UsernameToken 令牌生成者过程的过程:
    1. 使用 WSSFactory.getInstance() 获取 WSS API 实现实例。
    2. 根据 WSSFactory 实例创建 WSSGenerationContext 实例。
    3. 创建 JAAS CallbackHandler。 认证数据(如用户名和密码)指定为 CallbackHandler 的一部分。例如,以下代码指定 Chris 作为用户名,而指定 sirhC 作为密码: UNTGenerationCallbackHandler("Chris", "sirhC");
    4. 调用任何 JAAS CallbackHandler 参数,并检查令牌类信息以确定哪些参数是必需的或可选的。 例如,对于 UsernameToken,还可以配置下列参数:
      现时标志
      指示现时标志是否包含在令牌生成者的用户名令牌中。现时标志是一个嵌入在消息中的唯一的加密数字,以帮助停止用户名令牌的重复、未授权的攻击。 仅当生成令牌类型是 UsernameToken 并且应用于请求生成者绑定时,现时标志值才有效。
      创建的时间戳记
      指示是否将时间戳记插入至 UsernameToken。仅当生成令牌类型是 UsernameToken 并且应用于请求生成者绑定时,时间戳记值才有效。
    5. 从 WSSFactory 创建 SecurityToken。

      缺省情况下,UsernameToken API 将 ValueType 指定为:“http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken”

      缺省情况下,UsernameToken API 提供这个类的 QName 并将 NamespaceURI 指定为 http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd,并同时将 LocalPart 指定为 UsernameToken。

    6. 可选: 指定 JAAS 登录模块配置名称。 在生成者端,配置类型始终是 generate(例如,system.wss.generate.unt)。
    7. 将 SecurityToken 添加至 WSSGenerationContext。
    8. 调用 WSSGenerationContext.process() 然后生成 WS-Security 头。

结果

如果存在错误情况,那么将提供 WSSException。如果成功,那么将调用 WSSGenerationContext process(),并连接生成者绑定的安全性令牌。

示例

以下示例代码说明如何使用 WSS API 创建用户名安全性令牌、将用户名令牌连接至 SOAP 消息以及在生成者绑定中配置用户名令牌。

// import the packages
import javax.xml.ws.BindingProvider;
import com.ibm.websphere.wssecurity.wssapi.*;
import com.ibm.websphere.wssecurity.callbackhandler.*;
...
   // obtain the binding provider
   BindingProvider bp = ... ;

   // get the request context
   Map<String, Object> reqContext = bp.getRequestContext();

   // generate WSSFactory instance
   WSSFactory factory = WSSFactory.getInstance();

   // generate WSSGenerationContext instance
   WSSGenerationContext gencont = factory.newWSSGenerationContext();

   // generate callback handler
   UNTGenerateCallbackHandler untCallbackHandler = 
   new UNTGenerateCallbackHandler("Chris", "sirhC");

   // generate the username token 
   SecurityToken unt = factory.newSecurityToken(UsernameToken.class, untCallbackHandler);

   // add the SecurityToken to the WSSGenerationContext
   gencont.add(unt);

   // generate the WS-Security header
   gencont.process(reqContext);
以下示例代码显示如何修改先前的用户名令牌样本从当前线程的 runAs 身份创建 LTPAv2 令牌。将实例化回调处理程序并创建安全性令牌的两行代码替换为以下两行代码:
// generate callback handler
LTPAGenerateCallbackHandler ltpaCallbackHandler = new LTPAGenerateCallbackHandler(null, null);

// generate the LTPAv2 token 
SecurityToken ltpa = wssfactory.newSecurityToken(LTPAv2Token.class, ltpaCallbackHandler);

具有 (null, null) 的 LTPAGenerateCallbackHandler 对象的实例化指示应该从当前 runAs 身份生成 LTPA 令牌。如果以 basicAuth 信息(“用户名”、“密码”)实例化回调处理程序,那么使用指定的 basicAuth 信息创建新的 LTPA 令牌。

以下示例显示了如何使用与 WSS API 的安全对话来配置生成者令牌和使用者令牌。在此示例中,使用 WS-SecureConversation 草稿名称空间 http://schemas.xmlsoap.org/ws/2005/02/sc/sct 创建 SecurityContextToken 令牌。 要使用 WS-SecureConversation V1.3 名称空间 http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/sct,请指定 SecurityContextToken13.class 而不是 SecurityContextToken.class。
// import the packages
import javax.xml.ws.BindingProvider;
import com.ibm.websphere.wssecurity.wssapi.*;
import com.ibm.websphere.wssecurity.callbackhandler.*;
...
   // obtain the binding provider
   BindingProvider bp = ... ;

   // get the request context
   Map<String, Object> reqContext = bp.getRequestContext();

   // generate WSSFactory instance
   WSSFactory wssFactory = WSSFactory.getInstance();

   WSSGenerationContext bootstrapGenCon = wssFactory.newWSSGenerationContext();

   // Create a Timestamp
   ...
   // Add Timestamp
   ...

   // Sign the SOAP Body, WS-Addressing headers, and Timestamp
   X509GenerateCallbackHandler btspReqSigCbHandler = new X509GenerateCallbackHandler(...);
   SecurityToken btspReqSigToken = wssFactory.newSecurityToken(X509Token.class,
                                                               btspReqSigCbHandler);
   WSSSignature bootstrapReqSig = wssFactory.newWSSSignature(btspReqSigToken);
   bootstrapReqSig.setCanonicalizationMethod(WSSSignature.EXC_C14N);

   // Add Sign Parts
   ...
   bootstrapGenCon.add(bootstrapReqSig);

   // Encrypt the SOAP Body and the Signature
   X509GenerateCallbackHandler btspReqEncCbHandler = new X509GenerateCallbackHandler(...);
   SecurityToken btspReqEncToken = wssFactory.newSecurityToken(X509Token.class,
                                                               btspReqEncCbHandler);
   WSSEncryption bootstrapReqEnc = wssFactory.newWSSEncryption(btspReqEncToken);
   bootstrapReqEnc.setEncryptionMethod(WSSEncryption.AES128);
   bootstrapReqEnc.setKeyEncryptionMethod(WSSEncryption.KW_RSA15);

   // Add Encryption parts
   ...
   bootstrapGenCon.add(bootstrapReqEnc);
   WSSConsumingContext bootstrapConCon = wssFactory.newWSSConsumingContext();
   X509ConsumeCallbackHandler btspRspVfyCbHandler = new X509ConsumeCallbackHandler(....);
   WSSVerification bootstrapRspVfy = wssFactory.newWSSVerification(X509Token.class,
                                                                   btspRspVfyCbHandler);
   bootstrapRspVfy.addAllowedCanonicalizationMethod(WSSVerification.EXC_C14N);

   // Add Verify parts
   ...
   bootstrapConCon.add(bootstrapRspVfy);
   X509ConsumeCallbackHandler btspRspDecCbHandler = new X509ConsumeCallbackHandler(...);
   WSSDecryption bootstrapRspDec = wssFactory.newWSSDecryption(X509Token.class,
                                                               btspRspDecCbHandler);
   bootstrapRspDec.addAllowedEncryptionMethod(WSSDecryption.AES128);
   bootstrapRspDec.addAllowedKeyEncryptionMethod(WSSDecryption.KW_RSA15);

   // Add Decryption parts
   ...
   bootstrapConCon.add(bootstrapRspDec);
   SCTGenerateCallbackHandler sctgch = new SCTGenerateCallbackHandler(bootstrapGenCon,
                                                                      bootstrapConCon,
                                                                      ENDPOINT_URL,
                                                                      WSSEncryption.AES128);
   SecurityToken[] scts = wssFactory.newSecurityTokens(new Class[]{SecurityContextToken.class},
                                                       sctgch);
   SecurityContextToken sct = (SecurityContextToken)scts[0];

   // Use the SCT to generate DKTs for Secure Conversation
   // Signature algorithm and client and service labels
   DerivedKeyToken dktSig = sct.getDerivedKeyToken(WSSSignature.HMAC_SHA1,
                                                   "WS-SecureConversation",
                                                   "WS-SecureConversation");

   // Encryption algorithm and client and service labels
   DerivedKeyToken dktEnc = sct.getDerivedKeyToken(WSSEncryption.AES128,
                                                   "WS-SecureConversation",
                                                   "WS-SecureConversation");

   // Create the application generation context for the request message
   WSSGenerationContext applicationGenCon = wssFactory.newWSSGenerationContext();

   // Create and add Timestamp
   ...

   // Add the derived key token and Sign the SOAP Body and WS-Addressing headers
   WSSSignature appReqSig = wssFactory.newWSSSignature(dktSig);
   appReqSig.setSignatureMethod(WSSSignature.HMAC_SHA1);
   appReqSig.setCanonicalizationMethod(WSSSignature.EXC_C14N);
   ...
   applicationGenCon.add(appReqSig);

   // Add the derived key token and Encrypt the SOAP Body and the Signature
   WSSEncryption appReqEnc = wssFactory.newWSSEncryption(dktEnc);
   appReqEnc.setEncryptionMethod(WSSEncryption.AES128);
   appReqEnc.setTokenReference(SecurityToken.REF_STR);
   appReqEnc.encryptKey(false);
   ...
   applicationGenCon.add(appReqEnc);

   // Create the application consuming context for the response message
   WSSConsumingContext applicationConCon = wssFactory.newWSSConsumingContext();

   //client and service labels and decryption algorithm
   SCTConsumeCallbackHandler sctCbHandler = new SCTConsumeCallbackHandler("WS-SecureConversation",
                                                                          "WS-SecureConversation",
                                                                          WSSDecryption.AES128);

   // Derive the token from SCT and use it to Decrypt the SOAP Body and the Signature
   WSSDecryption appRspDec = wssFactory.newWSSDecryption(SecurityContextToken.class,
                                                         sctCbHandler);
   appRspDec.addAllowedEncryptionMethod(WSSDecryption.AES128);
   appRspDec.encryptKey(false);
   ...
   applicationConCon.add(appRspDec);

   // Derive the token from SCT and use it to Verify the
   // signature on the SOAP Body, WS-Addressing headers, and Timestamp
   WSSVerification appRspVfy = wssFactory.newWSSVerification(SecurityContextToken.class,
                                                             sctCbHandler);
   ...
   applicationConCon.add(appRspVfy);
   ...
   applicationGenCon.process(reqContext);
   applicationConCon.process(reqContext);

下一步做什么

对于每个令牌类型,使用 WSS API 或管理控制台来配置令牌。接下来,指定类似的使用者令牌(如果尚未这样做)。

如果生成者和使用者令牌均已配置,请根据需要通过签署 SOAP 消息或通过对消息进行加密来继续保护 SOAP 消息。可以使用 WSS API 或管理控制台来保护 SOAP 消息。


指示主题类型的图标 任务主题



时间戳记图标 最近一次更新时间: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_confwssgeneratortoken
文件名:twbs_confwssgeneratortoken.html