[jboss-cvs] JBossAS SVN: r85126 - in branches/JBPAPP_4_2_0_GA_CP/server: src/main/org/jboss/naming and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Mar 2 16:53:25 EST 2009


Author: mmoyses
Date: 2009-03-02 16:53:25 -0500 (Mon, 02 Mar 2009)
New Revision: 85126

Modified:
   branches/JBPAPP_4_2_0_GA_CP/server/build.xml
   branches/JBPAPP_4_2_0_GA_CP/server/src/main/org/jboss/naming/HttpNamingContextFactory.java
Log:
JBPAPP-1745: allow HttpNamingContextFactory to connect to secured URLs

Modified: branches/JBPAPP_4_2_0_GA_CP/server/build.xml
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/server/build.xml	2009-03-02 21:41:40 UTC (rev 85125)
+++ branches/JBPAPP_4_2_0_GA_CP/server/build.xml	2009-03-02 21:53:25 UTC (rev 85126)
@@ -429,6 +429,7 @@
         <include name="org/jboss/naming/LinkRefPair.class"/>
         <include name="org/jboss/naming/LinkRefPairObjectFactory.class"/>
         <include name="org/jboss/naming/*NamingContextFactory*.class"/>
+        <include name="org/jboss/naming/DummyConfiguration.class"/>
         <include name="org/jboss/naming/client/**"/>
         <include name="org/jboss/naming/interceptors/*"/>
         <include name="org/jboss/proxy/**"/>

Modified: branches/JBPAPP_4_2_0_GA_CP/server/src/main/org/jboss/naming/HttpNamingContextFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/server/src/main/org/jboss/naming/HttpNamingContextFactory.java	2009-03-02 21:41:40 UTC (rev 85125)
+++ branches/JBPAPP_4_2_0_GA_CP/server/src/main/org/jboss/naming/HttpNamingContextFactory.java	2009-03-02 21:53:25 UTC (rev 85126)
@@ -21,25 +21,34 @@
  */
 package org.jboss.naming;
 
+import java.io.IOException;
 import java.io.InputStream;
-import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.lang.reflect.InvocationTargetException;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.security.Principal;
 import java.util.Hashtable;
-import java.lang.reflect.InvocationTargetException;
+
+import javax.naming.AuthenticationException;
 import javax.naming.Context;
 import javax.naming.Name;
 import javax.naming.NamingException;
+import javax.naming.RefAddr;
 import javax.naming.Reference;
-import javax.naming.RefAddr;
 import javax.naming.spi.InitialContextFactory;
 import javax.naming.spi.ObjectFactory;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
 
 import org.jboss.invocation.InvocationException;
 import org.jboss.invocation.MarshalledValue;
 import org.jboss.invocation.http.interfaces.Util;
 import org.jboss.logging.Logger;
+import org.jboss.security.SecurityConstants;
+import org.jboss.security.auth.callback.UsernamePasswordHandler;
 import org.jnp.interfaces.Naming;
 import org.jnp.interfaces.NamingContext;
 
@@ -62,15 +71,17 @@
    {
       // Parse the Context.PROVIDER_URL
       String provider = (String) env.get(Context.PROVIDER_URL);
-      if( provider.startsWith("jnp:") == true )
+      if (provider.startsWith("jnp:") == true)
          provider = "http:" + provider.substring(4);
-      else if( provider.startsWith("jnps:") == true )
+      else if (provider.startsWith("jnps:") == true)
          provider = "https:" + provider.substring(5);
-      else if( provider.startsWith("jnp-http:") == true )
+      else if (provider.startsWith("jnp-http:") == true)
          provider = "http:" + provider.substring(9);
-      else if( provider.startsWith("jnp-https:") == true )
+      else if (provider.startsWith("jnp-https:") == true)
          provider = "https:" + provider.substring(10);
 
+      tryLogin(env);
+
       URL providerURL = null;
       Naming namingServer = null;
       try
@@ -79,9 +90,9 @@
          // Retrieve the Naming interface
          namingServer = getNamingServer(providerURL);
       }
-      catch(Exception e)
+      catch (Exception e)
       {
-         NamingException ex = new NamingException("Failed to retrieve Naming interface");
+         NamingException ex = new NamingException("Failed to retrieve Naming interface for provider " + provider);
          ex.setRootCause(e);
          throw ex;
       }
@@ -91,6 +102,76 @@
       return new NamingContext(env, null, namingServer);
    }
 
