JAAS is driving me up the wall
moraelin Sep 5, 2002 7:40 AM(Originally miss-posted in the FAQ forum.)
OK, I've been trying to make an application's authorizing part for several days now and I don't even start to understand how to use JAAS with JBOSS. Either I'm too stupid (which could well be the case) or the docs are too brief, confusing and generally assuming that the user is already a seasoned expert in EJB's and JAAS. (I'm neither.) So far, it looks like it would have been less work (if also a lot less elegant) to just propagate the login data in each EJB method and be done with it.
The first thing is that it's NOT about servlets running in the same JVM. It's about client applications running not only in a different JVM, but likely on another machine and on another site.
It's also NOT about user names and passwords, but about authorizing the client applications, which in turn do their own user management. There's an application key data object (including application id, password, the application's own user id and whatever else needed) which needs to be hauled over RMI to the server, checked and (if correct) stored and a handle is issued as the principal.
So I start with the obvious: make a straightforward AppLoginModule and an AppLoginDataCallback and the corresponding callback handler. The AppLoginModule sends an array with just the AppLoginDataCallback, the handler sets the AppLoginData key in the callback and returns. The AppLoginModule would check and store the data, issue a unique key wrapped in a SimplePrincipal, and set the SecurityAssociation principal and credentials for it.
It works off-line (i.e., without JBOSS involved) with JAAS, or at least it gives me a principal all right...
Now let's get JBOSS involved.
First it doesn't even work at all. The same code seems to still login into the application's own JAAS library, instead of into the one in JBoss. Then it propagates that locally obtained Principal to JBOSS, which obviously never heard of it and rejects it.
I eventually run out of better ideas and make a huge wrapper EJB for one of the actual EJB's, with PrivilegedAction classes for each actual EJB call. Now my application calls this wrapper EJB, which itself tries to login inside JBOSS, before forwarding the call. I know it's inefficient, inelegant, and probably the Wrong Thing (TM), but hey...
Oops, now JBOSS can't find the AppLoginModule, even though it's right there in lib/ext. After a couple more hours of trying every stupid thing and muttering dark curses at the monitor, I find out that I need to use the org.jboss.security.auth.spi.ProxyLoginModule. Oh well...
Then I discover another cute problem. The login data was handled by an EJB, since it also needs to be manageable somehow. (And various services must be able to ask for details about an application calling them.) The AppLoginModule was really just calling the EJB to store the data and get the principal. Now I can't call the AppLoginEJB to get a principal, because I don't yet have a valid principal, but can't get a principal before I call the EJB. Catch 22.
OK, I take the whole checking code out for now, planning to just move it later somewhere else. (An MBean maybe, or make the AppLoginData object be a Principal itself.) So now the login module just issues a random principal itself, without calling the EJB or anything else.
Ok, so let's recap the chain so far: the client calls the wrapper EJB (which isn't in a security zone), which logs in, and then calls the original EJB (which is in a security zone) via a doAs().
Now the wrapper EJB does log in (finally), and I'm actually issued a principal. (The System.out.println's lavishly scattered all over the code say so.) Only when I actually forward the call to the original EJB, I get an exception. Apparently SecurityInterceptor.checkSecurityAssociation() doesn't like my shiny new Principal after all.
Anyone has any ideas what I'm doing so awfully wrong please?
Thanks in advance.