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