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