glenn       2003/01/10 17:57:39

  Modified:    catalina/src/share/org/apache/catalina/realm JNDIRealm.java
               webapps/docs realm-howto.xml
  Log:
  Port JNDIRealm alternateURL patch to Tomcat 5
  
  Revision  Changes    Path
  1.4       +122 -30   
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/JNDIRealm.java
  
  Index: JNDIRealm.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/JNDIRealm.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JNDIRealm.java    19 Nov 2002 01:27:59 -0000      1.3
  +++ JNDIRealm.java    11 Jan 2003 01:57:39 -0000      1.4
  @@ -70,6 +70,7 @@
   import java.util.Hashtable;
   import java.util.List;
   import javax.naming.Context;
  +import javax.naming.CommunicationException;
   import javax.naming.NameNotFoundException;
   import javax.naming.NamingEnumeration;
   import javax.naming.NamingException;
  @@ -98,6 +99,10 @@
    *     element in the top level <code>DirContext</code> that is accessed
    *     via the <code>connectionURL</code> property.</li>
    *
  + * <li>If a socket connection can not be made to the <code>connectURL</code>
  + *     an attempt will be made to use the <code>alternateURL</code> if it
  + *     exists.</li>
  + *
    * <li>Each user element has a distinguished name that can be formed by
    *     substituting the presented username into a pattern configured by the
    *     <code>userPattern</code> property.</li>
  @@ -188,13 +193,11 @@
   
       // ----------------------------------------------------- Instance Variables
   
  -
       /**
        *  The type of authentication to use
        */
       protected String authentication = null;
   
  -
       /**
        * The connection username for the server we will contact.
        */
  @@ -244,15 +247,15 @@
        * The protocol that will be used in the communication with the directory 
