markt       2004/11/22 14:42:30

  Modified:    catalina/src/share/org/apache/catalina/realm JDBCRealm.java
                        LocalStrings.properties
               webapps/docs changelog.xml realm-howto.xml
  Log:
  Add support for DIGEST authentication to the JDBCRealm
  
  Revision  Changes    Path
  1.9       +126 -69   
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/JDBCRealm.java
  
  Index: JDBCRealm.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/JDBCRealm.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- JDBCRealm.java    23 Jun 2004 13:51:37 -0000      1.8
  +++ JDBCRealm.java    22 Nov 2004 22:42:28 -0000      1.9
  @@ -385,81 +385,44 @@
        * @param username Username of the Principal to look up
        * @param credentials Password or other credentials to use in
        *  authenticating this username
  -     *
  -     * @exception SQLException if a database error occurs
        */
       public synchronized Principal authenticate(Connection dbConnection,
                                                  String username,
  -                                               String credentials)
  -        throws SQLException {
  -
  -        // Look up the user's credentials
  -        String dbCredentials = null;
  -        PreparedStatement stmt = null;
  -        ResultSet rs = null;
  -
  -        try {
  -            stmt = credentials(dbConnection, username);
  -            rs = stmt.executeQuery();
  -
  -            if (rs.next()) {
  -                dbCredentials = rs.getString(1);
  -            }
  -            rs.close();
  -            rs = null;
  -            if (dbCredentials == null) {
  -                return (null);
  -            }
  -
  -            dbCredentials = dbCredentials.trim();
  +                                               String credentials) {
   
  +        // No user - can't possibly authenticate
  +        if (username == null) {
  +            return (null);
  +        }
   
  -            // Validate the user's credentials
  -            boolean validated = false;
  -            if (hasMessageDigest()) {
  -                // Hex hashes should be compared case-insensitive
  -                validated = 
(digest(credentials).equalsIgnoreCase(dbCredentials));
  -            } else {
  -                validated = (digest(credentials).equals(dbCredentials));
  -            }
  -
  -            if (validated) {
  -                if (container.getLogger().isTraceEnabled())
  -                    
container.getLogger().trace(sm.getString("jdbcRealm.authenticateSuccess",
  -                                     username));
  -            } else {
  -                if (container.getLogger().isTraceEnabled())
  -                    
container.getLogger().trace(sm.getString("jdbcRealm.authenticateFailure",
  -                                     username));
  -                return (null);
  -            }
  +        // Look up the user's credentials
  +        String dbCredentials = getPassword(username);
   
  -            // Accumulate the user's roles
  -            ArrayList roleList = new ArrayList();
  -            stmt = roles(dbConnection, username);
  -            rs = stmt.executeQuery();
  -            while (rs.next()) {
  -                String role = rs.getString(1);
  -                if (null!=role) {
  -                    roleList.add(role.trim());
  -                }
  -            }
  -            rs.close();
  -            rs = null;
  +        // Validate the user's credentials
  +        boolean validated = false;
  +        if (hasMessageDigest()) {
  +            // Hex hashes should be compared case-insensitive
  +            validated = 
(digest(credentials).equalsIgnoreCase(dbCredentials));
  +        } else {
  +            validated = (digest(credentials).equals(dbCredentials));
  +        }
   
  -            // Create and return a suitable Principal for this user
  -            return (new GenericPrincipal(this, username, credentials, 
roleList));
  -        } finally {
  -            if (rs!=null) {
  -                try {
  -                    rs.close();
  -                } catch(SQLException e) {
  -                    
container.getLogger().warn(sm.getString("jdbcRealm.abnormalCloseResultSet"));
  -                }
  -            }
  -            dbConnection.commit();
  +        if (validated) {
  +            if (container.getLogger().isTraceEnabled())
  +                
container.getLogger().trace(sm.getString("jdbcRealm.authenticateSuccess",
  +                                 username));
  +        } else {
  +            if (container.getLogger().isTraceEnabled())
  +                
container.getLogger().trace(sm.getString("jdbcRealm.authenticateFailure",
  +                                 username));
  +            return (null);
           }
   
  +        ArrayList roles = getRoles(username);
  +        
  +        // Create and return a suitable Principal for this user
  +        return (new GenericPrincipal(this, username, credentials, roles));
  +
       }
   
   
  @@ -553,8 +516,49 @@
        */
       protected String getPassword(String username) {
   
  -        return (null);
  +        // Look up the user's credentials
  +        String dbCredentials = null;
  +        PreparedStatement stmt = null;
  +        ResultSet rs = null;
   
  +        try {
  +            stmt = credentials(dbConnection, username);
  +            rs = stmt.executeQuery();
  +
  +            if (rs.next()) {
  +                dbCredentials = rs.getString(1);
  +            }
  +            rs.close();
  +            rs = null;
  +            if (dbCredentials == null) {
  +                return (null);
  +            }
  +
  +            dbCredentials = dbCredentials.trim();
  +            return dbCredentials;
  +            
  +        } catch(SQLException e){
  +            container.getLogger().
  +                    error(sm.getString("jdbcRealm.getPassword.exception",
  +                                       username));
  +        } finally {
  +            if (rs!=null) {
  +                try {
  +                    rs.close();
  +                } catch(SQLException e) {
  +                    
container.getLogger().warn(sm.getString("jdbcRealm.abnormalCloseResultSet"));
  +                }
  +            }
  +            try {
  +                dbConnection.commit();
  +            } catch (SQLException e) {
  +                container.getLogger().
  +                        warn(sm.getString("jdbcRealm.getPassword.exception",
  +                                          username));
  +            }
  +        }
  +        
  +        return (null);
       }
   
   
  @@ -563,11 +567,64 @@
        */
       protected Principal getPrincipal(String username) {
   
  -        return (null);
  +        return (new GenericPrincipal(this,
  +                                     username,
  +                                     getPassword(username),
  +                                     getRoles(username)));
   
       }
   
   
  +    /**
  +     * Return the roles associated with the gven user name.
  +     */
  +    protected ArrayList getRoles(String username) {
  +        
  +        PreparedStatement stmt = null;
  +        ResultSet rs = null;
  +
  +        try {
  +            // Accumulate the user's roles
  +            ArrayList roleList = new ArrayList();
  +            stmt = roles(dbConnection, username);
  +            rs = stmt.executeQuery();
  +            while (rs.next()) {
  +                String role = rs.getString(1);
  +                if (null!=role) {
  +                    roleList.add(role.trim());
  +                }
  +            }
  +            rs.close();
  +            rs = null;
  +            
  +            return (roleList);
  +            
  +        } catch(SQLException e){
  +            container.getLogger().
  +                    error(sm.getString("jdbcRealm.getRoles.exception",
  +                                       username));
  +        } finally {
  +            if (rs!=null) {
  +                try {
  +                    rs.close();
  +                } catch(SQLException e) {
  +                    
container.getLogger().warn(sm.getString("jdbcRealm.abnormalCloseResultSet"));
  +                }
  +            }
  +            try {
  +                dbConnection.commit();
  +            } catch (SQLException e) {
  +                container.getLogger().
  +                        warn(sm.getString("jdbcRealm.getRoles.exception",
  +                                          username));
  +            }
  +        }
  +
  +        return (null);
  +        
  +    }
  +    
  +    
       /**
        * Open (if necessary) and return a database connection for use by
        * this Realm.
  
  
  
  1.8       +5 -1      
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/realm/LocalStrings.properties,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- LocalStrings.properties   21 Sep 2004 23:29:33 -0000      1.7
  +++ LocalStrings.properties   22 Nov 2004 22:42:28 -0000      1.8
  @@ -35,6 +35,8 @@
   jdbcRealm.authenticateSuccess=Username {0} successfully authenticated
   jdbcRealm.close=Exception closing database connection
   jdbcRealm.exception=Exception performing authentication
  +jdbcRealm.getPassword.exception=Exception retrieving password for "{0}"
  +jdbcRealm.getRoles.exception=Exception retrieving roles for "{0}"
   jdbcRealm.open=Exception opening database connection
   jndiRealm.authenticateFailure=Username {0} NOT successfully authenticated
   jndiRealm.authenticateSuccess=Username {0} successfully authenticated
  @@ -65,4 +67,6 @@
   dataSourceRealm.authenticateSuccess=Username {0} successfully authenticated
   dataSourceRealm.close=Exception closing database connection
   dataSourceRealm.exception=Exception performing authentication
  +datasourceRealm.getPassword.exception=Exception retrieving password for "{0}"
  +datasourceRealm.getRoles.exception=Exception retrieving roles for "{0}"
   dataSourceRealm.open=Exception opening database connection
  
  
  
  1.180     +3 -0      jakarta-tomcat-catalina/webapps/docs/changelog.xml
  
  Index: changelog.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/docs/changelog.xml,v
  retrieving revision 1.179
  retrieving revision 1.180
  diff -u -r1.179 -r1.180
  --- changelog.xml     22 Nov 2004 15:04:58 -0000      1.179
  +++ changelog.xml     22 Nov 2004 22:42:29 -0000      1.180
  @@ -47,6 +47,9 @@
         <update>
           <bug>32282</bug>: Modify Windows Uninstaller to only remove 
webapps/ROOT and webapps if user asks to remove everything. (yoavs)
         </update>
  +      <update>
  +        Add DIGEST authentication support to the JDBC realm. Supports both 
digested and cleartext passwords. (markt)
  +      </update>
       </changelog>
     </subsection>
   
  
  
  
  1.22      +10 -4     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.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- realm-howto.xml   17 Nov 2004 16:50:31 -0000      1.21
  +++ realm-howto.xml   22 Nov 2004 22:42:30 -0000      1.22
  @@ -210,6 +210,13 @@
       standard output.</li>
   </ul>
   
  +<p>If using digested passwords with DIGEST authentication, the cleartext used
  +   to generate the digest is different. In the examples above
  +   <code>{cleartext-password}</code> must be replaced with 
  +   <code>{username}:{realm}:{cleartext-password}</code>. For example, in a
  +   development environment this might take the form
  +   <code>testUser:localhost:8080:testPassword</code>.</p>
  +
   <p>To use either of the above techniques, the
   <code>$CATALINA_HOME/server/lib/catalina.jar</code> file will need to be
   on your class path to make the <code>RealmBase</code> class available.</p>
  @@ -292,8 +299,6 @@
           in the <em>users</em> table).</li>
       <li>Role name of a valid role associated with this user.</li>
       </ul></li>
  -<li>Please note that the JDBCRealm currently does not support DIGEST 
authentication 
  -    (as opposed to BASIC authentication).  It does support digested 
passwords as explained here.</li> 
   </ul>
   
   <h3>Quick Start</h3>
  @@ -474,8 +479,9 @@
           in the <em>users</em> table).</li>
       <li>Role name of a valid role associated with this user.</li>
       </ul></li>
  -<li>Please note that the JDBCRealm currently does not support DIGEST 
authentication 
  -    (as opposed to BASIC authentication).  It does support digested 
passwords as explained here.</li> 
  +<li>Please note that the DataSourceRealm currently does not support DIGEST 
  +    authentication (as opposed to BASIC authentication).  It does support
  +    digested passwords as explained here.</li> 
   </ul>
   
   <h3>Quick Start</h3>
  
  
  

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

Reply via email to