I suspect the key concept is realising that there can be many authz URIs — and 
that that is ok. OAuth libraries should support this concept — perhaps by not 
expecting a single authz URI to be provided in a config file.

I fully agree with your statement. Authorization servers may use different URLs for different resource servers. For example, our token service uses URLs like

https://tokenservice.example.com/tokens/service1
https://tokenservice.example.com/tokens/service2

to identify services and their respective tokens.

b) documenting something that no one has built yet,
and that might not actually work
Defining a scope field in a 401 response is the novel aspect that “might not 
actually work”. Allowing a 'scope' query parameter in authz URIs is be quite 
separate.


I agree again. Moreover, I would say a 401 response is not the right place to talk about scopes. From my point of view, the scope is about permissions (authorization) and not about authentication. So a scope violation should be signaled using status code 403 (Forbidden).

from rfc2616
"The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead."

So if the token send with a request is not suffiently scoped, the server could respond as follows

HTTP/1.1 403
insufficient permission, required scope=delete

---------------------------------

I followed this thread the last days and came to the following conclusions/perception I would like to discuss:

Providing authorization server endpoint URLs to clients dynamically is a must have. Otherwise, URL cannot be changed easily by the resource or authorization server. Every authorization server may use several authz URLs. Such URLs may also contain query parameters. The client should use these URLs "as is" and add further parameters required for the flow it uses, respectively.

Realm in contrast to scope is about authentication domains. The realm element represents a protection doamin, typically identified with a single user database. In the context of OAuth, the authorization server (conceptually) represents a user database, but I don't tend to say the authorization server is the realm. I would suggest a realm represents the set of endpoints accepting the same kind of token (by content) issued by the same authorization server. Different tokens are need if authorization servers issue service-specific self-containt tokens with different contents (attributes or permissions), typically protected by different signatures. If an authorization server issues one kind of token only, which can be used on all services it is responsible for, there is one realm only. In contrast, if the authorization server issues different tokens, every realm is the set of resource servers (services) accepting this kind of token. Based on this definition, libraries can automatically send a particular token to all resource servers using the same realm.

A scope defines the set of permissions a client asks for and that becomes associated with tokens. I don't see the need (and a way) for automatic scope discovery. In my opinion, scopes are part of the API documentation of a particular resource server. So if someone implements a client, it needs to consider the different scopes this client needs the end users authorization for. If the resource server implements a OAuth2-based standard API (e.g. for contact management or e-Mail), a client might be interoperable (in terms of scopes) among the resource servers implementing this standard.

A token may be issued to a particular realm but it might not suffienctly be authorized to perform all possible actions on all corresponding resource servers. This means that the servers can interpret the token but may refuse to process a particular requests. Generally, a client should know the maximum set of permissions (scope) needed to function properly and indicate this during the authorization process.

I would like to illustrate what I have written in an example:

The client wants to access a photo on server webstorage.example.com

GET  /photos/example.jpg HTTP/1.1
     Host: webstorage.example.com

The server responds with the following header:

WWW-Authenticate Token realm="http://authorize.example.com/webstorage";,
authz-uri="https://authorize.example.com/oauth2/tokens/webstorage?format=compact";,
               token-uri="https://authorize.example.com/oauth2/tokens";

The client does not find a refresh token for the realm "http://authorize.example.com/webstorage"; in its persistent storage and thus initiates a authorization process. This time the client does not request a certain scope, so a default scope is automatically selected by the authorization server.

GET /oauth2/tokens/webstorage?format=compact&type=web_server&client_id=s6BhdRkqt3&redirect_uri=
         https%3A%2F%2Fwebstorage%2Eexample%2Ecom%2Fcb HTTP/1.1
     Host: https://authorize.example.com

After obtaining the token, the client retries the service request

GET  /photos/example.jpg HTTP/1.1
     Host: webstorage.example.com

Authorization: Token token="ECDuk8mV8OJIK6D6PAteNtXJAAsEBwAAASgsdUvAAAABKC4sv8ABAAgAAAEoLHVLqBShAyHT24Hq78UYdr3a-
bDggz2IAgwQAEkBUXdxYwACAAETJQAAAAA="

HTTP/1.1 200 OK

The client now wants to download another photo. Since the resource path contains the "same last symbolic element in the path field of the Request-URI", the token is automatically reused for that request.

GET  /photos/example1.jpg HTTP/1.1
     Host: webstorage.example.com

Authorization: Token token="ECDuk8mV8OJIK6D6PAteNtXJAAsEBwAAASgsdUvAAAABKC4sv8ABAAgAAAEoLHVLqBShAyHT24Hq78UYdr3a-
bDggz2IAgwQAEkBUXdxYwACAAETJQAAAAA="

After that, the client wants to download a video on the same resource server. Since the URL differs, it sends an unauthorized request first

GET  /videos/example1.mpg HTTP/1.1
     Host: webstorage.example.com

WWW-Authenticate Token realm="http://authorize.example.com/webstorage";,
authz-uri="https://authorize.example.com/oauth2/tokens/webstorage?format=compact";,
               token-uri="https://authorize.example.com/oauth2/tokens";

The resource server responds with the same realm as before thus the client can reuse the token again.

GET  /videos/example1.mpg HTTP/1.1
     Host: webstorage.example.com

Authorization: Token token="ECDuk8mV8OJIK6D6PAteNtXJAAsEBwAAASgsdUvAAAABKC4sv8ABAAgAAAEoLHVLqBShAyHT24Hq78UYdr3a-
bDggz2IAgwQAEkBUXdxYwACAAETJQAAAAA="

In the last step, the client wants to delete a photo. It sends the following request

DELETE /photos/example.jpg HTTP/1.1
     Host: webstorage.example.com

Authorization: Token token="ECDuk8mV8OJIK6D6PAteNtXJAAsEBwAAASgsdUvAAAABKC4sv8ABAAgAAAEoLHVLqBShAyHT24Hq78UYdr3a-
bDggz2IAgwQAEkBUXdxYwACAAETJQAAAAA="

Since the token has a default scope, which does not contain the permission to delete anything, the server responds with a status code 403 and a description of the problem in the response entity.

HTTP/1.1 403
scope=delete

Hence the client initiates an authorization process in order to obtain this additional authorization (together with a standard set of other permissions).

GET /oauth2/tokens/webstorage?format=compact&type=web_server&client_id=s6BhdRkqt3&redirect_uri= https%3A%2F%2Fwebstorage%2Eexample%2Ecom%2Fcb&scope=read,upload,delete HTTP/1.1
     Host: https://authorize.example.com

In the last call, the client uses the new token to delete the photo.

DELETE /photos/example.jpg HTTP/1.1
     Host: webstorage.example.com

Authorization: Token token="ECCkrX3ASC9BCLnjOzmYzMSHAAsEBwAAASgsgwIuAAABKC46di4BAAgAAAEoLIMCFwtd7LCwTW6MflQB8WT_mjZVQNpZAgwQAEkBUXdxYwACAAETJQAAAAA="

HTTP/1.1 200 OK

Any thoughts?

regards,
Torsten.

_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to