6 Replies Latest reply on Apr 26, 2004 4:39 PM by mkprim

    JMS Over Authenticated HTTPS Proxy

    mkprim

      Hi! I've a Client-Server app that uses JBoss Servers and Swing Clients that communicate over JMS. I've already set my JBoss up, and my swing clients are able to connect to the server either using UIL2 Connection Factory or HTTPIL ConnectionFactory.
      So I was able to connect the client with the server using JMS over HTTPS.
      My next step, is to connect to the JBoss server with the client being behind an HTTPS proxy. Well I've configured the https.proxyHost, https.proxyPort and the proxySet in the client, and I can connect to a non-Authenticated proxy.
      But when I try to connect to my proxy with username and password, specifiying the https.proxyUser and https.proxyPassword, the proxy denies the access, not seeing the username and password, as it was never sent.
      I've tryied with an authenticator, but nothing changed.
      What should I do to connect JMS over a tunneled (proxied with authentication) HTTPS?
      Can you PLEASE help me?
      I really need this, because the project may fail without this.
      Thanks a lot,
      Marcelo

        • 1. Re: JMS Over Authenticated HTTPS Proxy

          It is a fundamental practice in debugging that you isolate and elimante
          problems.

          You have already gone some way in this direction, but you missed a step.
          Can you do the proxy authentication using a simple java client
          either http or https?

          You might also find this useful:
          http://jboss.org/wiki/Wiki.jsp?page=ConfigHTTPIL

          • 2. Re: JMS Over Authenticated HTTPS Proxy
            mkprim

            Yes. We have already done the test, and it worked.
            We're currently using j2sdk 1.4.2_01, JBoss 3.2.3, and for the test we needed to setup the default authenticator. Then it works.
            Here's the simple client application code. You can see we are using a ProxyAuthenticator, wich is our own implementation of the java.net.Authenticator, were we override the getPassword(), returning the password passed in the class constructor.

            package com.primary.test;
            
            import java.io.*;
            import java.net.Authenticator;
            import java.net.URL;
            import com.primary.common.communications.ProxyAuthenticator;
            
            class TestHTTPAuth {
             public static void main(String args[]) throws IOException {
            
             System.setProperty("https.auth.digest.validateServer", "true");
             System.setProperty("https.auth.digest.validateProxy", "true");
             System.setProperty("https.proxyHost", "192.168.7.4");
             System.setProperty("https.proxyPort", "3128");
             System.setProperty("https.nonProxyHosts", "");
             Authenticator.setDefault(new ProxyAuthenticator("jero", "jero"));
            
            
             for (int i = 0; i < args.length; i++) {
             URL url = new URL(args);
             InputStream is = url.openStream();
             Reader stream = new InputStreamReader(is);
             int c;
             while ((c = stream.read()) != -1)
             System.out.print((char) c);
             }
             System.exit(0);
             }
            
             }
            


            We removed the "https.proxyUser" and "https.proxyPassword" properties, because they made no effect on the results. For the test, we used the "https://www.yahoo.com" address, and using the "-Djavax.net.debug=all" property, we saw it worked fine.

            We debugged the client code, and it steps into the ProxyAuthenticator getPassword() method. But using the SAME code in the JBoss client, it does not step int that method.
            Maybe this can help.
            It would be useful if we could change the JMS connection sockets properties, like the authentication (or am I wrong with all this supposition?)
            Thanks a lot,
            Marcelo.

            • 3. Re: JMS Over Authenticated HTTPS Proxy

              The HTTPConnectionFactory installs its own Authenticator that uses
              the JAAS user/principal.
              http://cvs.sourceforge.net/viewcvs.py/jboss/jbossmq/src/main/org/jboss/mq/il/http/HTTPClient.java?rev=1.2&view=auto

              • 4. Re: JMS Over Authenticated HTTPS Proxy
                mkprim

                OK, I've tryied to see if I could get it to work with the info you gave, about the Authenticator, but (after hours of test) I couldn't make any progress.
                Any ideas about what should I do to provide my own Username and Password to the authenticator or to override the default authenticator?
                Thanks a lot,
                Marcelo

                • 5. Re: JMS Over Authenticated HTTPS Proxy

                  The http connection factory does not provide a mechanism to override
                  the Authenticator it is hardwired in static initialisation.
                  Maybe you could provide a patch where it uses a system property to get the
                  class name to use as the authenticator (defaulting the jboss one).

                  To use the jboss authenticator, you need to do a jaas login.
                  See the JAAS howto, Scott's article on JAAS or the example in the admin docs.

                  Regards,
                  Adrian

                  • 6. Re: JMS Over Authenticated HTTPS Proxy
                    mkprim

                    Thank you very much! The pay doc / scotts article were very helpfull.
                    Finally I made a JAAS login, in this way:

                    1) Created a simple auth.conf file with a clientLoginModule.
                    2) System.setProperty("java.security.auth.login.config", "file:./auth.conf");
                    3) AppCallbackHandler handler = new AppCallbackHandler(username, password.toCharArray());
                    4) LoginContext lc;
                    try {
                    lc = new LoginContext("MyContext", handler);
                    lc.login();
                    } catch (LoginException e) {
                    e.printStackTrace();
                    }

                    That's it! With all that it worked!

                    Here's the AppCallbackHandler code:

                    import javax.security.auth.callback.Callback;
                    import javax.security.auth.callback.CallbackHandler;
                    import javax.security.auth.callback.NameCallback;
                    import javax.security.auth.callback.PasswordCallback;
                    import javax.security.auth.callback.UnsupportedCallbackException;
                    
                    public class AppCallbackHandler implements CallbackHandler {
                    
                     private String username;
                     private char[] password;
                    
                     public AppCallbackHandler(String username, char[] password)
                     {
                     this.username = username;
                     this.password = password;
                     }
                    
                     public void handle(Callback[] callbacks) throws
                     java.io.IOException, UnsupportedCallbackException
                     {
                     for (int i = 0; i < callbacks.length; i++)
                     {
                     if (callbacks instanceof NameCallback)
                     {
                     NameCallback nc = (NameCallback) callbacks;
                     nc.setName(username);
                     }
                     else if (callbacks instanceof PasswordCallback)
                     {
                     PasswordCallback pc = (PasswordCallback) callbacks;
                     pc.setPassword(password);
                     }
                     else
                     {
                     throw new UnsupportedCallbackException(callbacks, "Unrecognized Callback");
                     }
                     }
                     }
                     }