Re: [OAUTH-WG] 'Scope' parameter proposal

Torsten Lodderstedt <torsten@lodderstedt.net> Fri, 23 April 2010 22:31 UTC

Return-Path: <torsten@lodderstedt.net>
X-Original-To: oauth@core3.amsl.com
Delivered-To: oauth@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 0FC693A691F for <oauth@core3.amsl.com>; Fri, 23 Apr 2010 15:31:33 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.466
X-Spam-Level:
X-Spam-Status: No, score=-0.466 tagged_above=-999 required=5 tests=[AWL=-1.417, BAYES_50=0.001, HELO_EQ_DE=0.35, J_CHICKENPOX_56=0.6]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Zp6jI0nCQLkF for <oauth@core3.amsl.com>; Fri, 23 Apr 2010 15:31:31 -0700 (PDT)
Received: from smtprelay04.ispgateway.de (smtprelay04.ispgateway.de [80.67.31.31]) by core3.amsl.com (Postfix) with ESMTP id 3F2BC3A687E for <oauth@ietf.org>; Fri, 23 Apr 2010 15:31:30 -0700 (PDT)
Received: from p4fff0841.dip.t-dialin.net ([79.255.8.65] helo=[127.0.0.1]) by smtprelay04.ispgateway.de with esmtpa (Exim 4.68) (envelope-from <torsten@lodderstedt.net>) id 1O5ROz-00026i-C6; Sat, 24 Apr 2010 00:31:13 +0200
Message-ID: <4BD21FAD.8030706@lodderstedt.net>
Date: Sat, 24 Apr 2010 00:31:09 +0200
From: Torsten Lodderstedt <torsten@lodderstedt.net>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4
MIME-Version: 1.0
To: "Manger, James H" <James.H.Manger@team.telstra.com>
References: <C7F1D1FC.32809%eran@hueniverse.com> <0D5497F5-75A7-4A42-9A5E-9C2310162B18@jkemp.net> <90C41DD21FB7C64BB94121FBBC2E723438E5C7F30A@P3PW5EX1MB01.EX1.SECURESERVER.NET> <g2mdaf5b9571004221036j5d6837f6z4d7959d69a3cbb2b@mail.gmail.com> <BB02FD4F-071E-4FF5-B3D0-F8D3FA22FEEE@jkemp.net> <90C41DD21FB7C64BB94121FBBC2E723438E5C7FD26@P3PW5EX1MB01.EX1.SECURESERVER.NET> <h2ldaf5b9571004221235tb844eb6ah623955979526c1b6@mail.gmail.com> <90C41DD21FB7C64BB94121FBBC2E723438E5C7FD4A@P3PW5EX1MB01.EX1.SECURESERVER.NET> <l2idaf5b9571004221350oa0dbeb11ndeb4cb9147407ba9@mail.gmail.com> <255B9BB34FB7D647A506DC292726F6E1125793664B@WSMSG3153V.srv.dir.telstra.com>
In-Reply-To: <255B9BB34FB7D647A506DC292726F6E1125793664B@WSMSG3153V.srv.dir.telstra.com>
Content-Type: text/plain; charset="UTF-8"; format="flowed"
Content-Transfer-Encoding: 8bit
X-Df-Sender: 141509
Cc: OAuth WG <oauth@ietf.org>
Subject: Re: [OAUTH-WG] 'Scope' parameter proposal
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/oauth>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 23 Apr 2010 22:31:33 -0000

> 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.