[OAUTH-WG] user-agent flow needs a rewrite
Brian Eaton <beaton@google.com> Sun, 11 July 2010 03:55 UTC
Return-Path: <beaton@google.com>
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 077813A68D9 for <oauth@core3.amsl.com>; Sat, 10 Jul 2010 20:55:05 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -100.47
X-Spam-Level:
X-Spam-Status: No, score=-100.47 tagged_above=-999 required=5 tests=[AWL=-1.507, BAYES_40=-0.185, FM_FORGED_GMAIL=0.622, J_CHICKENPOX_42=0.6, USER_IN_WHITELIST=-100]
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 V6TmNaMtr3uq for <oauth@core3.amsl.com>; Sat, 10 Jul 2010 20:55:03 -0700 (PDT)
Received: from smtp-out.google.com (smtp-out.google.com [74.125.121.35]) by core3.amsl.com (Postfix) with ESMTP id 65EEF3A6827 for <oauth@ietf.org>; Sat, 10 Jul 2010 20:55:03 -0700 (PDT)
Received: from hpaq5.eem.corp.google.com (hpaq5.eem.corp.google.com [172.25.149.5]) by smtp-out.google.com with ESMTP id o6B3t9D5012247 for <oauth@ietf.org>; Sat, 10 Jul 2010 20:55:09 -0700
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1278820509; bh=x3nYA29hboWLmHq5VD7ilvgNRD8=; h=MIME-Version:Date:Message-ID:Subject:From:To:Content-Type; b=QhGZnTt6BjlaIJPd9nKIuccUDazzMPv+qVKrbI0g4wHi5qpao+16JKgnZY21XWh1h /Qi0yfFEKPi6GlNRg/1zw==
DomainKey-Signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=mime-version:date:message-id:subject:from:to:content-type:x-system-of-record; b=Iy5TlFZznGwUUTig/tlvXDcIOSRoboKmNeHiUTbQjuw3QnEtG7k6KEDYASRMcKOgw 8ckUoXmMcIeVcKAGXvwgQ==
Received: from pvc7 (pvc7.prod.google.com [10.241.209.135]) by hpaq5.eem.corp.google.com with ESMTP id o6B3t7CM006496 for <oauth@ietf.org>; Sat, 10 Jul 2010 20:55:08 -0700
Received: by pvc7 with SMTP id 7so1313087pvc.5 for <oauth@ietf.org>; Sat, 10 Jul 2010 20:55:07 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.142.133.12 with SMTP id g12mr2837488wfd.118.1278820506843; Sat, 10 Jul 2010 20:55:06 -0700 (PDT)
Received: by 10.142.193.19 with HTTP; Sat, 10 Jul 2010 20:55:06 -0700 (PDT)
Date: Sat, 10 Jul 2010 20:55:06 -0700
Message-ID: <AANLkTimYZg_PrDn9JvjHwuVHOwZuGIPZk6affFCTPQor@mail.gmail.com>
From: Brian Eaton <beaton@google.com>
To: oauth@ietf.org
Content-Type: text/plain; charset="ISO-8859-1"
X-System-Of-Record: true
Subject: [OAUTH-WG] user-agent flow needs a rewrite
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: Sun, 11 Jul 2010 03:55:05 -0000
The draft 9 spec has no efficient way for a javascript client to request a verification code. The spec creates extra client-to-server round trips. There is also some inaccurate description of the properties of the profile. The problems are located in section 1.4.2: http://tools.ietf.org/html/draft-ietf-oauth-v2-09#page-11. The spec requires that the verification code is always returned on the query string. This ends up busting the browser cache and creating an extra client-to-server round trip. It basically defeats the purpose of the user-agent profile entirely. (If you could afford an extra client-to-server round trip, you would just use the web server flow.) To clarify, here's how the flow works in practice: client web site loads relay page is loaded from the client web site. This page is typically heavily cached. It is almost always loaded from browser cache; it is very rarely actually fetched from the server, for performance reasons. client web site redirects browser to authorization server authorization server redirects back to relay page, with new data on the fragment there is no client-to-server round trip*. the client javascript is loaded from cache, and parses the fragment data if necessary, the client javascript uses XMLHttpRequest (XHR) to pass data up to the web server. This typically happens in the background, however, while the user is otherwise interacting with the web application. Here's what would happen if someone implemented the spec as written, though: client web site loads relay page is loaded from the client web site. This page is typically heavily cached. It is almost always loaded from browser cache; it is very rarely actually fetched from the server, for performance reasons. client web site redirects browser to authorization server authorization server redirects back to relay page, with new data on the fragment, *plus a verification code on the query string* *browser fetches new copy of relay page from web server* *user sits and waits* *kittens die when users have to wait* There are also several problems with the description of the flow. Most of the description seems to be left over from the time when the flow was spec'ed to only return an access token. Now that it can return a verification code, sentences like "does not utilize the client secret" are no longer true. The phrase "because the access token is encoded into the redirection URI, it may be exposed to the end-user and other applications residing on the computer" is just silly. That's equally true of the web server flow. So basically I think section 1.4.2 needs a rewrite, starting with the entire justification of the flow. Here's a brief description of how the flow should work: client web site loads client redirects to authorization server with: type="user_agent" client_id=client identifier redirect_uri=absolute URL on client web site response_type="code-and-token" or "token" (The client chooses the response type based on whether they want long-lived access or short-lived access to the user's data. Short-lived: just use "token".) authorization server confirms user consent (which might or might not require user interaction...) authorization server confirms redirect_uri is associated with the client_id. authorization server redirects to redirect_uri, with all of the return parameters on the URL fragment. Here's my proposed text for section 1.4.2. The user-agent profile is suitable for client applications residing in a user-agent, typically implemented in a browser using a scripting language such as JavaScript. These clients typically have strict latency requirements, and must be implemented using a minimum number of client-to-server calls. The client may have supporting code running on a web server. Authentication of the client-side components is based on the redirect URI and the user-agent's same-origin policy. Authentication of the server-side components is based on the client secret. Unlike other profiles, the user-agent profile returns data on the client on the URI fragment. In addition, the user-agent profile returns an access token directly on the redirect URI, to reduce the number of round trips required before the client can use the token. The client is able to immediately use the token to communicate to resource servers, using client-side cross-domain communication techniques such as window.postMessage, jsonp, and iframes. [Maybe just mention iframes here, better not to clutter the spec with references to all of the ways around same-origin...) Figure 5: this probably needs to change so that it looks more like Figure 4. Changes from Figure 4 would be: Step (C) returns access token and optional verification code New step (D): client using the access token directly with a resource server. Old step D becomes step E, but otherwise looks the same. Except it is optional. Step E: if this step occurs, refresh token is no longer optional More normative language (largely based on merging the user-agent language with the web-server language.) The user-agent flow illustrated in Figure 5 includes the following steps: (A) [no change] The clients sends the user-agent to the end-user authorization endpoint as described in section 3. The client includes its client identifier, requested scope, local state, and a redirect URI to which the authorization server will send the end-user back once authorization is granted. (B) [no change] (C) If the end-user granted access, the authorization server redirects the user-agent to the redirection URI provided earlier. The redirection URI includes the access token, and optional verification code, in the URI fragment. (D) The user-agent follows the redirection instructions by loading the redirection URI. The redirection URI is typically a heavily cached web page, so this is unlikely to result in an additional client to server round trip. (E) The client code parses the URL fragment to retrieve the access token and optional authorization code. (F) The client uses the access token to contact resource servers. (G) In parallel, the client passes the authorization code to the client's server side components. (H) The client's server-side components request an access token and refresh token from the authorization server by authenticating and including the authorization code received in the previous step. (I) The authorization server validates the client credentials and the authorization code and responds back with the refresh token and access token. Rest of the spec doesn't look like it needs to change much. Section 4.1.1. "Authorization Code" needs some modifications to make it clear that the redirect_uri sent to the authorization server MUST include any fragment included on the original authorization request. redirect_uri REQUIRED. The redirection URI used in the initial request. If the client included a URI fragment on the redirect_uri sent to the authorization server on the authorization request, the client MUST include the same URI fragment here. Cheers, Brian
- [OAUTH-WG] user-agent flow needs a rewrite Brian Eaton
- Re: [OAUTH-WG] user-agent flow needs a rewrite Eran Hammer-Lahav
- Re: [OAUTH-WG] user-agent flow needs a rewrite Brian Eaton
- Re: [OAUTH-WG] user-agent flow needs a rewrite Eran Hammer-Lahav
- Re: [OAUTH-WG] user-agent flow needs a rewrite Luke Shepard
- Re: [OAUTH-WG] user-agent flow needs a rewrite Eran Hammer-Lahav
- Re: [OAUTH-WG] user-agent flow needs a rewrite David Recordon
- Re: [OAUTH-WG] user-agent flow needs a rewrite Brian Eaton
- Re: [OAUTH-WG] user-agent flow needs a rewrite Eran Hammer-Lahav
- Re: [OAUTH-WG] user-agent flow needs a rewrite Blaine Cook
- Re: [OAUTH-WG] user-agent flow needs a rewrite Brian Eaton
- Re: [OAUTH-WG] user-agent flow needs a rewrite Naitik Shah
- Re: [OAUTH-WG] user-agent flow needs a rewrite Eran Hammer-Lahav
- Re: [OAUTH-WG] user-agent flow needs a rewrite Naitik Shah
- Re: [OAUTH-WG] user-agent flow needs a rewrite Eran Hammer-Lahav
- Re: [OAUTH-WG] user-agent flow needs a rewrite Brian Eaton
- Re: [OAUTH-WG] user-agent flow needs a rewrite Naitik Shah
- Re: [OAUTH-WG] user-agent flow needs a rewrite Bouiaw