I'm using CXF 3.1.5, trying to send a request to a STS server, the STS server has a policy , the related part is as following
<wsp:Policy>
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
</wsp:Policy>
so in the request CXF sends to the STS server, the signature key looks like that:
<wsse:SecurityTokenReference wsu:Id="...">
<wsse:KeyIdentifier EncodingType="..."ValueType="...#ThumbprintSHA1">...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
but I want to change the SecurityTokenReference into that
<wsse:SecurityTokenReference>
<wsse:Reference URI="..." ValueType="...#**X509v3**"/>
</wsse:SecurityTokenReference>
it refers to the BinarySecurityToken which is a X.509 Certificate
So what should I do? I found something about PolicyBasedWSS4JOutInterceptor and PolicyBasedWSS4JInInterceptor , but don't known how they works.
Thanks a lots!
You need a certificate issued by a CA accepted by your server to sign the SOAP request. You can use CXF with WSS4JOutInterceptor
This is the configuration to use WSS4J with CXF. Omit the part of creating the keystore
Set WSS4J properties (adjust to your policy)
outProps.put("action", "Signature");
outProps.put("user", certificateAlias);
outProps.put("passwordType", "PasswordText");
outProps.put("signaturePropFile", propertiesFile);
outProps.put("signatureKeyIdentifier","DirectReference");
outProps.put("passwordCallbackRef",clientPasswordCallback);
propertiesFile
contains the path to a properties file where is configured the path to the keystore
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=changeit
org.apache.ws.security.crypto.merlin.file=keystore.jks
ClientPasswordCallback
performs a callback from wss4j to get the password of the certificate
public class ClientPasswordCallback implements CallbackHandler {
String password = ...; //Configure the password
public void handle(Callback[] callbacks) {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
pc.setPassword(password);
}
}
}
Configure the CXF client using the WebService port
Client client = ClientProxy.getClient(port);
Endpoint cxfEndpoint = client.getEndpoint();
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
//Include LoggingOutInterceptor to log the soap message
cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor());
And finally call your service
port.myService();
@pedrofb, thanks a lot for your help. unfortunately, I still got two BinarySecurityToken Elements and I couldn't use an alternative policy file.
but I found a solution here: How to get incoming & outgoing soap xml in a simple way using Apache CXF?
It provides a solution for me to edit the soap envelop right before CXF sends it out. It's not very good, but it's the best solution I got.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.