J'essaye d'implémenter un client de service Web simple pour un service Web avec WSS activé (corps et timestamp signés). Telle est la politique de WSS:Comment implémenter un client de service Web avec un corps signé et un horodatage pour Weblogic
<wsp:Policy wsu:Id="SignatureRequired"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding>
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssX509V3Token10 />
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToInitiator">
<wsp:Policy>
<sp:WssX509V3Token10 />
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:TripleDesRsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict />
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp />
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:SignedParts>
<sp:Body />
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
La mise en œuvre du client est basé sur un exemple de la documentation Oracle: http://docs.oracle.com/cd/E24329_01/web.1211/e24488/message.htm#WSSOV273 et le service Web est en cours d'exécution sur Weblogic 12c (12.1.2) et Oracle Java 1.7.0_25
package com.example.testclient.mtom;
import weblogic.jws.jaxws.ClientPolicyFeature;
import weblogic.jws.jaxws.policy.InputStreamPolicySource;
import weblogic.security.SSL.TrustManager;
import weblogic.xml.crypto.wss.api.Timestamp;
import weblogic.xml.crypto.wss.api.WSSecurityFactory;
import weblogic.xml.crypto.wss.provider.CredentialProvider;
import weblogic.xml.crypto.wss.WSSecurityContext;
import weblogic.wsee.security.bst.ClientBSTCredentialProvider;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.MTOMFeature;
import org.apache.commons.lang.RandomStringUtils;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.cert.X509Certificate;
import com.example.attachment.TestWebServiceAttachment_Service;
import com.example.attachment.TestWebServiceAttachment;
public class TestWebServiceAttachmentClient {
public TestWebServiceAttachmentClient() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws Throwable {
String username = "User";
String password = "Pass";
String clientCertFile = "src/main/resources/User.jks";
QName operationName = new QName("http://www.example.com/ws/attachment", "fileUpload");
MTOMFeature mtomFeature = new MTOMFeature();
InputStream is = new FileInputStream("src/main/resources/my-wssp1.1-signature-required.xml");
ClientPolicyFeature clientPolicyFeature = new ClientPolicyFeature();
clientPolicyFeature.setEffectivePolicyForOperation(operationName, new InputStreamPolicySource(is));
TestWebServiceAttachment_Service service = new TestWebServiceAttachment_Service();
TestWebServiceAttachment port = service.getTestWebServiceAttachmentPort(clientPolicyFeature, mtomFeature);
//create credential provider and set it to the Stub
List credProviders = new ArrayList();
//client side BinarySecurityToken credential provider -- x509
CredentialProvider cp = new ClientBSTCredentialProvider(clientCertFile, password, username, password);
credProviders.add(cp);
Date date = new Date();
Calendar created = Calendar.getInstance();
created.setTime(date);
Calendar expired = Calendar.getInstance();
expired.setTime(date);
expired.set(Calendar.HOUR_OF_DAY, created.get(Calendar.HOUR_OF_DAY) + 1);
Timestamp timestamp = WSSecurityFactory.newTimestamp("TS-" + RandomStringUtils.randomNumeric(34), created, expired);
Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(WSSConstants.TIMESTAMP_ELEMENT, timestamp);
requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://myserver:7001/ws/TestWebServiceAttachment/1.0");
requestContext.put(WSSecurityContext.TRUST_MANAGER, new TrustManager() {
public boolean certificateCallback(X509Certificate[] chain, int validateErr) {
// need to validate if the server cert can be trusted
return true;
}
});
DataHandler dh = new DataHandler(new FileDataSource("src/main/resources/file1.pdf"));
long response = port.fileUpload("file1.pdf", dh);
System.out.println("response = " + response);
}
}
Le problème est l'horodatage. Je ne sais pas comment ajouter correctement la signature d'horodatage au contexte WSS. Est-ce que quelqu'un sait comment implémenter un tel client? Je reçois l'exception suivante:
Exception in thread "main" com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:125)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:181)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:258)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:117)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:91)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:154)
at com.sun.proxy.$Proxy37.fileUpload(Unknown Source)
Etes-vous sûr que vous utilisez le bon type d'horodatage? Où est défini 'WSSConstants'? 'WSSecurityFactory.newTimestamp' ne retourne probablement pas ce que vous voulez http://docs.oracle.com/cd/E24329_01/apirefs.1211/e24391/weblogic/xml/crypto/wss/api/WSSecurityFactory.html –