3

I don't think it is RESTful when authorization infiltrates into the representations of resources. The identity of the current user is strictly client state, so it should not effect on the representation of a resource except if identification factors or user id or permission details is sent with the request.

If you were using sessions this would be the stateful part of the process: For example if you want to read the profile page of somebody, you will have 2 representations: users/123 and users/123?editable=true. It depends on the permissions of the session whether you can choose the editable one. Where should the editable link appear? If it appears in the /users/123 representation only in that case if you have the permissions, then it violates the statelessness constraint of the service, because the representation of the resource will depend on the permissions of the current session. :S So if you want to have different representation for each user then you have to send something about this with every request.

Does anybody have a good solution for that? Is it possible to use sessions and separate the stateful part from the service?

Is it possible to completely separate the permissions dependent part from the resource dependent part by creating the response? (In that case the resource dependent part would be well maintainable even with sessions and it would be much easier to cache it.)

inf3rno
  • 24,976
  • 11
  • 115
  • 197
  • 2
    If you send credentials (explicit or security tokens) on each request, and validate authorization on each request, you are still stateless without session on your REST server to remember who was logged in before, so I believe it is still RESTful, maybe it is possible to consider request headers (like authentication / authorization) as an implicit part of your REST query. – zenbeni Dec 01 '13 at 15:14
  • I don't think so, you have very simple rules by authorization. If the user is not logged in then the response must be 401. If she is logged in, but not authorized, then the the response must be 403. If she is authorized, then by GET requests the response must be the representation of the resource. There is no such rule, that if the user is authorized, then she should get the representation of the resource, and if not, then she should get another representation of the resource... If you want your representation to stay stateless and cacheable, you have to obey these rules... – inf3rno Dec 02 '13 at 08:04
  • You seem to have the wrong idea about statelessness and representations. REST stands for "REpresentational State Transfer." In short, the server is communicating the state of its resources through representations of those resources it sends to the client. The communication itself is stateless "such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server" (Fielding, section 5.1.3). – Jonathan W Dec 02 '13 at 16:56
  • `Stored context` means for example session variables. If you still want to use sessions on the server they should not effect on the structure of the representation of a resource. They should only effect whether the server returns the requested representation or it just sends a 401 or 403 status header. – inf3rno Dec 02 '13 at 18:55
  • 3
    There are 2 problems with your question. Problem #1: "If it appears in the /users/123 representation only in that case if you have the permissions, **it violates the statelessness constraint of the service, because the representation of the resource will depend on the permissions of the current session.**" That is not true if you don't have a session. User permissions can be derived from the username / password credentials based as HTTP Basic authorization headers. So you *can* do this and it's okay from a REST perspective. – Jonathan W Dec 03 '13 at 02:10
  • 2
    Problem #2: "The identity and the permissions of the current user is strictly client state." If anything, the inverse is true. The client doesn't need to even have a notion of permissions. All the client needs is to be presented with a list of links it can follow, tailored to its specific authorizations as deemed appropriate on the server. Think about your typical web page. You don't display an "Edit" button if the user making the request doesn't have authorization to edit the given data. So why should a RESTful API be any different? – Jonathan W Dec 03 '13 at 02:17
  • @JonathanW I agree with the assessment in comment [1] by inf3rno. But from your comments I understand that the following case is RESTful : GET /things with credentials for user Bob gets the 'thing' resources of user Bob, followed by GET /things with credentials for user Alice gets the 'thing' resources for Alice. I don't think this is correct because the request isn't idempotent any more in that way: the response changes depending on the credentials. Correct would be e.g. GET /users//things and GET /users//things. Do you agree? [1] http://bit.ly/19c7ysI – Visionscaper Mar 11 '15 at 15:33
  • @Visionscaper I don't. I think it would be easier to cache the responses, but since you are "logged in" it would be `cache-control: private` in any regular webapplication, so a different URI per user would not have any advantage. – inf3rno Mar 11 '15 at 19:01
  • Inf3rno, @JonathanW, I ended up creating a new SO question [1] and answer [2]. Input is always welcome :) [1] http://stackoverflow.com/q/29005275/889617 [2] http://stackoverflow.com/a/29005276/889617 – Visionscaper Mar 12 '15 at 09:01

