03-25-2011 10:53 AM
09-15-2011 03:03 PM
Did you ever happen to secure your EJB's using either standard configuration or annotations? The problem is simple: an EJB is secured and certain methods only accessible to authenticated users that belong to a certain group/role. And exactly here is the problem: the user-to-roles mapping, which I would have to transport as well and somehow "set" them along with the user itself before invoking such a secured EJB.Yes and no. What we did in an early stage is to get rid of the 'dogma' that at the ejb level, individual users should be authenticated. That is where we authenticated the calling application (if it was a remote call). The user (and his roles) is passed on in a standardized way (SAML token), not via methods, but via threadlocal (a strong concept! appservers use it themselves all the time). But something like http://docs.jboss.org/seam/3/security/latest/reference/en-US/html/ is also an option
Hm, might be an option. However, then again I'm offloading at least all the authorization issue into the application code (although hidden by annotations) to some degree which I would like to avoid, since that's the purpose of standards like JAAS or JACC, aso. I would really like to let the container do those things in a very defined way (security-realms, login-modules, …).This would involve digging into the application servers code and find a way to set them programmatically. The GlassFish guys provide a simple class to "fake-authenticate" a user, however, they clearly state that this doesn't involve any real authentication and hence, no user/role mapping coming from e.g. a database or an external system.Well, not realy. It is not difficult (assuming ejb 3.0) to create your own annotations. This works cross appserver and the annotations read the threadlocal variable with the user details.
Exactly, I cannot control them, so I have to deal with what I get… somehow.Yes, it's simple. However, it's not so simple in my case and simply wouldn't work.I there are existing systems out of your control then I can imagine. If there are existing systems within your control, I'd seriously think of adapting those 😉
09-15-2011 06:59 PM
Hm, might be an option. However, then again I'm offloading at least all the authorization issue into the application code (although hidden by annotations) to some degree which I would like to avoid, since that's the purpose of standards like JAAS or JACC, aso. I would really like to let the container do those things in a very defined way (security-realms, login-modules, …).This would involve digging into the application servers code and find a way to set them programmatically. The GlassFish guys provide a simple class to "fake-authenticate" a user, however, they clearly state that this doesn't involve any real authentication and hence, no user/role mapping coming from e.g. a database or an external system.Well, not realy. It is not difficult (assuming ejb 3.0) to create your own annotations. This works cross appserver and the annotations read the threadlocal variable with the user details.
I've looked a bit deeper and with the SecurityContext in GlassFish I think I was on the right track. It seems that the only thing I really need is to get all of its data filled correctly. This data means: realm and subject, where the subject would have to contain the username and all the required groups assigned to it. If this is the only thing I have to do than it's completely fine, because I can retrieve the list of groups for a user from an external system. Does that sound like a solution?Just this? Hmmmm where and what are the credentials? Sounds like the 'fake authentication' you mentioned earlier.
Of course there is a lot of potential in there to break/misuse stuff. However, there's also the notion of a ClientSecurityContext, which might be more appropriate. However, if I go that way and it works, then I effectively authenticate (from a container point of view) without using authentication at all, so in the end, I'm abusing container-internals and completely break the chain of trust (again, from a container point of view - not so for the application, because it is trusted). But again, this only works within the container and not so when using external systems and also will probably result in problems in a clustered environment.
09-18-2011 02:06 PM
@Resource
private EJBContext context;
@RolesAllowed("testGroup")
@Override
public String sayHello(String name) {
return "Hello " + name + " from " + context.getCallerPrincipal().getName() + "!";
}
final String name = "bob";
SudoAction<String> action = new GlassfishNoLoginSudoAction<String>() {
@Override
public String run() throws Exception {
SecuredEJB instance = (SecuredEJB) container.getContext().lookup("java:global/sudo/glassfish/SecuredEJB");
return instance.sayHello(name);
}
@Override
public String getRealm() {
return "file";
}
@Override
public Principal getCallerPrincipal() {
return new MyPrincipal("alice", "somewhere");
}
@Override
public Group[] getGroups() {
Group[] groups = new Group[1];
groups[0] = new MyGroup("testGroup");
return groups;
}
};
SudoService sudo = new SudoServiceGlassFish();
String result = sudo.sudo(action);
System.out.println("SUDO (no-login) invocation OK: " + result);
[#|…|JACC: new ProtectionDomain added to cache|#]
[#|…|JACC: returning cached ProtectionDomain - CodeSource: ((file:/classes/classes <no signer certificates>))
PrincipalSet: org.ancoron.sudo.glassfish.test.MyPrincipal@1f52f43b testGroup|#]
[#|…|JACC: Access Control Decision Result: true EJBMethodPermission (Name) = SecuredEJBImpl
(Action) = sayHello,Local,java.lang.String (Caller) = null|#]
…
SUDO (no-login) invocation OK: Hello bob from alice!
09-19-2011 05:24 PM
Principal or authentication details are safe when they stay in EJB context or Security-context.
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.