This is a joint proposal from David Recordon and me:

** Background:
 
The latest draft (-08) unified the  web-server and user-agent client types into 
a single authorization request format. This was done because once we added an 
optional authorization code to the user-agent response, it became almost 
identical to the web-server call. The two remaining differences:
 
- The web-server response must not return an access token, only an 
authorization code.
- The web-server response uses the URI query while the user-agent response uses 
the URI fragment.
 
The way in which the client indicates which response is requests is by using 
the 'type' parameter with either 'web_server' or 'user-agent'. This is all 
documented in:
 
http://tools.ietf.org/html/draft-ietf-oauth-v2-08#section-3
 
Many (if not most) services are likely to implement both the user-agent and 
web-server types (based on existing deployment and the requirements expressed 
by many of the participants).

The web-server flow requires client authentication (client secret) in order to 
obtain an access token. It also enables the registration of a redirection URI.

When using the user-agent flow, the client does not authenticate with the 
authorization server (at all) to obtain an access token. However, it does need 
to authenticate if it wants to exchange the optional authorization code for 
(another) access token.
 
The authorization server has a few options when managing the security and trust 
implications of each request type:
 
- Require that the client provide its type when registering with the service - 
if the authorization server knows the client type, it can limit that client to 
only make requests suitable for that client type, as well as only issue a 
client secret when the client is not a user-agent.
 
- Issue different access tokens based on the security context in which they are 
obtained - access tokens issued using the direct user-agent request will 
provide less access (shorter duration, read only, etc.) than an access token 
obtained using the web-server request type.
 
The first approach is problematic for complex clients requesting both an access 
token and authorization code using the user-agent request type. In this case, 
the authorization server is issuing two access tokens, each using a different 
level of security. It is means that one developer will need to obtain a 
different client identifier for the same application across different platforms.
 
The current separation between the two request types (user-agent and 
web-server) seems artificial. This is especially true when considering the use 
cases for native applications and the applicability of both options. At the 
end, the client type doesn't matter. What matters is whether the access token 
is issued with or without client authentication (and whether that 
authentication can be trusted, which goes beyond what the protocol can provide).
 
** Proposal:
 
Replace the 'type' parameter with a new parameter called 'request' (working 
title) which can take one of three values: 'token', 'code', or 
'token_and_code'. This will allow the client (regardless of its type) to 
explicitly say what it wants.

The response is sent as follows:

- If the client requests an access token, all the response parameters 
(including errors) are included in the fragment (same as the user-agent flow 
today).
- If the client requests an authorization code, all the parameters are included 
in the query (same as the web server flow today).
- If the client requests both, the 'code', 'status', and 'error' are included 
in the query while everything else is included in the fragment (explained in 
the example below).

The authorization server issues the appropriate user warnings and access token 
based on the authentication level obtained. For example, when issuing an access 
token the server has to consider:
 
- Was the client authenticated using a secret or other means?
- Was the redirection URI registered?
- Is this a known client (white list) from a trusted third party (they are 
known not to leak their secrets)?
 
 The advantage of this approach is that it more clearly frames the security 
context of issuing tokens. It puts native applications at the same level as the 
web-server and user-agent clients (no one gets a special parameter value).

** Examples:

To help show the similarities, here are three example requests and responses:

- Token only (aka user-agent):

  https://server.example.com/oauth/authorize?
    client_id=...&
    redirect_uri=http://client.example.com/callback&;
    request=token&
    state=foo

  http://client.example.com/callback#access_token=...&expires_in=...&state=foo

In this case all of the parameters are in relation to the token and thus 
consumed directly by the JavaScript, desktop app, etc.

- Code only (aka web-server):

  https://server.example.com/oauth/authorize?
    client_id=...&
    redirect_uri=http://client.example.com/callback&;
    request=code&
    state=foo

  http://client.example.com/callback.php?code=...&state=foo

In this case there isn't an access token and all of the parameters are consumed 
by the client's server to be traded for an access token via a HTTPS request to 
the AS.

- Token and code:

https://server.example.com/oauth/authorize?
  client_id=...&
  redirect_uri=http://client.example.com/callback&;
  request=token_and_code&
  state=foo

http://client.example.com/callback.php?code=...&state=foo#access_token=...&expires_in=...

In this case the parameters are consumer both by the JavaScript and the 
client's server. The parameters about the access token are in the fragment. The 
code is a query parameter so that the server can access it. state and error are 
useful to both and thus are query parameters which can be accessed by the 
JavaScript and the server.
 

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

Reply via email to