What exactly is the problem here? An ejb has a fixed role based j2ee security model and any sharing of it requires that the different domain users have suitable permission mappings under the domain of the ejb. You need to seperate the business component from the security domain of the deployment. There is nothing wrong with deploying the same ejb mutiple times under different security domains for the security constraints required for the different users.
The exact problem is...
I have the EJB deployed once and accessed by two different WebApps.
a) If the EJB has no security-domain configured it all works just fine until the Security Proxy calls isCallerInRole() when it falls over with:
Exception: java.rmi.ServerException: RuntimeException; nested exception is:
java.lang.IllegalStateException: isCallerInRole() called with no security context. Check that a security-domain has been set for the application.
OK, I'll show my ignorance here: Why can't the EJB just pick up the security context/domain from the calling WebApp? That would suit my needs just fine. I can't see how to achieve that so I then tried setting the security-domain on the EJB...
b) If I configure a security-domain for the EJB, WebApps using any other security-domains cannot use the EJB, falling over with something like:
java.rmi.AccessException: SecurityException; nested exception is:
java.lang.SecurityException: Authentication exception, principal=cp1003
Surely I don't have to deploy the EJB twice just to work with different WebApps? Seems a little awkward to me...
Thanks for your help though!
The security domain is an aspect of the deployment so you would have to deploy the ejb twice to map it to the different security domains in use. You could write a custom security interceptor that installed the security domain dynamically based on some request property, but we don't support the notion of a runtime security domain based on the caller's security domain out of the box.
Surely, EJBs should be application components which may be shared between different applications - e.g. different WebApps. These different WebApps will probably use different security-domains...
For example, my EJB is used both by an administrator via a admin Web App and regular users via a users Web App; each of these Web Apps are configured with their own security domain. As far as I can tell, since the target EJB has been configured ('hard-wired'?) to use a specific security domain, it then cannot support both Web Apps - and my system design falls apart.
From your example it is not clear, why do you need different security domains for simple role based access control. The J2EE security model supports your example as the main use case. You fix method-role association at deployment time (inside deployment descriptor) and have freedom in user-role associations at run-time. The server side security interceptor (and correspondent security manager) will get the set of roles, to which the method invocation is permitted, and will get the set of roles for the particular user, which is making the call. If the interception of these sets is not empty, the call is allowed. In other case the exception will be thrown (SecurityException in default security interceptor). This scenario is strait forward and the most often used.
I think that different security domains are aimed to cover another requirements. In may opinion, it is better to think about them, as something like Windows or UNIX security domain. When you are trying to get access to another security domain, you should be authenticated separately, and your new credentials will be kept in new security cache, etc. (even if this process is hidden, and you are not aware about it). Scott, am I right? It means that each call from your web application should login to EJB container (in your case) separately and explicitly. I think it is possible, but personally I have never done such variant, and it requires additional investigations.
If I needed simple role-based access control I wouldn't have used an interceptor.
OK, I have two WebApps, an admin WebApp and a users WebApp.
Because I want the two WebApps to have separate namespaces for usernames, I have given them separate security domains. Thus, an admin user and a regular user could, theoretically, have the same username and my system would handle that perfectly well. In the past I have used one security domain and had to mess with usernames to artificially ensure namespace separation. With separate domains, I don't need to and the system can be more flexible and robust at the same time.
For one of the WebApps - the admin WebApp - the standard declarative J2EE arrangements will work just fine. I wouldn't need a proxy to support this app's access to the EJB - it can be controlled on role.
The other WebApp supports users. Unfortunately, access to the target EJB from this WebApp needs to be controlled based on a complex resource ownership test - there are no roles which could be used to determine whether the call should be allowed or not. Without the interceptor, any user could act upon any entity represented by the EJB whether they owned it or not by simple URL hacking. I don't want to do the ownership test in the presentation layer since they presentation layer will be replaced. I could do the test in the EJB but I then have to replicate the test across all the controlled methods.
Thanks for your help though guys, I appreciate it. I guess I'll put the test in the EJB.
How can a test in the ejb be any different then a test in a security interceptor? You stated that you were using role based security via the isCallerInRole method and this what is tying you to the deployment security domain.
Yep, you're so right.
It looks like I'll have to deploy the same EJB twice under different EJB names and JNDI entries in order to get it to work for both WebApps. Just hope I can do that in a simple way without too much duplication...
In fact, it's probably better all-round to combine the security domains back into one... shame - if the EJBs could have assumed the domain of the calling WebApp the whole thing would have been smoother.
So replace the org.jboss.ejb.plugins.SecurityInterceptor with one that does use the caller security domain.