I am trying to make a client to a SOAP with Spring Boot. The requests must have a digital certificate (public key) in the header, but when I try to add it to the secuityInterceptor.
I'm deploying the client on a WildFly server, I thought maybe I would have to add the certificate to the server somehow but I don't know for sure. In principle it is in the resources folder of the project and when generating the war it is still there.
Config:
private static final Resource KEYSTORE_LOCATION = new ClassPathResource("client-keystore.jks");
private static final String KEYSTORE_PASSWORD = "password";
private static final String KEY_ALIAS = "alias";
@Bean
TrustManagersFactoryBean trustManagers() throws Exception {
TrustManagersFactoryBean factoryBean = new TrustManagersFactoryBean();
factoryBean.setKeyStore(keyStore().getObject());
return factoryBean;
}
@Bean
HttpsUrlConnectionMessageSender messageSender() throws Exception {
HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
KeyManagersFactoryBean keyManagersFactoryBean = new KeyManagersFactoryBean();
keyManagersFactoryBean.setKeyStore(keyStore().getObject());
keyManagersFactoryBean.setPassword(KEYSTORE_PASSWORD);
keyManagersFactoryBean.afterPropertiesSet();
sender.setKeyManagers(keyManagersFactoryBean.getObject());
sender.setTrustManagers(trustManagers().getObject());
return sender;
}
@Bean
KeyStoreFactoryBean keyStore() throws GeneralSecurityException, IOException {
KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
factoryBean.setLocation(KEYSTORE_LOCATION);
factoryBean.setPassword(KEYSTORE_PASSWORD);
return factoryBean;
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("contextpath");
return marshaller;
}
@Bean
Wss4jSecurityInterceptor securityInterceptor() throws Exception {
Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
securityInterceptor.setSecurementActions("Signature");
securityInterceptor.setSecurementUsername(KEY_ALIAS);
securityInterceptor.setSecurementPassword(KEYSTORE_PASSWORD);
securityInterceptor.setSecurementSignatureCrypto(cryptoFactoryBean().getObject());
return securityInterceptor;
}
@Bean
SOAPConnector client() throws Exception {
SOAPConnector client = new SOAPConnector();
System.out.println("client(): ");
client.setInterceptors(new ClientInterceptor[] { securityInterceptor() });
client.setMessageSender(messageSender());
client.setMarshaller(marshaller());
client.setUnmarshaller(marshaller());
client.afterPropertiesSet();
return client;
}
Error:
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during Signature:
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:174)
at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:238)
at org.springframework.ws.soap.security.wss4j2.Wss4jHandler.doSenderAction(Wss4jHandler.java:58)
at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:609)
... 80 more
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:615)
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:166)
... 83 more
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:696)
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:558)
In case it is useful, I am basing myself on this repository to make the client
I think the error is that the functions I'm using are to add certificates with a private key but I try to do it with a public one, in that case I don't know how to add the public one
this is the sing of the setSecurementUsername
method:
public void setSecurementUsername(String securementUsername)
Sets the username for securement username token or/and the alias of the private key for securement signature