I did that part programmatically: public AppConfigurationEntry[] getAppConfigurationEntry( String applicationName ) { if( m_appConfig == null ) { if( applicationName == null ) { throw new NullPointerException( "Could not retrieve security configuration. " + "Application name was not specified." ); }
if( m_dbkey == null ) { throw new NullPointerException( "The application, \"" + applicationName + "\", " + "does not have a security configuration entry " + "defined in " + this.getClass().getName() + "." ); } String[] parms = { applicationName }; String sql = MessageFormat.format( SECURITY_CONFIGURATION_SQL, parms ); Connection dbConn = null; Statement stmt = null; ResultSet rs = null; ArrayList modules = new ArrayList(); try { dbConn = ConnectionFactory.getConnection( m_dbkey ); stmt = dbConn.createStatement(); rs = stmt.executeQuery( sql ); while( rs.next() ) { String loginClass = rs.getString( "LoginModuleClass" ); String cFlag = rs.getString( "ControlFlag" ); DEBUG_MODE = rs.getBoolean( "DebugFlag" ); HashMap options = new HashMap(); options.put( "debug", String.valueOf( DEBUG_MODE ) ); AppConfigurationEntry.LoginModuleControlFlag controlFlag = resolveControlFlag( cFlag ); AppConfigurationEntry appEntry = new AppConfigurationEntry( loginClass, controlFlag, options ); modules.add( appEntry ); m_appConfig = (AppConfigurationEntry[])modules.toArray( new AppConfigurationEntry[modules.size()] ); } } catch( SQLException e ) { Logger.log( Logger.ERROR, getClass() + ".getAppConfigurationEntry", e ); return null; } catch( KException e ) { Logger.log( Logger.ERROR, getClass() + ".getAppConfigurationEntry", e ); return null; } finally { SQLUtil.close( dbConn, stmt, rs ); rs = null; stmt = null; dbConn = null; } } return m_appConfig; } The hook into the login module is created when the context listener for the web-app is initialized. The initialization parameters come from the database, which is what I was referring to, as opposed to a policy file. What I find strange is that the authentication piece works perfectly. Tomcat calls my login module, does it's work and build a Subject that is consistent with what I expect. The question is, why am I able to call request.isUserInRole("landscape") when Tomcat's internal call to the roles in my Subject uses something else? The Tomcat code that is failing for my auth check is (http://kickjava.com/src/org/apache/catalina/realm/RealmBase.java.htm): } else if(!denyfromall) { 787 788 for (int j = 0; j < roles.length; j++) { 789 if (hasRole(principal, roles[j])) 790 status = true; 791 if( log.isDebugEnabled() ) 792 log.debug( "No role found: " + roles[j]); 793 } 794 } public boolean hasRole(Principal JavaDoc principal, String JavaDoc role) { 851 852 // Should be overriten in JAASRealm - to avoid pretty inefficient conversions 853 if ((principal == null) || (role == null) || 854 !(principal instanceof GenericPrincipal)) 855 return (false); 856 857 GenericPrincipal gp = (GenericPrincipal) principal; 858 if (!(gp.getRealm() == this)) { 859 if(log.isDebugEnabled()) 860 log.debug("Different realm " + this + " " + gp.getRealm());// return (false); 861 } 862 boolean result = gp.hasRole(role); 863 if (log.isDebugEnabled()) { 864 String JavaDoc name = principal.getName(); 865 if (result) 866 log.debug(sm.getString("realmBase.hasRoleSuccess", name, role)); 867 else 868 log.debug(sm.getString("realmBase.hasRoleFailure", name, role)); 869 } 870 return (result); 871 872 } So, what works in the one case, i.e., request.isUserInRole("landscape"), fails when using Tomcat's role checking, i.e., hasRole(principal, roles[j]). So, Tomcat isn't treating my Principal as a role, which its own messages says that it is: org.apache.catalina.realm.JAASRealm - Checking Principal "landscape" [com.kaleidescape.logdb.webapp.security.auth.UserGroupPrincipal] 2008-05-05 14:02:53,665 10885193 [http-9808-Processor24] DEBUG org.apache.catalina.realm.JAASRealm - Adding role Principal "landscape" to this user Principal's roles If my JAAS realm wasn't properly configured, I can't see how I'd get all the way to the JAASRealm hasRole() method. Also, my own implementation was a check against Tomcat. I called all the same code that Tomcat calls, the only difference is, I can access my Subject when I call my own code, whereas Tomcat sticks the Subject that it creates into an InternalSession, which isn't accessible outside of the Catalina code base. Since my UserGroupPrincipal implements Principal, it is castable to GenericPrincipal. I am not in a different realm, since the debug message about that isn't fired. So it comes down to how the Catalina code base is interpreting gp.hasRole(role). Haven't tracked down that code yet but I will. At least, that's how it appears to me, but I am open to any fixes. :) Robin. -----Original Message----- From: Caldarale, Charles R [mailto:[EMAIL PROTECTED] Sent: Monday, May 05, 2008 2:12 PM To: Tomcat Users List Subject: RE: JAAS authenticated user fails authorization check > From: Robin Coe [mailto:[EMAIL PROTECTED] > Subject: RE: JAAS authenticated user fails authorization check It appears that the problem is you haven't fully configured the JAAS environment. See below for details. > I tested the implementation of isUserInRole() by wild-carding > the role, to force Tomcat to authenticate but not authorize: It doesn't work that way. A <role-name> of * means that authorization is allowed for any of the listed <security-role>s, not that authorization is ignored. > As a side note, I wrote my own implementation of the login > process, using a servlet to hook into my login module, thus > avoiding the declarative security. Why did you choose to reinvent the wheel here? Use the declarative security - it's much easier. > <Context> > <Realm className="org.apache.catalina.realm.JAASRealm" > appName="landscape" The appName is not some arbitrary value; it needs to point to the entry in the file pointed to by the java.security.auth.login.config system property (see below). > The JAAS module is not based on a security policy file, I > wrote it to work from a database. Not relevant to the discussion. You still have to tell Tomcat's JAASRealm what your LoginModule class name is via the file pointed to by the java.security.auth.login.config system property. For example, here's ours: -Djava.security.auth.login.config=conf/security/tomcatLogin.config The conf/security/tomcatLogin.config file contains: TomcatLogin { com.unisys.os2200.security.TomcatLoginModule required; }; Have you done that? - Chuck THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. --------------------------------------------------------------------- To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]