Hi guys,

I put in a couple of simple classes that use the database for 
authentication and principal-to-role mapping. These classes have a 
high degree of cheese (no caching of database info, hard-coded 
table and column names, hard-coded database pool name, no way 
to actually use these classes without modifying source code, no 
per-container configuration, etc.) but might be adequate for 
someone who wanted to, for example, develop an application that 
used information returned from getCallerPrincipal or isCallerInRole. 
Also, it won't be that hard to de-cheese the code, but I've used my 
jboss time quota for the week. Any volunteers? (Anyway, the next 
thing I'm going to do is probably integrate security with Tomcat, 
unless someone else does it first.)

For the adventurous who would like to try this (or even contribute), 
here is a list of the necessary steps to get this to work (actually 
setting a principal and a credential on the client was covered in an 
earlier e-mail to this list AND is in bugzilla):

*** summary version ***

1. Add a minerva pool for security
2. Create the database tables
3. Hack the code to use the new classes



*** long version ***

1.  Add a minerva pool with the JNDI name SecureDS. Here is my 
entry from jboss.conf:

<MLET CODE="org.jboss.jdbc.XADataSourceLoader" 
ARCHIVE="jboss.jar" CODEBASE="../lib/ext/">
    <ARG TYPE="java.lang.String" VALUE="SecurityDS">
    <ARG TYPE="java.lang.String" 
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>

and here is my entry from jboss.jcml (sans user name and 
password):

     <mbean 
name="DefaultDomain:service=XADataSource,name=SecurityDS">
       <attribute 
name="URL">jdbc:interbase://localhost/E:/book/bookdata.gdb</attr
ibute>
       <attribute name="Password">****</attribute>
       <attribute name="JDBCUser">****</attribute>
     </mbean>

2.  Add two tables to the corresponding data base:

CREATE TABLE SEC_ACCESS (NAME VARCHAR(50) NOT 
NULL,
        PASS VARCHAR(50) NOT NULL,
PRIMARY KEY (NAME));

CREATE TABLE SEC_ROLES (SETNAME VARCHAR(25) NOT 
NULL,
        PRINCIPAL VARCHAR(50) NOT NULL,
        ROLENAME VARCHAR(50) NOT NULL,
PRIMARY KEY (SETNAME, PRINCIPAL, ROLENAME));

The sec_access table stores user-name / password values. The 
sec_roles table maps principals to roles. Although eventually this 
will be configurable per-bean (hence "setname" column--the name 
of the set of mappings), right now it is hard-coded to use the value 
"basic", so that is what you must have for every row (i.e. right there 
is a universal principal to role mapping, contrary to the spec).

3.  Currently in CVS, the container is hard-coded to use an 
authentication that simply checks if the user name and password 
are identical strings, and assumes that the principal name maps 
one-to-one with an identical role name. Although the intent is to be 
able to replace the authentication and role-mapping MBeans 
dynamically per-container, right now what I did in testing is to 
locally modify the classes org.jboss.security.SimpleRealmMapping 
and org.jboss.security.EJBSecurityManagerService to instantiate 
the new classes rather than those default ones. In 
EJBSecurityManagerService, change initService to look like this:

   protected void initService()
      throws Exception
   {
       // Create a new SM
       sm = new EJBSecurityManagerDatabaseImpl();
       
       // Bind reference to SM in JNDI
       Reference ref = new Reference(sm.getClass().toString(), 
getClass().getName(), null);
       new InitialContext().bind(JNDI_NAME, ref);
   }

and in SimpleRealmMappingService modify initService to look like 
this:

   protected void initService()
      throws Exception
   {
           // Create a new SM
           srm = new DatabaseRealmMapping();
           // Bind reference to JNDI
           Reference ref = new 
Reference(SimpleRealmMapping.class.toString(), 
getClass().getName(), null);
           new InitialContext().bind(JNDI_NAME, ref);
   }

Also in SimpleRealmMappingService add the following import:

import org.jboss.system.RealmMapping;

and change the variable srm to be of type RealmMapping, i.e.:

public class SimpleRealmMappingService
   extends ServiceMBeanSupport
   implements SimpleRealmMappingServiceMBean, ObjectFactory
{
   // Constants -----------------------------------------------------
   public static String JNDI_NAME = "SimpleRealmMapping";
   private static RealmMapping srm;

If anyone decides they want to play with this and runs into trouble, 
please let me know.

-Dan

Reply via email to