I am currently working on a REST library for .net, and I would like to hear some opinions about an open point I have: REST and authentication.
Here is an example of an RESTful interface used with the library:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
The server code then just implements the interface and the clients can obtain the same interface through a factory. Or if the client is not using the library a standard HTTP request also works.
I know that there are the major ways of either using HTTP Basic Auth or sending a token to requests requiring authenticated users.
The first method (HTTP Basic Auth), has the following issues (partly web browser specific):
- The password is transmitted with every request - even with SSL this has some kind of "bad feeling".
- Since the password is transmitted with a request header, it would be easy for an local attacker to look at the transmitted headers to gain the password.
- The password is available in the browsers memory.
- No standard way to expire user "sessions".
- Login with a browser interrupts the look and feel of a page.
The issues for the second method are more focused on implementation and library use:
- Each request URI which needs authentication must have a parameter for the token, which is just very repetitive.
- There is a lot more code to write if each method implementation needs to check if a token is valid.
- The interface will become less specific e.g.
[RestGet("/get/{id}")]
vs.[RestGet("/get/{id}/{token}")]
. - Where to put the token: at the end of the URI? after the root? somewhere else?
My idea was to pass the token as parameter to the URL like http:/server/user/get/1234?token=token_id
.
Another possibility would be to send the parameter as an HTTP header, but this would complicate usage with plain HTTP clients I guess.
The token would get passed back to the client as a custom HTTP header ("X-Session-Id") on each request.
This then could be completely abstracted from the interface, and any implementation needing authentication could just ask which user the token (if given) belongs to.
Do you think this would violate REST too much or do you have any better ideas?