Unable to get JAAS to authenticate
mrobin21 Mar 14, 2005 7:18 PMHello.
I am running JBOSS 4.0.1 and trying to secure my CMP EJBs. These EJBs are behind Session Beans compliant with the 'Business Delegate' and 'Session Facade' J2EE Patterns.
I have read the JBOSS JAAS documentation in the JBOSS4Guide:
http://docs.jboss.org/jbossas/jboss4guide/r2/html/ch8.chapter.html#ch8
And I have read the JAAS section of the JBoss 3.2 Deployment and Adminstration book (Meeraj Kunnumpurath).
However I am still unable to get JAAS to work properly. I am unable to access my methods even though I supply correct credentials!
I wish to use the Database Server Login Module to login to the Role 'Admin', which I have placed on every 'set' method of every CMP EJB via the @ejb.permission XDoclet Tag (All other methods are tagged with Admin,Guest):
* @ejb.interface-method * view-type="both" * * @ejb.permission * role-name="Admin"
These tags produce the following the ejb-jar.xml file (this is the finder method I am trying to access):
<method-permission > <description>[CDATA[description not supported yet by ejbdoclet]]</description> <role-name>Admin</role-name> <method > <ejb-name>AdminUser</ejb-name> <method-name>findByEmail</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </method-permission>
In my Oracle 9i database I have a table: ADMIN_USER and ADMIN_ROLE_TYPE which together expose the information I need: The ADMIN_USER record has a reference to a ADMIN_ROLE_TYPE via a Foreign Key constraint:
CREATE TABLE ADMIN_USER ( USER_ID NUMBER (10) NOT NULL, USER_EMAIL VARCHAR2 (50) NOT NULL, USER_PASSWORD VARCHAR2 (200) NOT NULL, USER_FIRSTNAME VARCHAR2 (50) NOT NULL, USER_LASTNAME VARCHAR2 (50) NOT NULL, ADMIN_ROLE_TYPE_ID NUMBER (10) NOT NULL, USER_GROUP VARCHAR2 (20) NOT NULL, . . . CONSTRAINT PK_ADMIN_USER PRIMARY KEY ( USER_ID ) ) ; ALTER TABLE ADMIN_USER ADD CONSTRAINT FK_ADMIN_TYPE FOREIGN KEY (ADMIN_ROLE_TYPE_ID) REFERENCES JBOSS.ADMIN_ROLE_TYPE (ROLE_ID) ; CREATE TABLE ADMIN_ROLE_TYPE ( ROLE_ID NUMBER (10) NOT NULL, NAME VARCHAR2 (50) NOT NULL, CREATED_DATE DATE DEFAULT SYSDATE NOT NULL, MODIFIED_DATE DATE DEFAULT NULL, CREATED_USER VARCHAR2 (50) DEFAULT USER NOT NULL, MODIFIED_USER VARCHAR2 (50) DEFAULT NULL, DELETED_USER VARCHAR2 (50) DEFAULT NULL, DELETED_DATE DATE DEFAULT NULL, CONSTRAINT PK_ADMIN_ROLE_TYPE PRIMARY KEY ( ROLE_ID ) ) ;
My login-config.xml contains (note the queries are based on the JBOSS 4 Guide examples adapted to my schema):
<!-- Security domain --> <application-policy name = "MattsDomain"> <authentication> <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required"> <module-option name = "unauthenticatedIdentity">guest</module-option> <module-option name = "dsJndiName">java:/OracleDS</module-option> <module-option name = "principalsQuery">SELECT USER_PASSWORD FROM ADMIN_USER WHERE USER_EMAIL=?</module-option> <module-option name = "rolesQuery">SELECT r.NAME, 'Admin' FROM ADMIN_ROLE_TYPE r, ADMIN_USER a WHERE a.USER_EMAIL=? AND r.ROLE_ID = a.ADMIN_ROLE_TYPE_ID</module-option> </login-module> </authentication> </application-policy>
The jboss.xml file has been tweaked with the following:
<security-domain>java:/jaas/MattsDomain</security-domain> <unauthenticated-principal>Guest</unauthenticated-principal>
And here is the client code in the SecurityFacade which attempts to invoke the finder method:
public AdminUserTO authenticate( AdminUserTO user )throws DatastoreException { try { UsernamePasswordHandler handler = new UsernamePasswordHandler( user.getUserEmail(), user.getUserPassword().toCharArray() ); LoginContext lc = new LoginContext( "MattsDomain" , handler ); lc.login(); System.out.println(lc.getSubject()); System.out.println("Caller Principal " + ctx.getCallerPrincipal()); AdminUserLocalHome adminUserLocalHome = getAdminUserHome(); if ( adminUserLocalHome == null ) throw new DatastoreException( "S002", "Admin User Local Home not found in Service Locator", null ); Collection usersByEmail = adminUserLocalHome.findByEmail( user.getUserEmail() ); . . .
My test client attempts to invoke the SecurityFacade method via a Business Delegate Facade thus:
AdminUserTO me = adminBean.authenticate( "matt@hotmail.com", "test" );
Finally the output, including the debug output you see in the example above:
09:14:39,598 INFO [STDOUT] Subject: Principal: matt@hotmail.com Principal: Admin(members:Admin) 09:14:39,598 INFO [STDOUT] Caller Principal nobody 09:14:39,618 ERROR [LogInterceptor] TransactionRolledbackLocalException in method: public abstract matt.datastore.dto.AdminUserTO matt.datastore.session.facade.admin.SecurityAdminFacadeLocal.authenticate(matt.datastore.dto.AdminUserTO) throws matt.datastore.exception.DatastoreException, causedBy: java.lang.SecurityException: Insufficient method permissions, principal=null, method=findByEmail, interface=LOCALHOME, requiredRoles=[Admin], principalRoles=[] at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:215) at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:91) at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:121) . . .
What am I Missing here?
Any help much appreciated!