users@jersey.java.net

Re: [Jersey] Security - Basic, Session, or Encrypted Key

From: Paul C. Bryan <pbryan_at_sun.com>
Date: Fri, 21 Aug 2009 09:09:38 -0700

My comments inline:

On Fri, 2009-08-21 at 11:19 -0400, Grover Blue wrote:
> I'm trying to add a security layer on top of my services. Below are
> the choices I think I have:
>
> Note: All would be required to run via HTTPS
>
> Basic Authentication:
> If I understand this correctly, the user of the WS sends a POST with a
> "Authorization Basic" header item. Browses cache the header line,
> sending it with each subsequent request. For users doing automation
> through code, they would have to include that with each request. So
> this method is effectively stateless.

Not quite. WS challenges with a 401 Unauthoized response (w.
WWW-Authenticate header), client needs to send username and password
credentials encoded in an Authorization header. As you point out, it is
stateless.

> Session Key:
> Even though the web server is stateless, it does run in a session,
> correct? So, another approach would be to have the resource generate
> a session key and save it to a session variable. I just haven't been
> able to figure out how to access the session scope from a JAX-RS
> service. If I could, the key could be return it in the response to
> the user, which would be appended to the resource URL in subsquent
> requests, like such:
>
> /resources/myservice/someGetMethod/someParam1/someParam2?sessionKey=ASDGJASFGKNASDGKNAKFADSF
>
> The key would be pulled from the URL and validated against what is in
> session:
>
> @GET
> @Path("/someGetMethod/{param1}/{param2}")
> @Produces("application/xml")
> public String getXmlByExternalIp(@PathParam("param1") String
> param1,
> @PathParam("param2") long param2,
> @QueryParam(value="sessionKey")
> String sessionKey) {
>
> // validate seesionKey, and return an appropriate
> response
>
> }
>

Indeed, though now you "pollute" your resource identifier by adding
transient parameters.

> Encrypted Key:
> I recently discussed WS security with a friend, and he told me about
> the approach Splunk takes. Apparently, the user POSTs their
> username/passowrd to /auth/login, which returns a specially encrypted
> key. The key is generate using a private server side key, which takes
> into account the username, password, start/end time (why time? - it's
> not like the key is updated). With each subsequent request the key is
> included in the POST, and it's decrypted on the server using the
> decryption key. The username/password is then re-evaluated. I can't
> verify any of this, though.

The only apparent difference between this and the session key is that
the server would not need to store state, because you can bake it into
the encrypted key instead. This has advantages and disadvantages.

Advantages:
* no need to coordinate state across servers in a farm

Disadvantages:
* need to coordinate keys between servers, and if key is compromised,
re-issue keys
* some potential for keys to be counterfeited, and server will simply
accept them
* depending how much state is required, key could get large

>
> What are your thoughts on these approaches?
>

I'd suggest looking at the OAuth support in Jersey. In OpenSSO, we're
using OAuth for authenticating requests to RESTful web services. You can
find more information on the OAuth work in Jersey at:

http://wikis.sun.com/display/Jersey/OAuth

Paul