1 Answers1

0

Should a RESTful representation depend on user permissions?

Yes.

I don't think it is RESTful when authorization infiltrates into the representations of resources. The identity of the current user is strictly client state, so it should not effect on the representation of a resource except if identification factors or user id or permission details is sent with the request.

It is client state, but you can send it with every message, so it does not violate the stateless constraint.

Is it possible to use sessions and separate the stateful part from the service?

Server side sessions are not allowed because they would violate the stateless constraint.

inf3rno
  • 24,976
  • 11
  • 115
  • 197
  • 2
    I'm sorry, but I no longer think I understand either your question or your answer. – Jonathan W Dec 02 '13 at 16:36
  • There are 3 states by REST. There is the state of the REST client, which can contain the current page loaded in the browser, the identity of the user, the pagination settings, etc... There is the state of the resources, and there is the application state which is these two states together. The communication is stateless between the client and the service, when the client sends everything with the request, which is necessary to generate the response. If it sends a session id, and the service gets the user identity from the session store, then the communication won't be stateless. – inf3rno Dec 02 '13 at 19:03
  • The server could choose to not implement sessions at all, as HTTP Basic requires that the client provide credentials necessary for authentication for every request. That's basically what you're describing when you say send the user ID with every request (except that you are also sending the password). – Jonathan W Dec 02 '13 at 19:09
  • This is important because of at least 2 things. 1: The response won't be cacheable, if it depends on headers and cookies. 2: If you start a new server instance, and if the representation of a resource depends on the session variables, it will be very hard to synchronize a big network of instances. If the representation of resources does not depend on permissions, then you can create an authorization server which filters the requests, and you can create multiple resource server instances which provide representations. – inf3rno Dec 02 '13 at 19:12
  • Yes if you send the username and password with every request, then it is okay, but with a good hash algorithm, for example with blowfish, it will be very slow. – inf3rno Dec 02 '13 at 19:16
  • Using a separated authorization server and separated resource server instances is a good choice, and the only way to do that if you detach the authorization from the generation of the content. – inf3rno Dec 02 '13 at 19:18
  • 2
    I would assume that's only if both the client and server do *not* cache the hash (internally), which would be folly. Both can cache the hash and preserve statelessness in the communication. Bu you only need a hash if you're using Digest. HTTP Basic simply does Base64-encoding of the username/password. Now to your question, not every response should be cached. Having a cacheable architecture does not mean that caching is truly the desired behavior for every request and response. It's going to depend wildly on your system and what your needs are. – Jonathan W Dec 02 '13 at 19:18
  • Okay, then http auth with caching the hash is a RESTful solution too. – inf3rno Dec 02 '13 at 19:24
  • I'll add that to my answer. – inf3rno Dec 02 '13 at 19:25
  • Heh. After all that, I still don't understand what problem you're trying to solve, so I guess updating your answer makes sense... as long as you know what you're talking about. – Jonathan W Dec 02 '13 at 19:26
  • I'll explain it tomorrow, I am too tired for that now... :-) – inf3rno Dec 02 '13 at 19:39
  • 1
    Interesting update. Unfortunately, it still doesn't make a lot of sense. You make many misstatements about statelessness, hashes, and sessions, and your arrows are undecipherable. Is anyone else watching this question and can perhaps clarify this for me? – Jonathan W Dec 03 '13 at 19:38
  • Is the question clear for you? If yes, you can add your own answer. – inf3rno Dec 03 '13 at 19:48
  • I believe your main problem is to enable cache on your queries based only on your HTTP requests (URL, params). Being cacheable is not directly coupled with REST, but can be a part of a REST architecture. That is why your question / answer seem strange to me as well. You should explain your problem only about cache (within REST) not about statelessness (ie: RESTful) and for instance you can use REST with states as well. It is not forbidden and can suit many interesting cases. – zenbeni Dec 10 '13 at 11:32
  • Yes, I confused statelessness with caching, now both are clear. Thank you for your comment! – inf3rno Dec 10 '13 at 14:38