REST and Authentication Options

I am currently working on a REST library for .net, and I would like to hear some opinions about the open point I have: REST and authentication.

Here is an example of the 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); } 

Then, the server code simply implements the interface, and clients can get the same interface through the factory. Or, if the client does not use the library, the standard HTTP request also works.

I know that there are basic ways to use HTTP Basic Auth or send a token to requests that require authenticated users.

The first method (HTTP Basic Auth) has the following problems (partially a web browser):

  • A password is sent with every request - even with SSL it has some kind of "bad feeling".
  • Since the password is transmitted with the request header, it would be easy for a local attacker to look at the transmitted headers in order to obtain the password.
  • Password is available in browser memory.
  • There is no standard way to expire user sessions.
  • Login to the browser interrupts the appearance of the page.

The problems for the second method are more focused on the implementation and use of the library:

  • Each URI request that requires authentication must have a parameter for the token, which is very repetitive.
  • There is much more code to write if each implementation of the method needs to check if the token is valid.
  • The interface will become less specific, for example. [RestGet("/get/{id}")] versus [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 a parameter to the url, like http:/server/user/get/1234?token=token_id .

Another possibility is to send the parameter in the form of an HTTP header, but this will make it difficult to use it using regular HTTP clients, which I suppose.

The token will be sent back to the client as a custom HTTP header ("X-Session-Id") for each request.

This can be completely abstracted from the interface, and any implementation that needs authentication can simply ask who the token belongs to (if given).

Do you think this violates REST too much or do you have any ideas?

+67
authentication rest
Jan 19 '09 at 17:47
source share
3 answers

I am inclined to believe that the authentication data belongs to the header and not to the URI. If you rely on a token hosted in a URI, then each URI in your application must be encoded to include the token. It will also negatively affect caching. Resources with a token that is constantly changing can no longer be cached. The information related to the resource belongs to the URI, not the data associated with the application, such as credentials.

It seems you should focus on web browsers as a client? If this is the case, you can investigate using HTTP digest authentication or issuing your own SSL certificates to clients for their unambiguous identification and authentication. In addition, I do not think that session cookies are necessarily bad. Especially when you have to deal with the browser. As long as you isolate the cookie processing code and do not rely on it, everything will be all right. The key stores only the user ID in the session, nothing more. Do not abuse server-side session state.

If you are targeting clients other than the browser, there are several approaches you can take. I got lucky using the Amazon S3 Authentication engine.

Of course, this is very subjective. Cleanliness and subsequent REST to a letter can sometimes be impractical. As long as you minimize and isolate this behavior, the core of your application can still be RESTful. I highly recommend RESTful Web Services as an excellent source of REST information and approaches.

+63
Jan 21 '09 at 20:21
source share

I agree with workmad3, if a session must be maintained, you must create a session resource. A message about this resource with user credentials (either basic authentication or credentials in the body contents) will return a unique session identifier. Delete on / session / {id} will exit the system.

If you want to control session expiration time. When creating a new session (message on the session resource), the server will set a cookie for the response (using the standard set-cookie header). The cookie will contain the expiration time. The cookie string must be encrypted on the server, so only the server can open this cookie. Each subsequent request to the server sends the session cookie to the cookie header. (this will be done automatically for you if your client is a browser). The server needs to β€œupdate” the cookie for each request, i.e. Create a new cookie with a new expiration time (extend the session timeout). Remember to clear the cookie when the user invokes deletion in the session resource.

If you want your application to be more secure, you can store the client's IP address in the cookie itself, so when the request arrives, the server can confirm that it was sent from the "original" client. But remember that this solution can be problematic when using a proxy, because the server can β€œsee” all requests coming from the same client.

+16
Jan 21 '09 at 18:27
source share

The rest of the authentication I saw treats the sessions as a REST resource to create, destroy, etc., and then the session identifier is passed back and forth. The ones I saw tend to use a session cookie for this, as this is the only way to actually protect it. If you pass the session ID in the URL, you have no way to truly authenticate it from the correct client.

Authentication is a complex issue with REST, though, since it requires some form of state to be stored outside the URL, which violates the REST principles of the URL, which is all that is required to represent the state.

+4
Jan 19 '09 at 18:05
source share



All Articles