10 Replies Latest reply on Mar 9, 2011 6:11 PM by sat.ena

    How can I do mutual SSL when using JBoss as Web service clie

    zhijun

      Hi,

      I'm running a Web Service client on JBoss 4.0.5 and JBossWS1.0.4GA.

      The Web service I'm trying to consume requires mutual SSL authentication.

      I have created keytore, with the private key, the certificate in it. I also added the Web service provider's certificate to this keystore as a trusted certificate.

      I have configured my server.xml file to include the following:

      <Connector port="8443" address="${jboss.bind.address}"
       maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
       emptySessionPath="true"
       scheme="https" secure="true" clientAuth="false"
       keystoreFile="${jboss.server.home.dir}/conf/jboss.keystore"
       keystoreType="jks"
       keystorePass="password" sslProtocol = "TLS" />


      But I guess this is not good enough (I don't feel that way either). So when I called the service, the error message said that my request did not present a certificate.

      How do I configure my Web service client, or write some code, to make sure that my web service request (to a https URL) will present a client certificate?

      I saw that you could specify user ID and password in the <service-ref> tag if you are using basic authentication. But I need certificate-based authentication and couldn't find an example.

      SOAP signing doesn't help me either because the Web service provider expects the certificate to be presented during the SSL handshake.

      Thanks!


        • 1. Re: How can I do mutual SSL when using JBoss as Web service
          peterj

          Try adding the following JVM options to the client:

          -Djavax.net.ssl.keyStore=xxx -Djavax.net.ssl.keyStorePassword=yyy

          where xxx is the filename for the keystore and yyy is the password for that keystore.

          • 2. Re: How can I do mutual SSL when using JBoss as Web service
            zhijun

            Thanks for the information.

            If I have multiple certificates in the keystore, how do I specify which one to use?

            • 3. Re: How can I do mutual SSL when using JBoss as Web service
              zhijun

              Actually since I'm running my Web service client in JBoss as a JSP page, where should I set up the keystore file and password to use as a Web service client?

              The set up in server.xml is apparently for managing the keys and certificates for JBoss as a server.

              Thanks!

              • 4. Re: How can I do mutual SSL when using JBoss as Web service
                peterj

                I don't think that you have to. The client and the server will negotiate on which certificate to use. If course, they have to have at least one matching certificate.

                • 5. Re: How can I do mutual SSL when using JBoss as Web service
                  peterj

                  I'm not sure how you go about doing this if both the client and the web service are in the same app server. Try adding the JVM options to the command line that starts JBoss and see if that works.

                  • 6. Re: How can I do mutual SSL when using JBoss as Web service
                    zhijun

                    Actually I'm only running the Web service client on JBoss. The Web service itself is running remotely on a Sun Solaris environment.

                    Thanks.

                    • 7. Re: How can I do mutual SSL when using JBoss as Web service
                      zhijun

                      I have tried everything I can think of.
                      - Added the -Djavax.net.ssl.keystore=.... properties in my command to start the JBoss JVM.
                      - Added the following in my web.xml file

                      <service-ref>
                      <service-ref-name>RemoteWebService</service-ref-name>
                      <service-interface>javax.xml.rpc.Service</service-interface>
                      <wsdl-file>RemoteWebService.wsdl</wsdl-file>
                      <jaxrpc-mapping-file>META-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
                      <port-component-ref>
                      <service-endpoint-interface>
                      com.zzz.MyWebService
                      </service-endpoint-interface>
                      <call-property>
                      <prop-name>javax.net.ssl.keyStore</prop-name>
                      <prop-value>my.keystore</prop-value>
                      </call-property>
                      <call-property>
                      <prop-name>javax.net.ssl.keyStorePassword</prop-name>
                      <prop-value>password</prop-value>
                      </call-property>
                      <call-property>
                      <prop-name>javax.net.ssl.trustStore</prop-name>
                      <prop-value>keystore.trust</prop-value>
                      </call-property>
                      <call-property>
                      <prop-name>javax.net.ssl.trustStorePassword</prop-name>
                      <prop-value>password</prop-value>
                      </call-property>
                      </port-component-ref>
                      </service-ref>

                      - I added the following lines in my Web service client that will run in JBoss
                      System.setProperty("javax.net.ssl.keyStore", "/opt/jboss/jas405/server/myserver/conf/my.keystore");
                       System.setProperty("javax.net.ssl.keyStorePassword", "password");
                       System.setProperty("javax.net.ssl.trustStore", "/opt/jboss/jas405/server/myserver/conf/trust.keystore");
                       System.setProperty("javax.net.ssl.trustStorePassword", "password");


                      Now when I ran my Web service client in JBoss and when I tried to call the web service, I continued to get the following error in server log:


                      2007-03-14 10:37:31,054 DEBUG [org.jboss.remoting.Client] invoke called, but our invoker is disconnected, discarding and fetching another fresh invoker for: InvokerLocator [https://....:1443/.../services/MyWebService]
                      2007-03-14 10:37:31,054 DEBUG [org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker] connect called for: org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker@154fc43
                      2007-03-14 10:37:31,063 DEBUG [org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker] Setting request header with SOAPAction : ""
                      2007-03-14 10:37:31,063 DEBUG [org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker] Setting request header with Content-Type : text/xml; charset=UTF-8
                      2007-03-14 10:37:31,098 DEBUG [org.jboss.ws.soap.SOAPContentElement] Transitioning to dom-valid state, MTOM disabled
                      2007-03-14 10:37:31,132 DEBUG [org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker] Error invoking http client invoker.
                      org.jboss.ws.WSException: Invalid HTTP server response [403] - Forbidden
                       at org.jboss.ws.binding.soap.SOAPMessageUnMarshaller.read(SOAPMessageUnMarshaller.java:73)
                       at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:175)
                       at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:81)
                       at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:143)
                       at org.jboss.remoting.Client.invoke(Client.java:525)
                       at org.jboss.remoting.Client.invoke(Client.java:488)
                       at org.jboss.ws.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:189)
                       at org.jboss.ws.jaxrpc.CallImpl.invokeInternal(CallImpl.java:687)
                       at org.jboss.ws.jaxrpc.CallImpl.invoke(CallImpl.java:404)
                       at org.apache.jsp.TestWS1_jsp._jspService(TestWS1_jsp.java:86)
                       at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                       at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:334)
                       at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                       at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
                       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
                       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
                       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
                       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
                       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
                       at java.lang.Thread.run(Thread.java:595)
                      2007-03-14 10:37:31,133 ERROR [org.jboss.ws.jaxrpc.CallImpl] Call invocation failed with unkown Exception
                      javax.xml.soap.SOAPException: Could not transmit message
                       at org.jboss.ws.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:204)
                       at org.jboss.ws.jaxrpc.CallImpl.invokeInternal(CallImpl.java:687)
                       at org.jboss.ws.jaxrpc.CallImpl.invoke(CallImpl.java:404)
                       at org.apache.jsp.TestWS1_jsp._jspService(TestWS1_jsp.java:86)
                       at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                       at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:334)
                       at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                       at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
                       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
                       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
                       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
                       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
                       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
                       at java.lang.Thread.run(Thread.java:595)
                      Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker.
                       at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:201)
                       at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:81)
                       at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:143)
                       at org.jboss.remoting.Client.invoke(Client.java:525)
                       at org.jboss.remoting.Client.invoke(Client.java:488)
                       at org.jboss.ws.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:189)
                       ... 28 more
                      Caused by: org.jboss.ws.WSException: Invalid HTTP server response [403] - Forbidden
                       at org.jboss.ws.binding.soap.SOAPMessageUnMarshaller.read(SOAPMessageUnMarshaller.java:73)
                       at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:175)
                       ... 33 more
                      2007-03-14 10:37:31,135 DEBUG [org.jboss.ws.soap.MessageContextAssociation] popMessageContext: org.jboss.ws.soap.SOAPMessageContextImpl@e782a8
                      2007-03-14 10:37:31,135 INFO [STDOUT] Call invocation failed: Could not transmit message; nested exception is:
                       javax.xml.soap.SOAPException: Could not transmit message


                      I would highly appreciate it if anyone can provide any clue as to what I'm missing or what might be the problem.

                      Thanks!

                      • 8. Re: How can I do mutual SSL when using JBoss as Web service
                        jeckles933

                        I have a similiar problem. I can call a ws via https using stand alone project just fine. Run same code in jboss container, get error

                        Can not connect http client invoker. Invalid HTTP server response [403] - Service Error. Response: Service Error/403

                        Side note: to get around the multiple keystores, you can use this approach

                        HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);

                        you'll find a bunch of posts on it. i can provide more detail if needed.
                        if you find solution to 403 problem, please post it.

                        • 9. Re: How can I do mutual SSL when using JBoss as Web service
                          richard.anywhere

                          As this is high on the Google search results for "jboss WS Client Mutual Certificate" and doesn't have a posted resolution, I thought I'd post what I did to get everything working.

                           

                          The basic principle here is that BOTH the Web Service (WS) and the Web Service Client (WS-C) need to have the other's key stored as "trusted". Specifically, the following needs to be set ON BOTH SIDES:

                           

                            -Djavax.net.ssl.trustStore=/home/dev/.truststore

                            -Djavax.net.ssl.trustStorePassword=changeit

                           

                          Now, both sides also need their own keystore. The key of WS needs to be trusted by WS-C and vice-versa. Set the following ON BOTH SIDES:

                           

                            -Djavax.net.ssl.keyStore=/home/dev/.keystore

                            -Djavax.net.ssl.keyStorePassword=changeit

                           

                          To get something up and running quickly, use the same keystore and truststore on both sides ... even simpler, you can create a new keystore and simply copy the output file to also become the truststore:

                           

                            $JAVA_HOME/bin/keytool -genkey -alias jboss -keyalg RSA

                            cp .keystore .truststore

                           

                          You can also do an explicit import to load a key into a truststore:

                           

                            keytool -import -alias jboss -file certificate -storepass changeit -keystore .truststore

                           

                          This all worked for me. If possible, please provide feedback on gotchas or success stories relating to the above.

                           

                          All the best,

                          Richard

                          • 10. Re: How can I do mutual SSL when using JBoss as Web service
                            sat.ena

                            Could anyone post resolution on the above org.jboss.ws.WSException: Invalid HTTP server response [403] - Forbidden error. I am facing the same issue currently. Many thanks in advance for your help.