Alexander is correct and the problem exists in the current cvs code. Here is a trival 
client
fragment that reproduces the problem:


public class StatelessSessionClient
{
    static void runAs(String username, char[] password)
    {
        LoginContext lc = null;
        try
        {
            AppCallbackHandler handler = new AppCallbackHandler(username, password);
            lc = new LoginContext("StatelessSessionClient", handler);
            System.out.println("Created LoginContext, username="+username);
            lc.login();
        }
        catch(LoginException le)
        {
            System.out.println("Login failed");
            le.printStackTrace();
            return;
        }

        try
        {
            InitialContext jndiContext = new InitialContext();
            StatelessSessionHome home = (StatelessSessionHome) 
jndiContext.lookup("StatelessSession");
            System.out.println("Found StatelessSessionHome");
            StatelessSession bean = home.create();
            System.out.println("Created StatelessSession");
            System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
            lc.logout();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) throws Exception
    {
        runAs("scott", "echoman".toCharArray());
        runAs("stark", "javaman".toCharArray());
    }
}

Two separate stateless session beans are being created with two different client 
identities.
This information is being passed to the server correctly, bu the SecurityInterceptor 
is not
using the method invocation credentials correctly. The problem is with the check of the
current thread's security association:

      Principal principal = SecurityAssociation.getPrincipal();
      Object credential = SecurityAssociation.getCredential();
      if (principal == null)
      {
         principal = mi.getPrincipal();
         credential = mi.getCredential();
         if (principal == null || !securityManager.isValid( principal, credential ))
         {
            // should log illegal access
            throw new java.rmi.RemoteException("checkSecurityAssociation", new 
SecurityException("Authentication exception"));
         }
         else
         {
            SecurityAssociation.setPrincipal( principal );
            SecurityAssociation.setCredential( credential );
         }
      }

The first three lines should not be there as the security association of the current 
thread does
not mean anything. If set, it is the identity of some previous method invocation 
dispatch. The
only place SecurityAssociation.setPrincipal() is invoked on the server side is in the
SecurityInterceptor in the above code block. The SecurityInterceptor should just be 
taking
the security information from the method invocation. Dropping the check of the current
thread security association yields the correct behavior:

     Principal principal = mi.getPrincipal();
     Object credential = mi.getCredential();
     if (principal == null || !securityManager.isValid( principal, credential ))
     {
        // should log illegal access
        throw new java.rmi.RemoteException("checkSecurityAssociation", new 
SecurityException("Authentication exception"));
     }
     else
     {
        SecurityAssociation.setPrincipal( principal );
        SecurityAssociation.setCredential( credential );
     }

bash 1127> java -Djava.security.auth.login.config=$jboss_home/client/auth.conf 
StatelessSessionClient
Created LoginContext, username=scott
Found StatelessSessionHome
Created StatelessSession
Bean.echo('Hello') -> Hello
Created LoginContext, username=stark
Found StatelessSessionHome
java.rmi.ServerException: RemoteException occurred in server thread; nested exception 
is:
        java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
        java.lang.SecurityException: Illegal access exception
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:        
java.lang.SecurityException: Illegal access
exception
java.lang.SecurityException: Illegal access exception
        at 
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)
        at 
org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)
        at org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:221)
        at $Proxy0.create(Unknown Source)
        at StatelessSessionClient.runAs(StatelessSessionClient.java:69)
        at StatelessSessionClient.main(StatelessSessionClient.java:83)
bash 1128>

----- Original Message -----
From: "Alexander Klyubin" <[EMAIL PROTECTED]>
To: "jBoss Developer" <[EMAIL PROTECTED]>
Sent: Tuesday, January 23, 2001 8:08 AM
Subject: RE: [jBoss-Dev] jaas - commit()


> No, I was looking at & testing with the code of PRE-2.1 checked out on
> January, 18.
>
> Alexander Klyubin
>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]]On Behalf Of Oleg Nitz
> Sent: Tuesday, January 23, 2001 13:12
> To: jBoss Developer
> Subject: Re: [jBoss-Dev] jaas - commit()
>
>
> Hi Alexander,
>
> Are you using JBoss 2.0?
> Then the bug that you report may have been already fixed.
> It was in EnterpriseContext.java where the beanPrincipal is cached -
> it wasn't properly cleaned when EnterpriseContext was reused for
> another method invocation.
>
> Regards,
>  Oleg
>



Reply via email to