配置XML签名的Web服务仍然是与特定服务器相关的,因此请参考你的服务器的相关文档。基于签名的身份验证是一种用于保障服务安全性的有效方法,这些服务的客户是其它服务器和设备。
基于签名的身份验证
UsernameToken身份验证适合于客户端身份基于用户的情况,但是你的Web服务客户端可能是一个并不直接代表一个用户的服务器或者设备。可以考虑这样一种情况:一个处理船舶运载的Web服务通过检查定单的交付日期,将定单发送到适当的运载服务供应商。假定客户端是一个消息驱动的服务器定单应用程序,这个应用程序从一个队列中接收消息,并且通过调用运载和账单处理服务来处理定单。在这种情况下,运载服务的身份验证就必须限制为只能给定单应用程序服务器而不是特定的用户。
验证服务器和设备客户端的一种方法是使用XML签名。客户端使用一个私钥来签署SOAP消息,而Web服务使用相应的公钥来验证这个签名。正如在前面的关于加密的示例中所讨论的那样,必须生成一对公/私钥密码。一个密钥存储通常情况下存储着包含服务器公钥的X509证书。图2显示了基于签名的身份验证顺序:
配置XML签名的Web服务仍然是与特定服务器相关的,因此请参考你的服务器的相关文档。
为客户端增加签名需要与配置加密方式一样配置一个WSS4J处理程序。你可以用以前介绍的configureClientHandlers方法为这个处理程序增加代码:
private static void configureClientHandlers(Object svc) {
Client client=Client.getInstance(svc);
client.addOutHandler(new DOMOutHandler());
// Add WSS4J signature Handler
Properties sigProps = new Properties();
configureSignature(sigProps);
client.addOutHandler(new WSS4JOutHandler(sigProps));
} |
configureClientHandlers方法调用configureSignature的目的是指定处理程序的签名属性。其属性包含要签名的局部消息、签名属性文件的位置以及用于在SOAP报头中指定签名的方法:
protected static void configureSignature(Properties config)
{
// Signature Action
config.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE );
// Method of specifying the signature in the header
config.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
// Signature Property File Location
config.setProperty
(WSHandlerConstants.SIG_PROP_FILE, "com/dev/ws/client/driver/outsecurity_sig.properties");
// Sign the Body part of the message
String bodyPart = "{Content}{}Body";
config.setProperty(WSHandlerConstants.SIGNATURE_PARTS,bodyPart);
} |
签名属性文件outsecurity_sig.properties指定了密钥存储的位置、口令、和签名者的别名:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=client344Password
org.apache.ws.security.crypto.merlin.keystore.alias=client-344-839
org.apache.ws.security.crypto.merlin.file=com/dev/ws/client/driver/clientStore.jks |
通过可用的签名运行计算器的例子会产生如下的SOAP消息:
<soap:Envelope ...>
<soap:Header>
<wsse:Security ...>
<ds:Signature ...>
...
<ds:SignatureValue ...>
Jx/wbsqjTsNZha+JDTCeCtNzUlaXAzWUOjyRCTQE6OQhiwQOpCt0gOd4mxsb5mI9Hrtr+0lSIZOJ
dOHBKTqcCQNmQneM8CI/oeo0RwLSaMXh2fIA+/mZt+EBcS9+WB9Vdv4AnCWYr4/feAxJkioZwzXt
9NquZMnC1nhRTMOoFpM=
</ds:SignatureValue>
...
</ds:Signature>
</wsse:Security>
</soap:Header>
<soap:Body ...>
...
</soap:Body>
<soap:Envelope> |
注意SOAP的头部现在包括了一个SignatureValue成分,该成分包含着签名。服务器使用这个签名来验证SOAP消息的真实性。
基于签名的身份验证是一种用于保障服务安全性的有效方法,这些服务的客户是其它服务器和设备。签名还满足了应用程序对安全性的需要,这些应用程序需要每一项服务处理身份验证的合法证据。管理客户端和服务器证书的需要增加了总体的可维护性,而且必须在规划阶段就加以考虑。你应该清楚,这种方案并没有涉及到J2EE验证模式,因此它仅限于处理身份验证的需要。