Spring WS Client-使用服务器和客户端证书进行身份验证


I need to be able to do a "client cert" authentication for a SOAP service.

我正在使用Spring WS.我有:一个my.key,一个myCA.pem和一个myClient.crt.

I'm using Spring WS. I have: a my.key, a myCA.pem, and a myClient.crt.


This is my relevant Java piece of code (I know it's still messy but I'm just trying to get it to work first):

public TheResponse doIt(TheRequest request) {
  log.info("Sending request...");
  try {
    InputStream is = new FileInputStream(new File("src/main/resources/keystore.jks"));
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(is, "keystore!passwd".toCharArray());
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());

    InputStream is1 = new FileInputStream(new File("src/main/resources/truststore.jks"));
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(is1, "truststore!passwd".toCharArray());
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

    HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();

    return (TheResponse) getWebServiceTemplate().marshalSendAndReceive(request,
        new SoapActionCallback("https://domain/tld/icc/SomePathDownTheLine"));
  } catch (Throwable e) {
    log.error("Sh*t didn't work due to:", e);
    throw new GatewayConnectionException(String.format("Unexpected error while sending request [%s]", e.getMessage()));


This is how I'm building the trust- and key- stores:

# KeyStore
$ openssl pkcs12 -export -in myClient.crt -inkey my.key -out keystore.p12 -name my_key -CAfile myCA.pem -caname root

$ keytool -importkeystore -deststorepass keystore!passwd -destkeypass keystore!passwd -destkeystore keystore.jks \
  -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass keystore!passwd -alias my_key

# Trustore (using truststore!passwd)
$ keytool -import -trustcacerts -alias my_ca -file myCA.pem -keystore truststore.jks

$ keytool -import -trustcacerts -alias my_cc -file myClient.crt -keystore truststore.jks


...and these are the verification steps:

$ keytool -list -keystore keystore.jks -storepass ********

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

my_key, Oct 17, 2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): 1A:9D:6A:65:. . .:E6:C1:90

$ keytool -list -keystore truststore.jks -storepass ********

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

my_cc, Oct 17, 2017, trustedCertEntry,
Certificate fingerprint (SHA1): 1A:9D:6A:65:. . .:E6:C1:90
my_ca, Oct 17, 2017, trustedCertEntry,
Certificate fingerprint (SHA1): 36:82:F7:AB:. . .:70:B2:6C

...但是,无论如何,每当我请求SOAP操作时,我都会取回HTTP 401(未经授权)-org.springframework.ws.client.WebServiceTransportException: Unauthorized [401].

...but still, whenever I request the SOAP action I'm getting back an HTTP 401 (Unauthorized) — org.springframework.ws.client.WebServiceTransportException: Unauthorized [401].


Any clue(s)? By the way, I'm pretty much following this guide. I'm not very familiar with SSL certificates and all that stuff.


SSL握手正常工作.我可以通过设置-Djavax.net.debug=all VM选项来查看其工作方式.现在发生的事情是,无论所有这些安全性如何,服务器都还需要用户名和密码.

The SSL handshake is working correctly. I can see how it works by setting the -Djavax.net.debug=all VM option. What's happening now is that, regardless all of this security, the server also needs a username and password.

 1 条回答