Uploaded image for project: 'Spring Web Services'
  1. Spring Web Services
  2. SWS-991

MessageSender incompatibility in SSL Mutual Auth and Basic Auth scenario

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 2.4.0
    • Fix Version/s: None
    • Component/s: Core, Documentation
    • Labels:
      None
    • Environment:
      Java 8 (OS irrelevant)

      Description

      Environment prerequisites

      We are integrating with a client that provides WSDL for their services. Their setup involves:

      • a properly signed server SSL certificate (Symantec Class 3 - G4, Verisign G5 root)
      • a mutual-authentication setup, where we produced a hostname CSR and they signed with their own (internal) CA, not certified by known root certificates
      • a load balancer (we assume NGINX but could be a heavy iron one) handling the SSL & Mutual Auth setup and authentication
      • an internal WS (Spring Boot) server application presenting Basic Authentication requests to the client

      Action Plan

      Using WS to generate and create client, we configure the WebServiceTemplate with the relevant jaxb2 marshaller/unmarshaller and proceed to configure message senders.

      Two senders were configured:

      • HttpsUrlConnectionMessageSender, for the keystore/truststore configuration and hostname verifier
      • HttpComponentsMessageSender, for the Basic Authentication to the end service

      Issue manifestation

      It seems that using the webServiceTemplate.setMessageSenders() call to set the array of message senders, the combination of the two produces weird results:

      • if the array contains the HttpsUrlConnectionMessageSender first, the SSL mutual auth consistently fails - the SSL trace shows that we do not produce a client certificate at all
      • if the array contains the HttpComponentsMessageSender first, the Basic Auth fails - there is no Basic Auth header added to the request. However, the SSL client mutual auth succeeds!

      Conclusion

      We believe that these two message senders are incompatible. Whichever goes last overrides (or uses different URL factories or something) and makes the first configuration to disappear. This is not evident in documentation anywhere and for our case it took us more than 2 days debugging with the client (initially thinking it was an SSL configuration issue on their side) to understand that this was an incompatibility.

      Available workaround

      In our scenario of SSL Mutual Auth and Basic Auth, we proceeded to add a custom override of the prepareConnection() call of the HttpsUrlConnectionMessageSender as below:

      @Override
      protected void prepareConnection(HttpURLConnection connection) throws IOException {
      	super.prepareConnection(connection);
      	String userCredentials = name + ":" + password;
      	String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
      	connection.setRequestProperty ("Authorization", basicAuth);
      }
      

      By doing that, we used only the SSL configuration MessageSender which successfully passed the client Mutual Authentication and also configured the header for the Basic Authentication.

      PS: Flagging as major due to lack of documentation and complexity of the debugging involved.

        Activity

        No work has yet been logged on this issue.

          People

          • Assignee:
            Unassigned
            Reporter:
            thanosa75 Thanos Angelatos
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: