使用 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 确认名称提供缺省值。缺省令牌行为包括:
生成者令牌决定 | 缺省行为 |
---|---|
要使用的令牌类型 | 令牌类型指定要对消息完整性、消息机密性或消息真实性使用的令牌类型。 WebSphere Application Server 提供了以下预配置的生成者令牌类型来确保消息完整性和消息机密性:
WebSphere Application Server 还提供了以下预配置的生成者令牌类型来确保消息真实性:
还可以根据需要创建定制令牌类型。 |
要指定的 JAAS 登录配置名称 | JAAS 登录配置名称指定要使用的 JAAS 登录配置名称。 |
要使用的配置类型 | JAAS 登录模块指定配置类型。只能将预先配置的生成者配置类型用于生成者令牌类型。 |
SecurityToken 类 (com.ibm.websphere.wssecurity.wssapi.token.SecurityToken) 是通用令牌类,并且表示具有获取标识、XML 格式和密钥的方法的安全性令牌。使用 SecurityToken 类可以将签名和加密应用于 SOAP 消息。但是,要应用两者,必须具有两个 SecurityToken 对象,分别用于签名和加密。
下列令牌类型是通用安全性令牌类的子类:
令牌类型 | JAAS 登录配置名称 |
---|---|
用户名令牌 | system.wss.generate.unt |
安全上下文令牌 | system.wss.generate.sct |
派生密钥令牌 | system.wss.generate.dkt |
下列令牌类型是二进制安全性令牌类的子类:
令牌类型 | 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 传播令牌。
过程
结果
示例
以下示例代码说明如何使用 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);
// 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 令牌。
// 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 消息。