Eduardo Pérez Ureta wrote:
> I am developing a web site using XMLHttpRequest and REST/JSON
> extensively. Now I want to add authentication to the REST Web
> services.
> The use case in question is having the user request some service and
> getting an error like "Not authorized!" instead of the data to be GET
> or POST.
> Ideally I would like to use the servlet session. Do you guys know of
> any successful implementation of REST/JSON authenticated Web Services
> for use with XMLHttpRequest Web applications?
>
> What would be the best way to signal authentication errors?
> - Return a HTTP 2xx response with a JSON object that contains a error
> object like:
> {"error":"Not authorized!"}
> - Return an error HTTP response with the error (possibly in plain
> text) (I think this should not be used as the error is not in the HTTP
> transport)
>
>
The "best practices" way to do this, per the HTTP 1.1 specification, is
to send back an HTTP response with a status code 401 ("Unauthorized")
for bad credentials. In addition, your application might require
checking whether a validated user can actually access the data they are
asking for. If not, they should get back a 403 ("Forbidden") response.
With JAX-RS and Jersey, all this is pretty easy if you code your
resource class methods something like this (for do-it-yourself
authentication/authorization):
@GET
@path("customer/{id}")
public Response findCustomer(@PathParam("id") String id,
@HeaderParam("Authorization") String authorization)
User user = MyLogic.lookupUser(authorization); // Return null if
not a valid user
if (user == null) {
return Response.status(401); // Username/password are
missing or invalid
} else if (!allowedToAccessCustomer(user, id) {
return Response.status(403); // Valid user but disallowed access
}
Customer customer = MyLogic.lookupCustomer(id); // Return null
if not an existing customer
if (customer == null) {
return Response.status(404); // Standard HTTP response for
requesting nonexistent data
}
return Response.ok(customer);
}
In a servlet based webapp, you could also use pretty much any of the
existing authorization filter schemes (like Acegi Security, or the
standard security mechanisms built into the servlet spec), which will
typically intercept your request and do the authentication check before
the request ever gets to your resource class, so you can assume (if you
are called) that the user has been validated already.
> Anyway I would like to see a successful implementation for reference.
> I would also like to see any standard way to protect from Cross-site
> request forgery.
>
>
Are there particular aspects of CSRF that you are concerned about? Note
that most of this is not specific to RESTful web services, so pretty
much any technique that works for general webapps is likely to work here
as well.
Craig