0 Replies Latest reply on Nov 12, 2004 3:31 AM by Thorsten Kitz

    Client JNDI Loogkup with HTTP authorization fails

    Thorsten Kitz Newbie

      Configuration: JBoss 3.2.5 (also checked in 3.2.6) running on Windows
      2000


      Hi,

      I have got a problem regarding the JNDI access over HTTP with authorization. Whenever I try to run the attached code (see end of posting), I get the following stacktrace:

      javax.naming.CommunicationException: Could not obtain connection to any of these urls: http://localhost:8080/invoker/restricted/JNDIFactory
       at
      org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1198)
       at
      org.jnp.interfaces.NamingContext.lookup(NamingContext.java:516)
       at
      org.jnp.interfaces.NamingContext.lookup(NamingContext.java:509)
       at javax.naming.InitialContext.lookup(Unknown Source)
       at de.eplus.JMSAuthTest.<init>(JMSAuthTest.java:62)
       at de.eplus.JMSAuthTest.main(JMSAuthTest.java:40)


      It seems to be, that there is an error in "org.jnp.interfaces.NamingContext.checkRef". The following is an extract of this method:

      private void checkRef(Hashtable refEnv)
       throws NamingException
       {
       if (naming == null)
       {
       String host = "localhost";
       int port = 1099;
      
       // Locate naming service
       String urls = (String) refEnv.get (Context.PROVIDER_URL);
       if (urls != null && urls.length () > 0)
       {
       StringTokenizer tokenizer = new StringTokenizer (urls,
      ",");
       while (tokenizer.hasMoreElements ())
       {
       String url = tokenizer.nextToken ();
       // Parse the url into a host:port form, stripping any
      protocol
       Name urlAsName = getNameParser("").parse(url);
       String server = parseNameForScheme(urlAsName); // <-- ( 1 )
       if( server != null )
       url = server;
       int colon = url.indexOf (':'); // <-- ( 2 )
       if( colon < 0 )
       {
       host = url;
       }
       else
       {
       host = url.substring (0, colon).trim();
       try
       {
       port = Integer.parseInt (url.substring
      (colon+1).trim
      ());
       }
       catch (Exception ex)
       {
       // Use default;
       }
       }
       try
       {
       // Get server from cache
       naming = getServer (host, port, refEnv); // <-- ( 3 )
       }
       catch(Exception e)
       {
       log.warn("Failed to connect to "+host+":"+port, e);
       }
       }
      [..]


      In (1) the NamingContext class tried to strip off the "http://" from the URL. If you look into parseNameForScheme(), it only tests for the following prefixes "java:", "jnp:", "jnps:", "jnp-http:" and "jnp-https", so it returns null for a "http://..." URL.
      In (2) and following, the URL gets splittet to the host part, which is the part before the first colon, in this case "http" and the port, which is the part next to the colon, in this case the rest of the URL. Obviously this can't be converted to Integer, resulting in an Exception and using the "Default", which is port 1099 (normal JNDI).
      In (3) the client tries to test connect to the server by using the host and port values, which is here incorrectly "http:1099".

      Do I use the wrong URL protocol?

      The Server btw runs fine. If I try to connect to the URL by a browser application, it requests credentials, so there is no network configuration
      or server problem. If anybody needs my server setup, I will happily post it here, but I skip it for now.

      Greetings,

      Thorsten.

      -----------------------------------------------------------------------------

      Test-Client Code:

      JMSAuthTest() {
      
       QueueConnectionFactory qcf = null;
       QueueConnection qc = null;
       Queue q = null;
       QueueSession s = null;
      
       Properties env = new Properties();
       env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
      "org.jboss.security.jndi.LoginInitialContextFactory");
      
      env.setProperty(Context.PROVIDER_URL,"http://localhost:8080/invoker/restricted/JNDIFactory");
       env.setProperty(Context.SECURITY_PRINCIPAL,"admin");
       env.setProperty(Context.SECURITY_CREDENTIALS,"password");
      
      env.setProperty(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
       env.setProperty("jnp.disableDiscovery","true");
       try {
       Context ctx = new InitialContext(env);
       System.out.println("Created InitialContext,
      env="+env);
      
       q = (Queue)ctx.lookup("queue/testQueue");
       qcf =
      (QueueConnectionFactory)ctx.lookup("ConnectionFactory");
       qc = qcf.createQueueConnection("test","testPassword");
      // <--- this is the line, where the exception is thrown
       s = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
      
       // Create a Test Message
       SimpleServiceMessage smsg = new SimpleServiceMessage();
       smsg.setAttribute("ATTRIBUTE_1", "10");
       smsg.setAttribute("ATTRIBUTE_2", "20");
       ObjectMessage omsg = s.createObjectMessage(smsg);
       QueueSender sender = s.createSender(q);
       sender.send(omsg
       , DeliveryMode.PERSISTENT
       , Message.DEFAULT_PRIORITY
       , Message.DEFAULT_TIME_TO_LIVE);
      
       } catch (NamingException e1) {
       e1.printStackTrace();
       } catch (JMSException e) {
       e.printStackTrace();
       }
      }