users@jersey.java.net

Re: [Jersey] Web applications using XMLHttpRequest and JAX-RS REST/JSON Web Services

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Fri, 07 Nov 2008 10:51:01 -0800

Julio Faerman wrote:
> I would like to discuss this further, i think it is a very common
> question. Let me try do defend some "statefulness".
>
> 1- The overhead of session management is questionable, as there are
> efficient persistence and replication mechanisms available in modern
> app servers. If we are talking about a sufficiently large number of
> server, the overhead is tolerable.
>
Perhaps. But why pay the overhead at all if you don't have to? (Of
course, your point being you think the statefulness buys you something
that is worth this cost).
> 2- The use of HTTP-Basic auth is less secure, specially if not using SSL.
>
>
It's better to assume that HTTP Basic is *totally* insecure unless you
are using SSL. But the same is true of a typical login screen in a
webapp (unless you are using SSL for that screen). And it's also true
for the cookie or URL rewriting used to maintain the session identity
(again, unless you are using SSL).

Bottom line -- security implications are roughly the same.

One alternative to reduce the insecurity of something like HTTP Basic
(especially if you are a client app talking to a web service) would be
to use some sort of one-time password scheme, so that the expected
password changes on each request. A snooper can listen in on one
password, but can't use it to inject any more transactions of their own.
> 3- The session helps a lot when the information the system should
> provide is contextualized to the authenticated user. For example,
> showing the accounts of the salesperson using the system. A stateless
> app would require additional authorization checks to perform the same
> operation.
>
Yes, there will be more authorization checks (one per request instead of
one per logon). The tradeoff is storing more state in your session --
which increases the overhead of migrating it.
> I tried hard to keep my current project completly "stateless", and i
> agree on storing the minimum possible state in the session, but the
> benefits of a small session outweights the cost in most applications,
> IMHO.
>
>
In my experience, sessions are OK (although still not RESTful because
they mean you are designing your application differently) for single
instance servers. But the session migration overhead is high enough
that, for multi instance servers, I tend to see sticky sessions (entire
session goes back to one server) used, not migrate-on-every-request,
because the migration overhead *is* significant compared to the normal
request processing time.

Craig
> On Fri, Nov 7, 2008 at 6:25 AM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
>> Hi Craig,
>>
>> Well said! Further more you often find that some web sites will be hidden
>> behind one URL. It is not book markable.
>>
>> The current state of affairs is this: at any one point in time how to do you
>> know web sites you are logged into? how do you log out? the browser does not
>> know really anything, because it is all opaque through server-given opaque
>> identifiers, usually cookies.
>>
>> Would it not be nice for the browser, and therefore the user, to have more
>> control over this? Utilizing HTTP authentication can enable this because the
>> browser is aware of the authentication process. Unfortunately browsers today
>> do a dreadful job popping up an ugly dialog box to login. I am sure there
>> are ways to get nice login pages working with this type of mechanism but the
>> frameworks and tools do not encourage this type of approach, thus the least
>> path of resistance is to use a session, which can easily come to be a
>> decision one might regret later on.
>>
>> Paul.
>>
>> On Nov 7, 2008, at 9:11 AM, Craig McClanahan wrote:
>>
>>
>>> Craig McClanahan wrote:
>>>
>>>> Eduardo Pérez Ureta wrote:
>>>>
>>>>> Ideally I would like to use the servlet session.
>>>>>
>>> I should have responded to this particular statement in my previous
>>> response (sorry for the omission). And it relates to some comments I *did*
>>> make that might not make a lot of sense without a little bit of context.
>>>
>>> One of the key principles behind RESTful APIs is that they should be
>>> *stateless*. In other words, if the server is implemented as multiple
>>> instances of your application behind a load balancer, it should not matter
>>> if the (n)th request and the (n+1)th request are served by different
>>> instances. This is a key attribute in designing an application that can
>>> scale beyond a single server instance.
>>>
>>> When you use servlet sessions, you are risking a violation of this basic
>>> principle. Let's assume that you are taking the typical approach where a
>>> cookie is used to tell the client what session identifier to submit on
>>> subsequent requests. The usual server side implementation of a "session" is
>>> essentially a HashMap of session attributes, keyed by the session id. But
>>> the *crucial* point is that this information normally lives only within the
>>> context of a single JVM (i.e. a single instance of your server). Supporting
>>> an application that scales horizontally (that is, across multiple server
>>> instances) would require that either:
>>>
>>> * the load balancer recognize that a subsequent request belongs to an
>>> existing session on a *single* instance of your application, which means
>>> you are likely to experience service overloads if this single instance has
>>> too many active sessions. (You will often see this referred to as "sticky
>>> sessions").
>>>
>>> * the server environment recognizes that there is an existing session, but
>>> the data for it lives on some other server instance so it needs to be
>>> copied
>>> to this instance before the request can be processed. As you can imagine,
>>> there can be significant overhead in doing this sort of thing.
>>>
>>> With respect to authentication (which was the particular context of
>>> Eduardo's questions), the standard HTTP approach is to include an HTTP
>>> header named "Authorization" with each request -- most typically using the
>>> HTTP Basic authentication scheme (http://www.ietf.org/rfc/rfc2617.txt).
>>> This means that the authentication operation must occur on *every* request,
>>> but it also means that you can indeed scale your application across multiple
>>> server instances, because any one of them is capable of performing the
>>> authentication transaction. You would be wise, if you are planning on an
>>> application that does, or even *might*, require deployment of more than one
>>> instance, to keep this consideration in mind.
>>>
>>> For a Java developer who doesn't want to care about all the nuances and
>>> complexities of the HTTP protocol, my recommendation is pretty simple --
>>> figure out how to design your application without using sessions. For
>>> authentication, that's pretty simple ... just include the authorization
>>> header on each request (for human-interaction web applications, browsers
>>> even do this for you if your server is designed for HTTP Basic
>>> authentication). For application state, everything that the server needs to
>>> know about the current state should be included with each request. (The
>>> details of this topic is the source of many thesis-length dissertations, but
>>> the fundamental principle is pretty easy to grok.)
>>>
>>> Or, of course, if you *know* your application will never need more than
>>> one instance (even to ensure availability in the case of an instance
>>> failure), you can safely ignore this advice. But can you really be sure?
>>> (For a 10-user departmental app behind your company firewall, sure you can.
>>> For an Internet facing app, no way IMHO. All it takes is a single
>>> "Slashdot Effect" surge of interest in your app, which overloads your single
>>> server instance, to demonstrate to you (and to the world, unfortunately)
>>> that you weren't ready for Internet scale user traffic).
>>>
>>> Craig
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>