I thought I'd toss in another change to JDBC Realm, specifically the
ability to override the SQL query used for the password and the roles. 

It let's you have a config like:

      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm" debug="99"
            driverName="sun.jdbc.odbc.JdbcOdbcDriver"
            connectionURL="jdbc:odbc:CATALINA"
            <!-- for both the user and the roles queries only the first
column
                 in the result set is looked at for the password and
role -->
            userQuery="SELECT user_pass FROM users WHERE user_name = ?"
            userRoleQuery="SELECT role_name FROM roles WHERE user_name =
?"
      />

This gives people the ability to use SQL statements that may involve
joins, which is something I need to get the roles correctly.

Paul Lamb

> 
> Hola David:
> 
> Sorry for the delay, just catched your message in the archive.
> 
> > 
> > * Would it be acceptable for me to submit a patch for this code that
> > currently gets repeated in 2-3 different places ( in a few 
> > different ways
> > for Tomcat 3.2 ), moving the act of reconnecting to the 
> > database to it's own
> > seperate method that either returns void or returns a connection.
> > 
> 
> 3.3 JDBCRealm is now doing that in this way, but i use a boolean
> checkConnection(), I have planned backport this snippet soon ( this
> night ) but in the review i have found some things that can 
> done better
> too, as translating the log methods from SimpleRealm and JDBCRealm to
> BaseRealm, 
> 
> What do you think Craig?
> 
> > * Would this adversely affect the amount of logging that is 
> > done in the
> > current code?
> 
> I think JDBCRealm is doing too much logging now, so no problem.
> 
> > * If I am interpreting the logic that checks for the presence of a
> > connection name and connection password correctly, in the 
> > case that only
> > *one* of them is empty or null, the three parameter 
> > getConnection method is
> > used. Is it possible that this could cause problems as well?
> 
> i think you are right, i will change this in ALL tomcat versions ASAP,
> if nobody complaints.
> 
> > 
> > I apologize for not catching this with my original patch, 
> and for not
> 
> No problem, Thanks to point on this , i will try to do it ASAP, 
> 
> 
> Saludos ,
> Ignacio J. Ortega
> 
Index: JDBCRealm.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/JDBCRealm.java,v

retrieving revision 1.7
diff -u -r1.7 JDBCRealm.java
--- JDBCRealm.java      2000/12/16 23:49:35     1.7
+++ JDBCRealm.java      2000/12/26 22:55:37
@@ -208,6 +208,16 @@
     private String userTable = null;
 
     /**
+     * The query to retrieve the user date.
+     */
+    private String userQuery = null;
+
+   /**
+     * The query to retrieve the roles
+     */
+    private String userRoleQuery = null;
+ 
+    /**
      * The connection URL to use when trying to connect to the databse
      */
     private String connectionName = null;
@@ -348,6 +358,22 @@
     }
 
     /**
+     * Set the query that will be used to retrieve the user data
+     * @param userQuery SQL Query string
+     */
+    public void setUserQuery(String userQuery ) {
+        this.userQuery = userQuery;
+    }
+    
+    /**
+     * Set the query that will be used to retrieve the roles
+     * @param userRoleQuery SQL Query string
+     */
+    public void setUserRoleQuery(String userRoleQuery ) {
+        this.userRoleQuery = userRoleQuery;
+    }
+
+    /**
      * Set the name to use to connect to the database.
      *
      * @param connectionName User name
@@ -446,9 +472,14 @@
            }
 
            // Create the authentication search prepared statement if necessary
+            String sql = "";
            if (preparedAuthenticate == null) {
-               String sql = "SELECT " + userCredCol + " FROM " + userTable +
-                   " WHERE " + userNameCol + " = ?";
+                if (userQuery == null) {
+                    sql = "SELECT " + userCredCol + " FROM " + userTable +
+                        " WHERE " + userNameCol + " = ?";
+                } else {
+                    sql = userQuery;
+                }
                if (debug >= 1)
                    log("JDBCRealm.authenticate: " + sql);
                preparedAuthenticate = dbConnection.prepareStatement(sql);
@@ -456,13 +487,17 @@
 
            // Create the roles search prepared statement if necessary
            if (preparedRoles == null) {
-               String sql = "SELECT " + roleNameCol + " FROM " +
-                   userRoleTable + " WHERE " + userNameCol + " = ?";
+                if (userRoleQuery == null ) {
+                    sql = "SELECT " + roleNameCol + " FROM " +
+                        userRoleTable + " WHERE " + userNameCol + " = ?";
+                } else {
+                    sql = userRoleQuery;
+                }
                if (debug >= 1)
                    log("JDBCRealm.roles: " + sql);
                preparedRoles = dbConnection.prepareStatement(sql);
            }
-
+            
            // Perform the authentication search
            preparedAuthenticate.setString(1, username);
            ResultSet rs1 = preparedAuthenticate.executeQuery();



Index: server.xml
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/conf/server.xml,v
retrieving revision 1.16
diff -u -r1.16 server.xml
--- server.xml  2000/12/17 01:03:29     1.16
+++ server.xml  2000/12/26 23:00:26
@@ -126,6 +126,16 @@
           userRoleTable="user_roles" roleNameCol="role_name" />
       -->
 
+      <!--
+      <Realm  className="org.apache.catalina.realm.JDBCRealm" debug="99"
+            driverName="sun.jdbc.odbc.JdbcOdbcDriver"
+            connectionURL="jdbc:odbc:CATALINA"
+            <!-- for both the user and the roles queries only the first column
+                 in the result set is looked at for the password and role -->
+            userQuery="SELECT user_pass FROM users WHERE user_name = ?"
+            userRoleQuery="SELECT role_name FROM roles WHERE user_name = ?"
+      />
+
       <!-- Define the default virtual host -->
       <Host name="localhost" debug="0" appBase="webapps">
 

Reply via email to