I've found what looks to be a mis-feature with JAAS authentication for EJB's.  
I'm using the ServerServlet to call EJB's over http/s.  It looks like in order 
to work, the JAAS realm that authenticates the EJB user must either be named 
the same as the WAR that contains ServerServlet OR it must be defined globally 
in Tomcat's server.xml.  

Defining the JAAS realm in ServerServlet's WAR with any name other than the 
WAR's name fails with a strange, "java.rmi.RemoteException: Received invalid 
response code from server: 3".  Best I can tell, the '3' corresponds to 
org.apache.openejb.client.ResponseCodes.AUTH_DENIED, which for some reason gets 
marshalled back under a "javax.ejb.EJBException: Unknown Container Exception" 
with a cause of that RemoteException.  Possibly there's another problem here 
with marshalling back the error condition from an AUTH_DENIED, but I haven't 
dug into that.

The closest thing to a root cause I can find is the behavior in 
org.apache.tomee.catalina.TomcatSecurityService::findRealm which is called by 
login, ultimate called by org.apache.openejb.server.ejbd.EjbRequestHandler 
processRequest method (securityToken = 
securityService.login(authentication.getRealm(), authentication.getUser(), new 
String(authentication.getPassword())); // Line 171)

The findRealm method searches a Map from TomcatWebAppBuilder which appears to 
contain keys of the various archive names to their defined realms.  

The two ways that this works successfully are:

1) If the Realm that should be securing your EJB's is in the default 
conf/server.xml, the fallthrough that returns defaultRealm works.

2) If the Realm is named the same as the WAR's URI, then it'll be found in the 
Map within TomcatWebAppBuilder.


My (failing) environment looked like this:

ejb.war!META-INF/context.xml:

<Context>
  <Realm 
    className="org.apache.catalina.realm.JAASRealm" 
    appName="ucs_security"
    userClassNames="ucs.common.tomee.UcsUser"
    roleClassNames="ucs.common.tomee.UcsRole"
  />
</Context>


ejb.war!WEB-INF/web.xml:

<web-app version="3.1"
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"; 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd";>
    
    <servlet>
        <servlet-name>ServerServlet</servlet-name>
        
<servlet-class>org.apache.openejb.server.httpd.ServerServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServerServlet</servlet-name>
        <url-pattern>/invoke/*</url-pattern>
    </servlet-mapping>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>ejb</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ejb-user</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <security-role>
        <role-name>ejb-user</role-name>
    </security-role>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>ucs_security</realm-name>
    </login-config>
</web-app>

And the client-side JAAS configuration also uses "ucs_security" as its realm 
name.

If I moved the <Realm/> tag from the WAR's context.xml into server.xml, EJB 
calls authenticated successfully as it become the defaultRealm.  That bound the 
entire server to that authentication realm which isn't desired.  If I rename 
all the "ucs_security" references to "ejb" (or presumably renamed the WAR 
itself to "ucs_security" though I didn't test that), then it finds the right 
realm & authenticates.

It seems like incorrect behavior to force the name of the authentication realm 
to be the name of the EAR with all of the other various parts of JAAS able to 
specify an arbitrary realm name.

Is this expected behavior, or have I done something silly I'm not seeing?  This 
is all with TomEE 7.0.1.

Thanks in advance,
Zac Bedell

Reply via email to