我们已经开发了使用Metro 2.0堆栈的Web服务,并通过具有对称密钥机制的用户名身份验证来保护Web服务应用程序。我们正在使用Spring WS开发一个示例客户端。
我们能够执行加密部分(时间戳,使用X509IssuerSerial加密的密钥以及使用标头中引用的加密密钥对Soap Body进行加密)。但是签名部分没有成功。安全令牌引用设置为UsernameToken而不是EncryptedKey。因此,我们从服务器端收到“ WSS1816:解析直接引用时发生错误”。
示例工作请求(使用jax-ws)如下
pip install
Spring bean配置如下。
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#">
<S:Header>
<To xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5005">AAAAA</To>
<Action xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5006">AAAAAAAA</Action>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5004">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
<MessageID xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5003">uuid:940807fd-ce2a-43a8-bc7a-e6c6ff60a0d7</MessageID>
<wsse:Security S:mustUnderstand="1">
<wsu:Timestamp xmlns:ns19="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"
xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" wsu:Id="_3">
<wsu:Created>2018-10-08T17:19:45Z</wsu:Created>
<wsu:Expires>2018-10-08T17:24:45Z</wsu:Expires>
</wsu:Timestamp>
<xenc:EncryptedKey xmlns:ns19="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"
xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_5002">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="KeyInfoType">
<wsse:SecurityTokenReference>
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>xxxxxxxxxxx</ds:X509IssuerName>
<ds:X509SerialNumber>xxxxxxxx</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>xxxxxxxxxxxxxxxxx</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
<xenc:ReferenceList xmlns:ns19="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"
xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
xmlns:ns17="http://www.w3.org/2003/05/soap-envelope">
<xenc:DataReference URI="#_5008" />
<xenc:DataReference URI="#_5009" />
</xenc:ReferenceList>
<xenc:EncryptedData xmlns:ns19="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"
xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_5009"
Type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="KeyInfoType">
<wsse:SecurityTokenReference>
<wsse:Reference URI="#_5002" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>xxxxxxxxxxx</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
<ds:Signature xmlns:ns19="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"
xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_1">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<exc14n:InclusiveNamespaces PrefixList="wsse S" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
<ds:Reference URI="#_5003">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<exc14n:InclusiveNamespaces PrefixList="S" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>c9ZlkDDMAW50WAsxUmfyqrlvhxM=</ds:DigestValue>
</ds:Reference>
<!-- many other references-->
</ds:SignedInfo>
<ds:SignatureValue>98jlT6xXmKFw6DiNZWRJ+EQjvk4=</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference wsu:Id="uuid_0001ebbf-5b73-42b2-a557-f945301fe28d">
<wsse:Reference URI="#_5002" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</S:Header>
<S:Body wsu:Id="_5007">
<!-- body data-->
</S:Body>
</S:Envelope>
使用上述配置,我们的请求如下生成
@Bean
public CryptoFactoryBean serverSignatureStoreCryptoFactoryBean() throws IOException, Exception {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
Properties cryptoFactoryBeanConfig = new Properties();
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jks");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "pwd");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.file", "C:\\TestCert.jks");
cryptoFactoryBean.setConfiguration(cryptoFactoryBeanConfig);
cryptoFactoryBean.afterPropertiesSet();
return cryptoFactoryBean;
}
@Bean
public CryptoFactoryBean serverEncryptionStoreCryptoFactoryBean() throws IOException, Exception {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
Properties cryptoFactoryBeanConfig = new Properties();
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jks");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "pwd");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.file", "C:\\TestCert.jks");
cryptoFactoryBeanConfig.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", "alias");
cryptoFactoryBean.setConfiguration(cryptoFactoryBeanConfig);
cryptoFactoryBean.afterPropertiesSet();
return cryptoFactoryBean;
}
@Bean
public Wss4jSecurityInterceptor securityInterceptor() throws IOException, Exception {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("Encrypt UsernameTokenSignature Timestamp ");
wss4jSecurityInterceptor.setSecurementUsername("testuser");
wss4jSecurityInterceptor.setSecurementPassword("testpwd");
wss4jSecurityInterceptor.setSecurementPasswordType("PasswordText");
wss4jSecurityInterceptor.setSecurementEncryptionCrypto(serverEncryptionStoreCryptoFactoryBean().getObject());
wss4jSecurityInterceptor.setSecurementEncryptionUser("alias");
wss4jSecurityInterceptor.setSecurementEncryptionParts("{}{http://schemas.xmlsoap.org/soap/envelope/}Body");
wss4jSecurityInterceptor.setSecurementSignatureCrypto(serverEncryptionStoreCryptoFactoryBean().getObject());
wss4jSecurityInterceptor.setSecurementSignatureUser("alias");
wss4jSecurityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");
wss4jSecurityInterceptor.setSecurementSignatureParts("{}{http://schemas.xmlsoap.org/soap/envelope/}Body");
wss4jSecurityInterceptor.afterPropertiesSet();
return wss4jSecurityInterceptor;
}