views:

220

answers:

2
+1  Q: 

JAXWS and sessions

I'm fairly new to writing web services. I'm working on a SOAP service using JAXWS. I'd like to be able to have users log-in and in my service know which user is issuing a command. In other words, have some session handling.

One way I've seen to do this is to use cookies and access the HTTP layer from my web service. However, this puts a dependency on using HTTP as the transport layer (I'm aware HTTP is almost always the transport layer but I'm a purist).

Is there a better approach which keeps the service layer unaware of the transport layer? Is there some way I can accomplish this with servlet filters? I'd like the answer to be as framework agnostic as possible.

+1  A: 

As you mention, servlet filters can provide the basis of solution. Use a filter to store the current session details (e.g. the session context Map) in a threadLocal storage. This is implemented as your application class, so is transport agnostic. Your service simply uses a static method to fetch the current context, unaware of where it came from.

E.g.

class ServiceSessionContext
{
    static ThreadLocal<Map> local = new ThreadLocal<Map>();

    // context set by the transport layer, e.g. servlet filter
    static public void setContext(Map map)
    {
        local.put(map);
    }

    // called when request is complete
    static public void clearContext()
    {
        local.put(null);
    }

    // context fetched by the service
    static public Map getContext()
    {
        return local.get();
    }
}    
mdma
Thanks, I think I can use this pattern to pass the token mentioned above into my service layer.
Pace
+2  A: 

I'm working on a SOAP service using JAXWS. I'd like to be able to have users log-in and in my service know which user is issuing a command. In other words, have some session handling.

Conventional Web services are stateless in nature, there is no session handling in web services (which has by the say nothing to do with identifying the caller).

If you want to require your users to be authenticated to call a service, the traditional approach is to:

  1. Expose an "authentication" web service (passing user credentials) that returns an authentication token.
  2. Have the users call this authentication first.
  3. Have the users pass the token in a custom header on subsequent calls of "business" web services.

On the server side:

  1. Reject any call that doesn't contain a valid token.
  2. Invalidate tokens after some time of inactivity

You can implement a custom solution for this approach (this is a highly interoperable solution). Or you can use WS-Security/UsernameTokens that provides something similar out of the box. WS-Security is a standard (Metro implements it), it isn't "framework" specific.

Pascal Thivent
Outstanding answer. Thank you very much.
Pace