JAAS Principals problem

Programming, for all ages and all languages.
Post Reply
jelleghys

JAAS Principals problem

Post by jelleghys »

Hello,

I'm working on a forum application in Java. We have a server saving all users, topics, messages etc. We use java.rmi for the clients to post messages etc.

Before being able to post anything, users have to login. We use the JAAS technology for the authentication and authorization. A client logs in on the server and gets a Subject object in return. This object contains some Principals. If I understand correctly, the client will be able to execute stuff on the server according to which Principals the Subject contains.

At the client side there's an interface (which extends java.rmi.Remote) with this method:

Code: Select all

public Subject anonymousLogIn(IUserCallbackHandler callbackHandler) throws RemoteException;
At the server side an identical interface exists plus a class implementing the interface (and extending java.rmi.server.UnicastRemoteObject):

Code: Select all

public Subject anonymousLogIn(IUserCallbackHandler callbackHandler) throws RemoteException {
      LoginContext loginContext = null;
      
      try {
          loginContext = new LoginContext("AnonymousLogin", callbackHandler);
          loginContext.login();
      } catch (LoginException le) {
          le.printStackTrace();
          return null;
      } 
       return loginContext.getSubject();
    }
The server side has only knowledge of the interface IUserCallbackHandler (which extends javax.security.auth.callback.CallbackHandler) while the client side also has a class implementing this interface.

There's a config file (on server side) with these lines:

Code: Select all

AnonymousLogin {
   authmodule.CaptchaAuthenticationModule required;
};
CaptchaAuthenticationModule is a class on the server side. It implements LoginModule and thus has the following method:

Code: Select all

public boolean commit() throws LoginException
in which these lines of code are executed:

Code: Select all

Principal anonymousUserPrincipal = new AnonymousUserPrincipal("");
$subject.getPrincipals().add(anonymousUserPrincipal);
$subject is a javax.security.auth.Subject. AnonymousUserPrincipal implements java.security.Principal.


I think you have enough information now to understand my problem.

If we run our application and try to login, we get this:

Code: Select all

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
   java.lang.ClassNotFoundException: principals.AnonymousUserPrincipal (no security manager: RMI class loader disabled)
   at sun.rmi.server.UnicastRef.invoke(Unknown Source)
   at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
   at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
   at $Proxy0.anonymousLogIn(Unknown Source)
   at presentation.sysout.StartBaseAction.runAnonymousLogin(StartBaseAction.java:129)
   at presentation.sysout.StartBaseAction.run(StartBaseAction.java:43)
   at presentation.sysout.TextMain.start(TextMain.java:24)
   at domain.core.Client.main(Client.java:17)
Caused by: java.lang.ClassNotFoundException: principals.AnonymousUserPrincipal (no security manager: RMI class loader disabled)
   at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
   at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
   at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
   at java.rmi.ser.......
This is because the client side has no knowledge of a AnonymousUserPrincipal. If we add the classes implementing java.security.Principal there is no problem. But I think that's not the right solution. The client must not have the Principal classes. Isn't it?

Any ideas?

Thanks!
jelleghys

Re:JAAS Principals problem

Post by jelleghys »

We've found a solution. The classes implementing Principal (like AnonymousUserPrincipal) have to extend java.rmi.server.UnicastRemoteObject.


- Jelle
Post Reply