Proposed OAuth WRAP Client Only Profile

37 views
Skip to first unread message

Luke Shepard

unread,
Dec 17, 2009, 1:22:06 PM12/17/09
to oauth-...@googlegroups.com
Last Tuesday, we had an OAuth WRAP community meeting at Facebook. The main purpose of the discussion was to answer the question of how applications written primarily in JavaScript would interact with OAuth WRAP – specifically, we’d like to figure out how to make products like Facebook Connect work without requiring server code.

The outcome of the meeting was that we would create a new profile that doesn’t require the Client Secret in order to make calls. We’ve focused mostly on applications written entirely in Javascript, but it should also extend to other client-only apps such as desktop and mobile. The proposed addition to the spec is attached. It’s the same as the Web App profile with the main difference that the Access Token is returned directly on the callback URL without requiring an extra round trip.

Examples

Thanks to Bret Taylor and the Friendfeed team for providing a great playground to illustrate the profiles with working code.

- FriendFeed has an OAuth WRAP provider prototype, with the following endpoints:
Authorize URL: https://friendfeed.com/account/wrap/authorize
Access Token URL: https://friendfeed.com/account/wrap/access_token
(no Refresh Token URL yet)

- Web App profile demo:
http://friendfeed-wrap.appspot.com/
(source: http://github.com/finiteloop/friendfeed-wrap-example )

- Client Only (Javascript) profile demo:
http://open.lukeshepard.com/oauth-wrap/console/
(source: http://github.com/lshepard/oauth-wrap-demo )

Both of these examples do the same thing – get an access token and then fetch and render your Friendfeed news feed. The first does it on the server, the second entirely in JavaScript.

Discussion

In contrast to the Web Gadget Profile proposed earlier ( http://groups.google.com/group/oauth-wrap-wg/browse_thread/thread/cfafaa4acb5cf1e1?hl=en ) , this profile leaves all JavaScript specifics out of the spec. Sure, we need to use things like postMessage and whatever, but those can be handled in libraries and reference implementations.

I also chose not to add a “wrap_profile” parameter. I’m a little worried that if we start identifying a bag of behavior by “wrap_profile” then the spec will be less able to handle new profiles in the future, since each server will have to know about each profile name. I’d love to hear ideas on how we can customize behavior between profiles while supporting future extensibility.

Looking forward to all your feedback!

- Luke
OAuth WRAP Client Only Profile (draft 2009-12-16).pdf
OAuth WRAP Client Only Profile (draft 2009-12-16).docx

Evan Gilbert

unread,
Dec 18, 2009, 3:22:08 AM12/18/09
to oauth-...@googlegroups.com
This proposal looks great.

I like that we're calling it a Client App Profile (and combining with Rich App instead of having a different profile).

A few suggestions:

5.5.1 Provisioning

Registration and obtaining a client identifier should still be a MAY.  Unregistered clients can use the domain of the callback as an identifier for who is requesting the data. This also means that wrap_client_id can be a MAY when sent to the authentication server.

5.5.2 Client Directs User to the Authentication Server
Should support an OPTIONAL wrap_username. This is useful on computers used by multiple people - the client can request to get an auth token matching their logged in user.

Recommendation should be to always use the hash. Just https:// has the problem of leaking token in referrers (I think).

5.5.3 Authorization Server Confirms Delegation Request with User
The user prompt should be a MAY. If the user has already granted consent for the app to access data, the authorization server may redirect back with a token without user interaction.

Evan


--

You received this message because you are subscribed to the Google Groups "OAuth WRAP WG" group.
To post to this group, send email to oauth-...@googlegroups.com.
To unsubscribe from this group, send email to oauth-wrap-w...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/oauth-wrap-wg?hl=en.

Dick Hardt

unread,
Dec 18, 2009, 5:08:20 PM12/18/09
to oauth-...@googlegroups.com

Hi Luke

 

Thanks so much for writing this up, and thanks Bret et al for putting up some working code!

 

It looks like you are proposing that ALL rich clients have to have a call back URL to get their Access Token. Would you elaborate on this requirement?

 

I agree that including JS in a spec is problematic. I do think that the spec needs to describe how the Client gets the Access Token. I found myself wondering how the Access Token magicly gets from the server where the callback URL is to the client.

 

I’m confused why 5.5.5 is there. Would you elaborate on what is going on here? I don’t follow it given the discussion we had.

 

I’ll comment on a separate thread about the use of wrap_profile.

 

-Dick

--

Luke Shepard

unread,
Dec 19, 2009, 3:09:52 AM12/19/09
to oauth-...@googlegroups.com
Thanks Dick and Evan for the feedback. Responses:

[dick]

> It looks like you are proposing that ALL rich clients have to have a call back URL to get their Access Token. Would you elaborate on this requirement?

I’m sorry for the confusion; I didn’t mean to mix this in with the Rich App Profile. I originally began by copying the Web App profile (5.4), but I suppose in retrospect it’s probably better to mix with Rich App.

Frankly, I’d like to separate out desktop apps with access to a browser from desktop apps without; make the callback url required in this profile, and put the weird user-entered token into its own profile. I think that will be pretty rare relative to the other profile usage.

[dick]

>  I do think that the spec needs to describe how the Client gets the Access Token. I found myself wondering how the Access Token
> magically gets from the server where the callback URL is to the client.

I added a section 5.5.2.1, “Choosing a callback URL”:

Pure Client Apps may live entirely in JavaScript, on the desktop, or in other client-only environments without easy access to a dynamic server. In this case, the Callback URL MAY be any device-specific URL. It is possible in many cases for Client-only apps to still read parameters from a web page (for example, if a desktop application controls a Webview, or a JavaScript application reads the window.location property).

Because the raw Access _Token will be passed back on this Callback URL, it is strongly RECOMMENDED that the Callback URL be HTTPS, or that it include a hash (“#”) in the URL to prevent the Access Token from being transmitted over an insecure line.

[dick]
> I’m confused by 5.5.5 is there (the section on refresh tokens)

This was an outgrowth of some discussion at the tail end of last week’s meeting; namely, apps that exist primarily as client only may nonetheless want the ability to, at some point, refresh their short-lived access token. There are many examples of this: for instance, Facebook Connect apps may want to just use the Javascript authentication, but then use a session key for offline data access. Or, you could imagine an iPhone app that operates exclusively on the client for authentication, but then sends feed stories on behalf of the user offline.

The use cases here should certainly be flushed out a bit more; I think Brian mentioned some similar cases on his side. Also, the term “Refresh” token isn’t really appropriate because you’re not necessarily refreshing a short-lived token; you may exchange it for a longer-lived one, or something.

[evan]

> Registration and obtaining a client identifier should still be a MAY.

I copied the provisioning section from 5.4.1, the Web App profile:

>>
Prior to initiating this protocol profile, the Client MUST have obtained a Client Identifier
>> and Client Secret from the Authorization Server. The Authorization Server MAY have
>> also required the Client to pre-register their Callback URL.

I’m not sure of why that is different from 5.5.1, or which one is most appropriate here. Facebook would still require a client ID regardless.

[evan]
>
Should support an OPTIONAL wrap_username.

I understand the desire for this, but in the interest of keeping it simple, is it really necessary as a core part of the spec? What are some examples of real-world use cases for this?

[evan]

> Recommendation should be to always use the hash. Just https:// has the problem of leaking token in referrers (I think).

If the callback url doesn’t have any included iframes or images, then there is no risk of leaking referers, but I take your point. Since this is just a recommendation, we should think about how complex we want to make it, and perhaps we should just say “use the hash” unless there’s a situation where that doesn’t work.

[evan]
> The user prompt should be a MAY. If the user has already granted consent for the app to access data, the authorization server may redirect back with a token without user interaction.

Good point. My initial inclination is to agree with you, as that is the behavior Facebook takes today.

However: in OpenID we have two modes, checkid_setup and checkid_immediate, and many providers implement checkid_setup to always show an auth dialog – even if the user has already authed. Without a clear MUST, the behavior becomes inconsistent as some providers choose to show the dialog and some don’t; I’m just curious if people have strong feelings one way or another about this.

Now that I see the other thread, I agree with the addition of a “mode” parameter to distinguish behavior like this.

Evan Gilbert

unread,
Dec 22, 2009, 1:01:46 AM12/22/09
to oauth-...@googlegroups.com
Responses inline...

On Sat, Dec 19, 2009 at 12:09 AM, Luke Shepard <lshe...@facebook.com> wrote:
Thanks Dick and Evan for the feedback. Responses:
[evan]

> Registration and obtaining a client identifier should still be a MAY.

I copied the provisioning section from 5.4.1, the Web App profile:

>>
Prior to initiating this protocol profile, the Client MUST have obtained a Client Identifier
>> and Client Secret from the Authorization Server. The Authorization Server MAY have
>> also required the Client to pre-register their Callback URL.

I’m not sure of why that is different from 5.5.1, or which one is most appropriate here. Facebook would still require a client ID regardless.

The Web App profile doesn't work without a client_id and client_secret, as these are needed to get an access token (see 5.4.5 "Client Requests Access Token").

The client only profile doesn't need a secret (only for the refresh case). 

For the client ID, you can use the domain of the callback URL if they haven't registered. Google supports a similar flow today with unregistered AuthSub (click on one of the Login links on http://code.google.com/apis/contacts/docs/1.0/developers_guide_js.html for an example).

Unregistered  is less safe and more appropriate for development mode / low volume apps. It's also useful for sample pages, etc.
 

[evan]
>
Should support an OPTIONAL wrap_username.

I understand the desire for this, but in the interest of keeping it simple, is it really necessary as a core part of the spec? What are some examples of real-world use cases for this?

This is needed to choose the right account when two people are using the same computer (or a user has multiple accounts). 

For example, my wife is logged into Facebook on our shared computer. I then use the same computer, log into nytimes.com, and click the "Share on Facebook" button. We need a way for nytimes.com to link to the right account on Facebook. 

The specific use case where this is needed:
- The client has their own login system, and
- The AS supports redirecting with an access token without prompting the user


[evan]

> Recommendation should be to always use the hash. Just https:// has the problem of leaking token in referrers (I think).

If the callback url doesn’t have any included iframes or images, then there is no risk of leaking referers, but I take your point. Since this is just a recommendation, we should think about how complex we want to make it, and perhaps we should just say “use the hash” unless there’s a situation where that doesn’t work.

Sounds good.

(FYI - token would also leak on outbound links)
 

[evan]
> The user prompt should be a MAY. If the user has already granted consent for the app to access data, the authorization server may redirect back with a token without user interaction.

Good point. My initial inclination is to agree with you, as that is the behavior Facebook takes today.

However: in OpenID we have two modes, checkid_setup and checkid_immediate, and many providers implement checkid_setup to always show an auth dialog – even if the user has already authed. Without a clear MUST, the behavior becomes inconsistent as some providers choose to show the dialog and some don’t; I’m just curious if people have strong feelings one way or another about this.

Now that I see the other thread, I agree with the addition of a “mode” parameter to distinguish behavior like this.

--

Alan Karp

unread,
Dec 27, 2009, 11:31:20 PM12/27/09
to oauth-...@googlegroups.com
I like the demo.  I know you want to keep it simple, but you've missed a good educational opportunity.  The authorize page says that allowing access will let you access my profile and all of my feeds and post on my behalf.  The WRAP token should be able to specify specific rights being granted.  To show that you could change the two bullets to check boxes.  The ability to grant a subset of the user's rights goes a long way to better supporting the Principle of Least Privilege, which is one of the things I like about WRAP.

--------------
Alan Karp (a lurker)


--

Dick Hardt

unread,
Dec 31, 2009, 2:58:01 PM12/31/09
to <oauth-wrap-wg@googlegroups.com>
On 2009-12-19, at 12:09 AM, Luke Shepard wrote:

Thanks Dick and Evan for the feedback. Responses:

[dick]
> It looks like you are proposing that ALL rich clients have to have a call back URL to get their Access Token. Would you elaborate on this requirement?

I’m sorry for the confusion; I didn’t mean to mix this in with the Rich App Profile. I originally began by copying the Web App profile (5.4), but I suppose in retrospect it’s probably better to mix with Rich App.

Frankly, I’d like to separate out desktop apps with access to a browser from desktop apps without; make the callback url required in this profile, and put the weird user-entered token into its own profile. I think that will be pretty rare relative to the other profile usage.

What is rare depends on your perspective!

I'd prefer to have a new profile that focusses on the RIA use cases that are missing. I'm unsure why you want to mix it up with an existing profile

One of the issues with OAuth 1.0A was that everything was in one profile. There are significantly different security and implementation considerations depending on the Client.



[dick]
>  I do think that the spec needs to describe how the Client gets the Access Token. I found myself wondering how the Access Token
> magically gets from the server where the callback URL is to the client.

I added a section 5.5.2.1, “Choosing a callback URL”:

Pure Client Apps may live entirely in JavaScript, on the desktop, or in other client-only environments without easy access to a dynamic server. In this case, the Callback URL MAY be any device-specific URL. It is possible in many cases for Client-only apps to still read parameters from a web page (for example, if a desktop application controls a Webview, or a JavaScript application reads the window.location property).

Because the raw Access _Token will be passed back on this Callback URL, it is strongly RECOMMENDED that the Callback URL be HTTPS, or that it include a hash (“#”) in the URL to prevent the Access Token from being transmitted over an insecure line.

I still wonder how the Access Token magicly gets to the Client. For JS clients, I thought the Callback URL was a service that would be able to pass the Access Token back to the Client.



[dick]
> I’m confused by 5.5.5 is there (the section on refresh tokens)

This was an outgrowth of some discussion at the tail end of last week’s meeting; namely, apps that exist primarily as client only may nonetheless want the ability to, at some point, refresh their short-lived access token. There are many examples of this: for instance, Facebook Connect apps may want to just use the Javascript authentication, but then use a session key for offline data access. Or, you could imagine an iPhone app that operates exclusively on the client for authentication, but then sends feed stories on behalf of the user offline.

The use cases here should certainly be flushed out a bit more; I think Brian mentioned some similar cases on his side. Also, the term “Refresh” token isn’t really appropriate because you’re not necessarily refreshing a short-lived token; you may exchange it for a longer-lived one, or something.

While the developer might want to reuse the token, the user and the AS gave permission to a RIA. I think we need to be careful about mixing contexts.

-- Dick

Reply all
Reply to author
Forward
0 new messages