2 Replies Latest reply on Mar 21, 2005 9:58 AM by starksm64

    Identifying a java.rmi.ServerException as a failed login exc

    nlejeune

      Hello Scott

      First of all I'd like to congratulate you on your jaas_howto document, I found it very useful both in understanding the concepts as well as the implementation details of JBoss.

      I will formulate my question around one of your example : example1-test2. That example tests access with an invalid password.

      Here is an extract of the client code

       try
       {
       AppCallbackHandler handler = new AppCallbackHandler(name, password);
       LoginContext lc = new LoginContext("TestClient", handler);
       System.out.println("Created LoginContext");
       lc.login();
       }
       catch (LoginException le)
       {
       System.out.println("Login failed");
       le.printStackTrace();
       }
      
       try
       {
       InitialContext iniContext = new InitialContext();
       SessionHome home = (SessionHome) iniContext.lookup(example + "/PublicSession");
       System.out.println("Found PublicSession home");
       Session bean = home.create();
       System.out.println("Created PublicSession");
       System.out.println("Bean.echo('Hello') -> " + bean.echo("Hello"));
       bean.remove();
       }
       catch (Exception e)
       {
       e.printStackTrace();
       }


      Even with a wrong password, the LoginException is never thrown. I understand this is due to the fact that the org.jboss.security.ClientLoginModule does not perform authentication. That behaviour is clearly stated in the documentation, I have no problem with that.

      What troubles me is that the exception that will be received by the client when trying to create a bean is a java.rmi.ServerException, and that to identify it's actually a SecurityException I have to travel down the exception chain and cast the nested-nested exception to an EJBException.

      Here is the exception that example1-test2 prints :
      client-test2:
       [java] +++ Running SessionClient with username=java, password=badpass, example=example1
       [java] Created LoginContext
       [java] Found PublicSession home
       [java] java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
       [java] java.rmi.ServerException: EJBException:; nested exception is:
       [java] javax.ejb.EJBException: checkSecurityAssociation; CausedByException is:
       [java] Authentication exception, principal=java
       [java] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:292)
       [java] at sun.rmi.transport.Transport$1.run(Transport.java:148)
       [java] at java.security.AccessController.doPrivileged(Native Method)
       [java] at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
       [java] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
       [java] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
       [java] at java.lang.Thread.run(Thread.java:534)
       [java] at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
       [java] at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
       [java] at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
       [java] at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source)
       [java] at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:135)
       [java] at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:96)
       [java] at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
       [java] at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:53)
       [java] at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:173)
       [java] at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
       [java] at $Proxy0.create(Unknown Source)
       [java] at org.jboss.docs.jaas.howto.SessionClient.main(SessionClient.java:79)
       [java] Caused by: java.rmi.ServerException: EJBException:; nested exception is:
       [java] javax.ejb.EJBException: checkSecurityAssociation; CausedByException is:
       [java] Authentication exception, principal=java
       [java] at org.jboss.ejb.plugins.LogInterceptor.handleException(LogInterceptor.java:347)
       [java] at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:124)
       [java] at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
       [java] at org.jboss.ejb.StatelessSessionContainer.internalInvokeHome(StatelessSessionContainer.java:319)
       [java] at org.jboss.ejb.Container.invoke(Container.java:743)
       [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       [java] at java.lang.reflect.Method.invoke(Method.java:324)
       [java] at org.jboss.mx.server.ReflectedDispatcher.dispatch(ReflectedDispatcher.java:60)
       [java] at org.jboss.mx.server.Invocation.dispatch(Invocation.java:61)
       [java] at org.jboss.mx.server.Invocation.dispatch(Invocation.java:53)
       [java] at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       [java] at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:185)
       [java] at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:473)
       [java] at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:360)
       [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       [java] at java.lang.reflect.Method.invoke(Method.java:324)
       [java] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
       [java] at sun.rmi.transport.Transport$1.run(Transport.java:148)
       [java] at java.security.AccessController.doPrivileged(Native Method)
       [java] at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
       [java] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
       [java] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
       [java] at java.lang.Thread.run(Thread.java:534)
       [java] Caused by: javax.ejb.EJBException: checkSecurityAssociation; CausedByException is:
       [java] Authentication exception, principal=java
       [java] at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:166)
       [java] at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:83)
       [java] at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:120)
       [java] ... 25 more
       [java] Found PrivateSession home
       [java] Failed to create PrivateSession as expected
      
      


      In my client code, to be sure the exception indicates a SecurityException and not another exception, I'd have to do something like

      catch (RemoteException e) {
       Throwable cause = e.getCause();
       if (cause != null) {
       cause = cause.getCause();
       if (cause != null && cause instanceof EJBException) {
       cause = ((EJBException) cause).getCausedByException();
       if (cause instanceof SecurityException) {
       // OK it was caused by a security problem, handle it
       ...
       }
       }
       }
       }
      


      Is it the right way to do it or is there a more elegant approach? Or did I miss something about the authentication process?

      Thank you for reading this


      Nicolas Lejeune
      Belgium.





        • 1. Re: Identifying a java.rmi.ServerException as a failed login
          severityone

          This is more or less the way that I'm doing it, except that I use a loop that keeps on retrieving the parent cause (with the getCause() method) until the message (from the getMessage() method) starts with 'checkSecurityAssociation'. This way, I remove a dependency in the application client on certain classes. The client doesn't have any references to JBoss classes in it, although it references jbossall-client.jar in the JNLP descriptor (it is launched from Java WebStart).

          I agree that it's not elegant, and handling an exception by actively looking at its cause(s) is not considered proper programming, but I see no other way.

          - Peter

          • 2. Re: Identifying a java.rmi.ServerException as a failed login
            starksm64

            More recent versions throw a security specific java.rmi.AccessException with the underlying cause.