oauth related container features

6 views
Skip to first unread message

Martin

unread,
Feb 15, 2008, 12:24:12 PM2/15/08
to OpenSocial and Gadgets Specification Discussion
Hi,

I would like to see two oauth related container features:

1. an extension to support the generation of consumer-key and consumer-
secret via the container

See Brian Eaton's document at http://groups.google.com/group/oauth-extensions/t/bdd87bc7de25867c

2. to support the request-token and access-token exchanges via the
container, along with a trigger of the authorise step - to supplement
the patch included in https://issues.apache.org/jira/browse/SHINDIG-35

See the post and replies to:
http://mail-archives.apache.org/mod_mbox/incubator-shindig-dev/200802.mbox/%3c94b82bfd0802120335x3d...@mail.gmail.com%3e

Can I start the ball rolling and propose an enhancement to the Google
Gadget spec to support the following concept:

<ModulePrefs title="A gadget that depends on oauth">
<Require feature="oauth" />

<!--
as this gadget accesses a resource over HTTP (and not
HTTPS) then the required and optional request parameters
also need to be signed (according to the oauth spec), so
these need to be detailed in comma delimited lists

Taking as an example:
http://oauth.net/core/1.0/#anchor26
-->

<Resource
url="http://photos.example.net/photo"
required="file"
optional="size">

<!--
the following are the service provider's oauth
endpoints

the container (at the very least) will need to manage
a consumer-key and consumer-secret for this
oauth-provider / service provider

the container may not need to manage keys/secrets on a
per resource url for the same oauth-provider endpoints

the container will need to manage either keys/secrets
on:
* a per gadget xml url basis, or

* a per gadget xml url per service provider basis
this allows a gadget scoped access token to be used
across all urls published by service provider.

the management of the keys/secrets is not considered at
this stage
-->

<ResourcePref
name="request_token"
url="https://photos.example.net/request_token"
type="POST"
signaturemethod="PLAINTEXT" />

<ResourcePref
name="authorize"
url="http://photos.example.net/authorize"
type="GET" />

<ResourcePref
name="access_token"
url="https://photos.example.net/access_token"
type="POST"
signaturemethod="PLAINTEXT" />

<!--
the following defines how the container/gadget
framework should persist the access-token
-->

<ResourcePref name="persistence" value="cookie" />

