Мы разработали веб-сервис, использующий стек Metro 2.0 и защищенный аутентификацией по имени пользователя с помощью механизма Symmetric Key для защиты приложения веб-службы.Мы работаем над примером клиента с использованием Spring WS.
Мы смогли выполнить часть шифрования (временная метка, зашифрованный ключ с X509IssuerSerial и зашифровать Soap Body с помощью зашифрованного ключа, указанного в заголовке).Но подписывающая часть не удалась.Ссылка на токен безопасности установлена на UsernameToken вместо EncryptedKey.Поэтому мы получаем «WSS1816: Произошла ошибка при разрешении прямой ссылки» со стороны сервера.
Пример рабочего запроса (с использованием jax-ws) выглядит следующим образом
<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>
Конфигурации Spring bean похожиниже.
@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;
}
При указанных выше конфигурациях наш запрос генерируется как показано ниже
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security 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"
SOAP-ENV:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-b005d85e-c7e5-4d49-ad77-0672d6a58b29">
<wsu:Created>2018-10-09T13:43:54.310Z</wsu:Created>
<wsu:Expires>2018-10-09T13:48:54.310Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
wsu:Id="UsernameToken-a895d28f-1f3f-4d9f-85e1-aff8400834b4">
<wsse:Username>testuser</wsse:Username>
<wsse11:Salt>xxxxxxxxx</wsse11:Salt>
<wsse11:Iteration>1000</wsse11:Iteration>
<wsse:Nonce
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
xxxxxxxx</wsse:Nonce>
<wsu:Created>2018-10-09T13:43:54.283Z</wsu:Created>
</wsse:UsernameToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-463b7470-6066-40c2-b598-4e9dec570f3b">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="SOAP-ENV"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<ds:Reference URI="#id-fb70c636-999d-4f3b-9715-d79b7a6f275e">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>xxxxxxxx</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>xxxxxxxxxx</ds:SignatureValue>
<ds:KeyInfo Id="KI-7d2da23a-61b0-4794-b37a-14d996b93ce3">
<wsse:SecurityTokenReference wsu:Id="STR-7b363afe-2dab-4df7-bd1f-9c3f8878d0b6">
<wsse:Reference URI="#UsernameToken-a895d28f-1f3f-4d9f-85e1-aff8400834b4"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-3bd2d6b0-d869-4144-9ad1-19482e525d01">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>xxxxxxxxxxxx</ds:X509IssuerName>
<ds:X509SerialNumber>xxxxxxxxx</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>xxxxxxxxxxx</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#ED-4fc0faad-029e-4dd3-9984-8abace8b1e7d"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<!-- body data-->
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>