server.
        */
       protected String protocol = null;
  -    
  -    
  +
  +
       /**
        * How should we handle referrals?  Microsoft Active Directory can't handle 
        * the default case, so an application authenticating against AD must 
        * set referrals to "follow".
        */
       protected String referrals = null;
  -
  +    
       
       /**
        * The base element for user searches.
  @@ -339,11 +342,19 @@
        */
       protected boolean roleSubtree = false;
   
  -
  +    /** 
  +     * An alternate URL, to which, we should connect if connectionURL fails.
  +     */
  +    protected String alternateURL;  
  +    
  +    /**
  +     * The number of connection attempts.  If greater than zero we use the
  +     * alternate url.
  +     */
  +    protected int connectionAttempt = 0;
   
       // ------------------------------------------------------------- Properties
   
  -
       /**
        * Return the type of authentication to use.
        */  
  @@ -353,7 +364,6 @@
       
       }
    
  - 
       /**
        * Set the type of authentication to use.
        *
  @@ -364,8 +374,7 @@
           this.authentication = authentication;
           
       }
  -    
  -    
  +      
       /**
        * Return the connection username for this Realm.
        */
  @@ -463,7 +472,6 @@
    
       }
       
  -    
       /**
        * Set the protocol for this Realm.
        *
  @@ -491,7 +499,7 @@
       public void setReferrals (String referrals) {
           this.referrals = referrals;
       }
  -
  +    
   
       /**
        * Return the base element for user searches.
  @@ -723,6 +731,28 @@
   
       }
   
  +    /**
  +     * Getter for property alternateURL.
  +     *
  +     * @return Value of property alternateURL.
  +     */
  +    public String getAlternateURL() {
  +        
  +        return this.alternateURL;
  +        
  +    }    
  +
  +    /**
  +     * Setter for property alternateURL.
  +     *
  +     * @param alternateURL New value of property alternateURL.
  +     */
  +    public void setAlternateURL(String alternateURL) {
  +        
  +        this.alternateURL = alternateURL;
  +        
  +    }
  +    
   
       // ---------------------------------------------------------- Realm Methods
   
  @@ -743,15 +773,41 @@
       public Principal authenticate(String username, String credentials) {
   
           DirContext context = null;
  +        Principal principal = null;
   
           try {
   
               // Ensure that we have a directory context available
               context = open();
  -
  -            // Authenticate the specified username if possible
  -            Principal principal = authenticate(context,
  -                                               username, credentials);
  +            
  +            // Occassionally the directory context will timeout.  Try one more
  +            // time before giving up.
  +            try {
  +                
  +                // Authenticate the specified username if possible
  +                principal = authenticate(context, username, credentials);
  +                
  +            } catch (CommunicationException e) {
  +                
  +                // If not a "Socket closed." error then rethrow.
  +                if (e.getMessage().indexOf("Socket closed") < 0)                    
  +                    throw(e);
  +                
  +                // log the exception so we know it's there.
  +                log(sm.getString("jndiRealm.exception"), e);
  +                
  +                // close the connection so we know it will be reopened.
  +                if (context != null)
  +                    close(context);
  +                
  +                // open a new directory context.
  +                context = open();
  +                
  +                // Try the authentication again.
  +                principal = authenticate(context, username, credentials);
  +                
  +            }
  +                
   
               // Release this context
               release(context);
  @@ -1365,27 +1421,63 @@
           if (context != null)
               return (context);
   
  -        // Establish a connection and retrieve the initial context
  -        if (debug >= 1)
  -            log("Connecting to URL " + connectionURL);
  +        try {
  +            
  +            // Ensure that we have a directory context available
  +            context = new InitialDirContext(getDirectoryContextEnvironment());
  +                
  +        } catch (NamingException e) {
  +                
  +            connectionAttempt = 1;
  +                
  +            // log the first exception.
  +            log(sm.getString("jndiRealm.exception"), e);
  +                
  +            // Try connecting to the alternate url.
  +            context = new InitialDirContext(getDirectoryContextEnvironment());
  +        
  +            // reset it in case the connection times out.
  +            // the primary may come back.
  +            connectionAttempt = 0;
  +    
  +        }
  +        
  +        return (context);
  +
  +    }
  +    
  +    /**
  +     * Create our directory context configuration.
  +     *
  +     * @return java.util.Hashtable the configuration for the directory context.
  +     */
  +    protected Hashtable getDirectoryContextEnvironment() {
  +        
           Hashtable env = new Hashtable();
  +
  +        // Configure our directory context environment.
  +        if (debug >= 1 && connectionAttempt == 0)
  +            log("Connecting to URL " + connectionURL);
  +        else if (debug >= 1 && connectionAttempt > 0)
  +            log("Connecting to URL " + alternateURL);
           env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
           if (connectionName != null)
               env.put(Context.SECURITY_PRINCIPAL, connectionName);
           if (connectionPassword != null)
               env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
  -        if (connectionURL != null)
  +        if (connectionURL != null && connectionAttempt == 0)
               env.put(Context.PROVIDER_URL, connectionURL);
  +        else if (alternateURL != null && connectionAttempt > 0)
  +            env.put(Context.PROVIDER_URL, alternateURL);
           if (authentication != null)
               env.put(Context.SECURITY_AUTHENTICATION, authentication);
           if (protocol != null)
  -            env.put(Context.SECURITY_PROTOCOL, protocol);    
  +            env.put(Context.SECURITY_PROTOCOL, protocol);   
           if (referrals != null)
               env.put(Context.REFERRAL, referrals);   
  -            
  -        context = new InitialDirContext(env);
  -        return (context);
  -
  +    
  +        return env;
  +        
       }
   
   
  @@ -1440,7 +1532,7 @@
           close(this.context);
   
       }
  -
  +    
   
   }
   
  
  
  
  1.5       +5 -0      jakarta-tomcat-catalina/webapps/docs/realm-howto.xml
  
  Index: realm-howto.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/docs/realm-howto.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- realm-howto.xml   28 Dec 2002 02:05:39 -0000      1.4
  +++ realm-howto.xml   11 Jan 2003 01:57:39 -0000      1.5
  @@ -507,6 +507,11 @@
   to, and optionally the port number and distinguished name (DN) of the
   required root naming context.</p>
   
  +<p>If you have more than one provider you can configure an
  +<strong>alternateURL</strong>.  If a socket connection can not be
  +made to the provider at the <strong>connectionURL</strong> an
  +attempt will be made to use the <strong>alternateURL</strong>.</p>
  +
   <p>When making a connection in order to search the directory and
   retrieve user and role information, the realm authenticates itself to
   the directory with the username and password specified by the
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to