+   /**
+    * if anyone bothers to set the JNDI style authentication stuff then let's use it or 
+    * just ignore it if they don't (they can still use JAAS style if they want)
+    */
+   private void tryLogin(Hashtable env) throws NamingException
+   {
+      // Get the login configuration name to use, initially set to default.
+      String protocol = SecurityConstants.DEFAULT_APPLICATION_POLICY;
+      Object prop = env.get(Context.SECURITY_PROTOCOL);
+      if (prop != null)
+         protocol = prop.toString();
+
+      // Get the login principal and credentials from the JNDI env
+      Object credentials = env.get(Context.SECURITY_CREDENTIALS);
+      Object principal = env.get(Context.SECURITY_PRINCIPAL);
+      if (principal == null || credentials == null)
+      {
+         return; //don't bother and don't throw any exceptions
+      }
+      try
+      {
+         // Get the principal username
+         String username;
+         if (principal instanceof Principal)
+         {
+            Principal p = (Principal) principal;
+            username = p.getName();
+         }
+         else
+         {
+            username = principal.toString();
+         }
+
+         UsernamePasswordHandler handler = new UsernamePasswordHandler(username, credentials);
+         Configuration conf = getConfiguration();
+         // Do the JAAS login
+         LoginContext lc = new LoginContext(protocol, null, handler, conf);
+         lc.login();
+      }
+      catch (LoginException e)
+      {
+         AuthenticationException ex = new AuthenticationException("Failed to login using protocol=" + protocol);
+         ex.setRootCause(e);
+         throw ex;
+      }
+
+   }
+
+   /**
+    * Either call Configuration.getConfiguration() like LoginContext does, or if that fails due to no
+    * auth.conf or whatever config file, then return DummyConfiguration which does what we expect for 
+    * UsernamePasswordHandler. 
+    */
+   private Configuration getConfiguration()
+   {
+      Configuration conf = null;
+      try
+      {
+         conf = Configuration.getConfiguration();
+      }
+      catch (Exception e)
+      {
+         if (e.getCause() instanceof IOException)
+         { //no auth.conf or whatever so we make our own dummy
+            conf = new DummyConfiguration();
+         }
+      }
+      return conf;
+   }
+
    // ObjectFactory implementation ----------------------------------
    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
       Hashtable env)
@@ -112,23 +193,23 @@
     * @throws IOException thrown on any trasport failure
     * @throws InvocationTargetException throw on failure to install a JSSE host verifier
     * @throws IllegalAccessException throw on failure to install a JSSE host verifier
-    */ 
+    */
    private Naming getNamingServer(URL providerURL)
       throws ClassNotFoundException, IOException, InvocationTargetException,
          IllegalAccessException
    {
       // Initialize the proxy Util class to integrate JAAS authentication
       Util.init();
-      if( log.isTraceEnabled() )
-         log.trace("Retrieving content from : "+providerURL);
+      if (log.isTraceEnabled())
+         log.trace("Retrieving content from : " + providerURL);
 
       HttpURLConnection conn = (HttpURLConnection) providerURL.openConnection();
       Util.configureHttpsHostVerifier(conn);
       Util.configureSSLSocketFactory(conn);
       int length = conn.getContentLength();
       String type = conn.getContentType();
-      if( log.isTraceEnabled() )
-         log.trace("ContentLength: "+length+"\nContentType: "+type);
+      if (log.isTraceEnabled())
+         log.trace("ContentLength: " + length + "\nContentType: " + type);
 
       InputStream is = conn.getInputStream();
       ObjectInputStream ois = new ObjectInputStream(is);
@@ -136,17 +217,17 @@
       ois.close();
 
       Object obj = mv.get();
-      if( (obj instanceof Naming) == false )
+      if ((obj instanceof Naming) == false)
       {
-         String msg = "Invalid reply content seen: "+obj.getClass();
+         String msg = "Invalid reply content seen: " + obj.getClass();
          Throwable t = null;
-         if( obj instanceof Throwable )
+         if (obj instanceof Throwable)
          {
             t = (Throwable) obj;
-            if( t instanceof InvocationException )
-               t = ((InvocationException)t).getTargetException();
+            if (t instanceof InvocationException)
+               t = ((InvocationException) t).getTargetException();
          }
-         if( t != null )
+         if (t != null)
             log.warn(msg, t);
          else
             log.warn(msg);
@@ -157,3 +238,23 @@
       return namingServer;
    }
 }
+
+/**
+ * When no configuration file is found (we get IOException as the cause of a SecurityException),
+ * we make this dummy that uses the default ClientLoginModule as required with no options.  
+ *
+ */
+class DummyConfiguration extends Configuration
+{
+   public AppConfigurationEntry[] getAppConfigurationEntry(String name)
+   {
+      return new AppConfigurationEntry[]
+      {new AppConfigurationEntry("org.jboss.security.ClientLoginModule",
+            AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new java.util.HashMap())}; //return a big dummy entry saying use the jboss login module that takes username/password
+   }
+
+   public void refresh()
+   {
+      //do nothing 
+   }
+}




More information about the jboss-cvs-commits mailing list