<-- with values for:
container - (optional) container manages access-token
on behalf of the end-user this could (down to the
container implementation) be held against the session
(anonymous users), or against the user's profile
(however, we might need to worry about "remember
me" scenarios)

cookie - held as a client-side cookie on the end
user's browser

DOM - held in the gadget's DOM - lost when the page
reloads
-->

<ResourcePref name="duration" value="86400" />

<!--
seconds - 86400 secs = 1 day

session - dictates either a session cookie, or
(optional) if persistence=container then a logged
in session. If persistence=dom then the duration
has no impact

profile - (optional) if persistence=container and if
the user is logged into the container then
persisted against the user's profile
-->

<!--
the use of persistence and duration gives the gadget
developer complete control over the length of time
the access-token is held

it will still be down to the service endpoint / oauth
provider to control the expiry of access-tokens

the use of persistence="container" allows the
access-token to be portable across browsers - when
used the access-token must not be send down to the
browser
-->

<!--
if a container doesn't support the optional
persistence=container, then the container must degrade
gracefully to persist against a cookie

if a container doesn't support the optional
duration=profile, then the container must degrade
gracefully to hold for the duration of the session
(however - typically sessions timeout after 20
minutes inactivity, so is here any point in using the
server's session?)

is it too complex?
-->

</Resource>

<!--
a gadget might want to access other resources protected
by different oauth service providers

this gadget then might want to access a more secure
service that requires HTTPS for the service, and uses a
wildcard rather than needing to specify all the
individual service endpoints
-->

<Resource url="http://secure.example.net/services/*">

<!--
the following oauth-provider will need the container to
manage a separate consumer-key and consumer-secret than
used in the previous oauth-provider
-->

<ResourcePref
name="request_token"
url="https://secure.example.net/request_token"
type="POST"
signaturemethod="PLAINTEXT" />

<ResourcePref
name="authorize"
url="https://secure.example.net/authorize"
type="GET" />

<ResourcePref
name="access_token"
url="https://secure.example.net/access_token"
type="POST"
signaturemethod="PLAINTEXT" />

<ResourcePref name="persistence" value="DOM" />
<!--
as soon as the gadget unloads the access-token is lost
-->

</Resource>

</ModulePrefs>

I'm not too concerned about the XML structure, the use of tags versus
attributes etc, etc. I would just like to see the oauth provider and
server endpoint data defined within the gadget spec so that the gadget
container can parse it and then use it whenever it recevies anHTTP 401
Unauthorized from a service endpoint along with the header:

WWW-Authenticate: OAuth realm="http://photos.example.net/"

Regards
Martin

John Panzer

unread,
Feb 15, 2008, 12:40:38 PM2/15/08
to opensocial-an...@googlegroups.com
Sounds good, but...


...you don't want to have to hard-code the protected resource URL in the gadget spec; the URL often will vary, especially for RESTful services.

Since you want to react to a 401 response automatically, it's slightly difficult.  Perhaps using the realm parameter to match things up would work (the resource above would return a realm on a 401 that should be the same realm as /photo?id=3434343 and /photo?id=9938383).

 

I'd hope a lot of this could be auto-discovered via OAuth extensions (so maybe we should define the ones we need, suggest them as standards, and then start using them ourselves regardless...)
 

Brian Eaton

unread,
Feb 15, 2008, 5:03:47 PM2/15/08
to opensocial-an...@googlegroups.com
On Fri, Feb 15, 2008 at 9:40 AM, John Panzer <jpa...@google.com> wrote:
> ...you don't want to have to hard-code the protected resource URL in the
> gadget spec; the URL often will vary, especially for RESTful services.

Yeah, I agree.

> Since you want to react to a 401 response automatically, it's slightly
> difficult. Perhaps using the realm parameter to match things up would work
> (the resource above would return a realm on a 401 that should be the same
> realm as /photo?id=3434343 and /photo?id=9938383).

I don't think we can do this without making lots of assumptions about
DNS domains and realms being more or less equivalent. I'd rather see
the gadget author tell us which OAuth service provider they're talking
to.

In the patch I sent to shindig-dev this was done with a
'providerNickname' parameter to gadgets.io.makeRequest. The idea is
that the gadget spec maps nicknames to OAuth URLs for each provider,
and then the gadget calls makeRequest() to specify which providers go
with which resources.

Cheers,
Brian

Martin Webb

unread,
Feb 18, 2008, 4:50:35 AM2/18/08
to opensocial-an...@googlegroups.com
On Feb 15, 2008 10:03 PM, Brian Eaton <bea...@google.com> wrote:

On Fri, Feb 15, 2008 at 9:40 AM, John Panzer <jpa...@google.com> wrote:
> ...you don't want to have to hard-code the protected resource URL in the
> gadget spec; the URL often will vary, especially for RESTful services.

Yeah, I agree.

Can we mine the requests as they come through the container to extract the query parameters for the service provider and use them when signing?  If so then the gadget does not need to specify the required/optional request parameters.

In the patch I sent to shindig-dev this was done with a
'providerNickname' parameter to gadgets.io.makeRequest.  The idea is
that the gadget spec maps nicknames to OAuth URLs for each provider,
and then the gadget calls makeRequest() to specify which providers go
with which resources.

We do not want the OAuth URLs to be predefined.  We want the gadget spec to specify the OAuth URLs and for the container to cache them along with the gadget XML.  Taking the use of the providerNickname to the proposal I made earlier, then how about:


<ModulePrefs title="A gadget that depends on oauth">
   <Require feature="oauth" />

   <OauthProvider
     providerNickname="simpleUseCase">

     <OauthPref

       name="request_token"
       url="https://photos.example.net/request_token"
       type="POST"
       signaturemethod="PLAINTEXT" />

     <OauthPref

       name="authorize"
       url="http://photos.example.net/authorize"
       type="GET" />

     <OauthPref

       name="access_token"
       url="https://photos.example.net/access_token"
       type="POST"
       signaturemethod="PLAINTEXT" />

     <OauthPref name="persistence" value="cookie" />

     <OauthPref name="duration" value="86400" />

   </OauthProvider>

   <OauthProvider
     providerNickname="otherUserCase">

     <OauthPref

       name="request_token"
       url="https://secure.example.net/request_token"
       type="POST"
       signaturemethod="PLAINTEXT" />

     <OauthPref

       name="authorize"
       url="https://secure.example.net/authorize"
       type="GET" />

     <OauthPref

       name="access_token"
       url="https://secure.example.net/access_token"
       type="POST"
       signaturemethod="PLAINTEXT" />

     <OauthPref name="persistence" value="DOM" />

   </OauthProvider>

 </ModulePrefs>


Which could be used as per:

gadgets.io.makeRequest(
  'http://photos.example.net/photo?file=123456789',
  callbackFunction1,
  { 'AUTHORIZATION': 'AUTHENTICATED', 'PROVIDERNICK': 'simpleUseCase'}
);

and:

gadgets.io.makeRequest(
  'http://secure.example.net/services/something.do',
  callbackFunction1,
  { 'AUTHORIZATION': 'AUTHENTICATED', 'PROVIDERNICK': 'otherUserCase'}
);

Regards
Martin

--
Internet Related Technologies - http://www.irt.org

Brian Eaton

unread,
Feb 19, 2008, 12:39:21 PM2/19/08
to opensocial-an...@googlegroups.com
On Feb 18, 2008 1:50 AM, Martin Webb <martin...@gmail.com> wrote:
> Can we mine the requests as they come through the container to extract the
> query parameters for the service provider and use them when signing? If so
> then the gadget does not need to specify the required/optional request
> parameters.

This sounds like the way to go. We are already in the business of
parsing query parameters for signed fetch, doing it for OAuth seems
reasonable.

> We do not want the OAuth URLs to be predefined. We want the gadget spec to
> specify the OAuth URLs and for the container to cache them along with the
> gadget XML. Taking the use of the providerNickname to the proposal I made
> earlier, then how about:

<snip proposal for OAuthProvider and OAuthPref elements.>

This looks good to me. I'll let others comment on the exact XML syntax to use.

I'm not sure I see why the gadget XML should specify the mechanism to
use for persisting the OAuth tokens. That seems like it should be up
to the container to implement. (And I hope containers don't send
those tokens in the browser.)

Do you have any thoughts on whether the OAuth token used for these
kinds of requests should be the owner or the viewer token? Should we
restrict OAuth access to cases where owner and viewer are the same?
Do we need some kind of scheme to let the gadget spec make that
decision?

Should we provide an API for gadgets to use to figure out what access
tokens are available to them? Consider this use case: a photo
provider wants to provide an API for a gadget to embed a photo from
their site, but the gadget doesn't know the name or URL of the photo
in advance. Instead the user should be directed to the photo site to
pick the photo. The flow might look something like this:

- user clicks 'add a photo' link in the gadget
- container gets oauth request token from service provider
- gadget opens window to service provider authorization URL
- user picks photo from service provider
- container exchanges request token for access token
- whenever gadget uses that particular access token they get that same photo

In order to make that scenario work I think we'd need a system for a
gadget to have multiple access tokens for the same service provider.

Cheers,
Brian

Brian Eaton

unread,
Mar 4, 2008, 4:13:35 PM3/4/08
to opensocial-an...@googlegroups.com
*bump*

What is the best way to move forward on this update to the gadget spec?

Maybe we should call this a draft proposal, experiment with support in
Shindig, and then update the gadget spec based on how that goes?

Cheers,
Brian

Kevin Brown

unread,
Mar 4, 2008, 11:35:24 PM3/4/08
to opensocial-an...@googlegroups.com
That could be interesting, though I am currently refactoring the spec parsing logic so I'm hesitant to introduce such a significant syntax change.

If you can come up with a mapping (in the interim) for the OAuth params that uses the basic <Param name="">value</Param> syntax, that would allow us to do it in shindig without breaking other stuff. If that proves effective, we can discuss a cleaner syntax.

A simple solution may just be an external file:

<Require feature="oauth">
  <Param name="configuration">http://path/to/policy.xml</Param>
</Require>

This would allow the actual oauth configuration (and, naturally, the library that corresponds with it) to evolve independently from the main gadget spec. This has worked reasonably well for other file types in the past (message bundles), so I think it'll probably be OK here as well.
--
~Kevin

Cassie

unread,
Apr 1, 2008, 8:07:19 AM4/1/08
to opensocial-an...@googlegroups.com
Okay, is this something we want to get in the next iteration(0.8) of the spec?
If so, which design did we want to choose?

1. Many new ResourcePrefs or OauthPrefs plus a new require.
2. A new oauth feature which has one external configuration file.

Thanks.

- Cassie

Brian Eaton

unread,
Apr 1, 2008, 1:12:15 PM4/1/08
to opensocial-an...@googlegroups.com
Shindig uses syntax like this:

<Require feature="oauth">
<Param name="service_name">
demo
</Param>
<Param name="access_url">
http://localhost:9090/oauth-provider/access_token
</Param>
<Param name="access_method">
GET
</Param>

<Param name="request_url">
http://localhost:9090/oauth-provider/request_token
</Param>
<Param name="request_method">
GET
</Param>

<Param name="authorize_url">
http://localhost:9090/oauth-provider/authorize
</Param>
</Require>

Open issues with that format:
1) It requires gadget developers to specify the OAuth URLs. That's
probably unavoidable until OAuth discovery gets some momentum.
2) It only supports a single service provider per gadget.

Cheers,
Brian

Martin Webb

unread,
Apr 1, 2008, 6:36:07 PM4/1/08
to opensocial-an...@googlegroups.com
On Tue, Apr 1, 2008 at 1:07 PM, Cassie <do...@google.com> wrote:
Okay, is this something we want to get in the next iteration(0.8) of the spec?
If so, which design did we want to choose?

1. Many new ResourcePrefs or OauthPrefs plus a new require.
2. A new oauth feature which has one external configuration file.

Thanks.

- Cassie

At this point in time, I see us only needing to support a single oauth service endpoint.  So as long as we get that in the short-term I would be very happy.  Longer term others might require multiple oauth service endpoints...  So whatever is the easiest to give us the single endpoint...

Cassie

unread,
Apr 24, 2008, 12:00:36 PM4/24/08
to opensocial-an...@googlegroups.com
For posterity, this thread discussion moved over here:
http://groups.google.com/group/opensocial-and-gadgets-spec/browse_frm/thread/a1ce63eecfb21cad

You can see the linked thread for resolutions on this issue.
Reply all
Reply to author
Forward
0 new messages