tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Robin Coe <Robin....@kaleidescape.com>
Subject RE: JAAS authenticated user fails authorization check
Date Mon, 05 May 2008 18:31:51 GMT
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:Chuck.Caldarale@unisys.com]
Sent: Monday, May 05, 2008 2:12 PM
To: Tomcat Users List
Subject: RE: JAAS authenticated user fails authorization check

> From: Robin Coe [mailto:Robin.Coe@kaleidescape.com]
> 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: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message