Adam,

I use an older version of the library (v 1.2-b1), so what I do might not be the most accurate with the latest version (though I assume it's practically the same).

The basic authentication credentials are available by implementing the AuthenticatedXmlRpcHandler interface (or ContextXmlRpcHandler) in your handler class. So, if your handler class implements this interface, the execute method will be called with the client's username and password from the basic authentication.

From there, it's just a matter of looking up and validating the credentials, matching it up to a user session, etc. I basically keep some User objects cached in a Map, keyed off of the username and password. Or, you could just go straight to the database to lookup the user each request.

Now, the interesting thing with this approach is that your public methods in your handler class are now not "exposed" to the client. When you implement one of the XmlRpcHandler interfaces, the class isn't introspected for public methods. What you can do though is call the Invoker class which will then do the reflection just like the non-implementing "basic" handler class would.

So, your calculator class might look something like this (note, I didn't compile this, just typing off the top of my head):


public class Calculator implements AuthenticatedXmlRpcHandler {
        
        // needed to store the current user in a thread safe way
        private ThreadLocal<User> userThreadLocal = new ThreadLocal<User>();


public Object execute(String method, Vector params, String username, String password) throws Exception {

                // check username and password and store it
                User user = getUser(username, password);
                userThreadLocal.set(user);
                
                // use the Invoker on this class.
                Invoker invoker = new Invoker(this);
                Object obj = invoker.execute(method, params);

                return obj;
        }

        public int add(int i1, int i2) {
                // check the user
                User user = userThreadLocal.get();
                user.checkSomeProperty();
                return i1 + i2;
        }

        public int subtract(int i1, int i2) {
                return i1 - i2;
        }
}

Obviously, in the example above, you'll need a supporting User class. I also end up storing the user in a ThreadLocal (as you can see), so that the methods (add, subtract) can get to the user object and change the behavior of the method based on it. I tried to demonstrate this above.

Hope this helps.


Adam Bennett wrote:
I've got the server and client example code working, (the Calculator),
and I enhanced it to use HTTP basic authentication.  The next thing I
need is for the server to know which user is making the request.  For
example, on the server we have:
package videx; public class Calculator
{
  public int add(int i1, int i2)
  {
    return i1 + i2;
  }
public int subtract(int i1, int i2)
  {
    return i1 - i2;
  }
}
But instead lets say the result of the subtract() method depends upon
the user who is making the call.  That is, the user supplied during the
authentication process.  I know that if I can get the HttpServletRequest
object then I can query it for this information, but how do I get at it?
Is this possible with this library?

The real need for this steams from the fact that each user has a
different view of the data in our database and thus the response will be
different for each user.

Thanks for your help on this.
- Adam


This message has been scanned by Symantec Mail Security for SMTP.

Reply via email to