On November 21, 2011 14:49 , Mark Montague <m...@catseye.org> wrote:
I need Tomcat 6 to use the authentication performed by the front-end webserver without breaking the roles required by the Tomcat Manager webapp.

I'm replying to myself to document what I did in case it helps other people. Feedback and criticism are welcome, since I'm new to both Tomcat and Java. André's suggestion, to move authorization into Apache HTTPD along with authentication and then delete the servlet's security constraints, is much simpler and more practical than the method I describe here.

In a default installation of Tomcat 6, the Tomcat Manager web application is configured to use the UserDatabaseRealm for authentication and authorization. When authentication is moved to the front-end web server by setting the tomcatAuthentication="false" attribute for the connector, authorization breaks because the servlet request object now contains principals of class CoyotePrincipal, which do not contain role information, instead of principals of class GenericPrincipal, which do contain role information.

My solution (which appears to work, although it is inefficient) is to create a new realm named CoyoteUserDatabaseRealm that extends UserDatabaseRealm. CoyoteUserDatabaseRealm overrides the hasrole() method in order to convert the principal of class CoyotePrincipal into a principal of class GenericPrincipal and then invoking the hasRole() method of UserDatabaseRealm.

Instructions for a Unix-based system:

# Download, unpack, and build the Tomcat source code into the directory
# apache-tomcat-6.0.33-src

# Copy and save CoyoteUserDatabaseRealm.java from this email (below).
mkdir -p org/apache/catalina/realm/
# Copy and save org/apache/catalina/realm/mbeans-descriptors.xml from this email (below).

# Compile the class and move it into place.
javac -sourcepath ./apache-tomcat-6.0.33-src/java CoyoteUserDatabaseRealm.java
mv CoyoteUserDatabaseRealm.class org/apache/catalina/realm/

# Create a .jar file:
jar cf coyote-realm.jar org/

# Install the jar file:
cp coyote-realm.jar $CATALINA_HOME/lib
chcon system_u:object_r:usr_t:s0 $CATALINA_HOME/lib/coyote-realm.jar # for SELinux users only

# Edit $CATALINA_HOME/conf/server.xml
# Change the lines
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
# to
<Realm className="org.apache.catalina.realm.CoyoteUserDatabaseRealm"
             resourceName="UserDatabase"/>

# restart Tomcat so the changes take effect:
service tomcat6 restart


I hope this helps.

--
  Mark Montague
  m...@catseye.org


---- start file CoyoteUserDatabaeRealm.java --------------------------

package org.apache.catalina.realm;


import java.security.Principal;

import org.apache.catalina.Role;
import org.apache.catalina.User;
import org.apache.catalina.UserDatabase;
import org.apache.catalina.Realm;
import org.apache.catalina.realm.UserDatabaseRealm;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.realm.RealmBase;
import org.apache.catalina.util.StringManager;
import org.apache.catalina.connector.CoyotePrincipal;


public class CoyoteUserDatabaseRealm
    extends UserDatabaseRealm
    implements Realm
{

    protected final String info =
        "org.apache.catalina.realm.CoyoteUserDatabaseRealm/1.0";

    protected static final String name = "CoyoteUserDatabaseRealm";

    private static StringManager sm =
        StringManager.getManager(Constants.Package);


    public String getInfo() {
        return info;
    }


    protected String getName() {
        return name;
    }


    public boolean hasRole(Principal principal, String role) {

        if (principal instanceof CoyotePrincipal) {
            // Look up this user in the UserDatabaseRealm.  The new
            // principal will contain UserDatabaseRealm role info.
            Principal p = super.getPrincipal(principal.getName());
            if (p != null) {
                principal = p;
            }
        }
        return super.hasRole(principal, role);

    }

}


---- end file CoyoteUserDatabaeRealm.java ----------------------------


---- start file org/apache/catalina/realm/mbeans-descriptors.xml -----

<?xml version="1.0"?>
<mbeans-descriptors>
  <mbean         name="CoyoteUserDatabaseRealm"
          description="Realm using CoyotePrincipal connected to a UserDatabase as a 
global JNDI resource"
               domain="Catalina"
                group="Realm"
                 type="org.apache.catalina.realm.CoyoteUserDatabaseRealm">
    <attribute   name="className"
          description="Fully qualified class name of the managed object"
                 type="java.lang.String"
            writeable="false"/>
    <attribute   name="resourceName"
          description="The global JNDI name of the UserDatabase resource to use"
                 type="java.lang.String"/>
  </mbean>
</mbeans-descriptors>

---- end file org/apache/catalina/realm/mbeans-descriptors.xml -------




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to