The simplest possible OAuth element declares that a gadget will use
OAuth with a service provider that supports OAuth discovery:
<ModulePrefs>
<OAuth>
<Service />
</OAuth>
</ModulePrefs>
OAuth discovery is new, and not many service providers support it yet.
The simplest possible OAuth element for a service provider that does
not support OAuth discovery declares three URLs used during the OAuth
protocol. Several reasonable defaults are assumed for some of the
OAuth protocol details.
<ModulePrefs>
<OAuth>
<Service>
<Request url="http://www.example.com/request"/>
<Authorization url="http://www.example.com/authorize"/>
<Access url="http://www.example.com/access"/>
</Service>
</OAuth>
</ModulePrefs>
The most complex OAuth element declares that the gadget will access
data from multiple OAuth service providers, and declares URLs and
several OAuth protocol details for all of them.
<OAuth>
<Service name="serviceOne">
<Request url="http://www.example.com/request"
method="GET"
param_location="header" />
<Authorization url="http://www.example.com/authorize"
method="GET"
param_location="header" />
<Access url="http://www.example.com/access"
method="GET"
param_location="header" />
</Service>
<Service name="serviceTwo">
<Request url="http://other.example.com/request"
method="GET"
param_location="header" />
<Authorization url="http://other.example.com/authorize"
method="GET"
param_location="header" />
<Access url="http://other.example.com/access"
method="GET"
param_location="header" />
</Service>
</OAuth>
OK, now that there are some examples to show how things ought to look,
let's get normative:
The <ModulePrefs> element can contain 0 or 1 <OAuth> elements.
The <OAuth> element can contain 1 or more <Service> elements.
The <Service> element has a single attribute:
name [optional]. This is a nickname the gadget will use to
reference the service provider. If unspecified, it defaults to "".
The <Service> element contains three elements, a <Request> element, an
<Authorization> element, and an <Access> element.
The <Request> element has three attributes.
url [required]: the absolute URL of the service provider request endpoint.
method [optional]: the HTTP method to use to access the
endpoint. May be GET or POST. If unspecifed, defaults to "GET".
param_location [optional]: the location of the OAuth parameters
in the request. May be "url", "header", or "body". If unspecified,
defaults to "header".
The <Access> element is identical to the <Request> element, but
describes an access token URL instead of a request token URL.
The <Authorization> element has a single attribute:
url [required]: the authorization URL for the service provider.
No, you would need to include an OAuth stanza for each service
provider whose data your gadget wants to access.
Example:
Gadget G hosted on container C1 wants to access user data on service provider S.
Gadget G should:
- include an OAuth stanza describing the OAuth interface provided by S.
- obtain a consumer key and secret from S.
- notify C1 about the consumer key and secret for the gadget.
If gadget G wants to run on container C2, the same consumer key and
secret might be usable, or perhaps a separate API key is necessary.
That's up to the gadget author and the service provider. The same
OAuth stanza should work in all containers that support OAuth.
Some bits can be automated very well, such as figuring out the OAuth
endpoints. That's grunt work for gadget authors, and OAuth discovery
will make that problem go away.
Registering consumer keys is interesting, it has more to do with
business than technology at this point. It's my hope that service
providers will make registering for consumer keys an automatic
process. If that doesn't happen, then either containers or gadget
authors are going to have to go through the manual registration
process. Legal issues, like agreeing to TOS, need to be addressed.
Containers need to tell gadget authors how to associate consumer keys
and secrets with their applications.
I put together a proposal that would allow a consumer and service
provider to automate registration. The consumer would verify that
they own a particular URL, and then the service provider would issue a
consumer key to that URL. That could be a good fit for gadgets and
OAuth.
Cheers,
Brian
I don't think your questions are off-topic at all. The problem I am
trying to solve is this one:
- user has an account at some service provider.
- they also have an account at some social networking site.
- how can they see their data from the service provider on the SNS?
There have been several answers to that question in the past (BBAuth,
AuthSub, others...). OAuth is an attempt to standardize those
protocols so that developers don't need to learn a new protocol every
time they integrate with a new service provider.
The problem with gadgets and OAuth is that gadgets don't know much
about who the user is without container support, and gadgets have no
way of keeping long-lived secrets (like the consumer key and secret,
or the access token and secret) out of browsers. One way to fix that
is container support for OAuth, where the gadget server stores the
OAuth secrets and carries out the OAuth protocol on behalf of the
gadget. That's the goal of my proposals.
> So maybe I came late to the discussion, but all I see is that you're
> proposing adding more information to the gadget xml. But who will use
> that information and for what?
The gadget server will use the information run the OAuth protocol on
behalf of the gadget.
> Are you trying to offload some oauth related work to the container?
> What work?
Most of the work. The gadget developer needs to
a) register a consumer key and secret, and tell the container about that secret.
b) understand the semantics of the service provider APIs.
c) direct the user to the service provider approval page at the
appropriate time.
The gadget developer should *not* need to know the details of the
OAuth protocol.
> Are you saying that the container would somehow be an oauth bridge for
> gadgets?
> Is that a good idea?
Yes, and yes. =)
> Why would an app trust a container enough to let it impersonate the
> gadget?
The gadget already has to trust the container completely, since the
container does all of the work to authenticate users, render the
gadget, and handle requests from the gadget. They are joined at the
hip. There's no way to implement OAuth in pure client-side code with
any degree of security or usability, there has to be server-side
support.
Cheers,
Brian
Yes, it does. Service providers need to make this easy if they want
third-parties to write apps that use their APIs. If a service
provider wants to restrict access to their APIs, they can certainly do
that.
> But even if the
> consumer registration is automated, doesn't the consumer app need to
> have prior knowledge of what is available from the service provider to
> write code and make use of the service providers APIs?
Service providers provide APIs, and gadget developers will write to
those APIs. The gadget developer has to know what those APIs can do,
how else are they going to write a cool application on top of them?
My goal is to prevent gadget developers from needing to learn OAuth.
Learning the service provider APIs is enough of a challenge.
> Where is your proposal for automating registration?
http://groups.google.com/group/oauth-extensions/browse_thread/thread/bdd87bc7de25867c
Cheers,
Brian
OK, good. Feel free to say so when I stop making sense, it happens on occasion.
> Though, this is for the use case where the gadget is fully client-
> side. Though I guess you could argue that for most gadgets worth
> their weight, it will be heavy weight and backed by a server..
> maybe? :) :)
I hope the OAuth proxy makes it so easy to write fully client-side
gadgets that this isn't true.
> (you could expose this oauth bridge through the REST api as well!! )
Whoops, my brain just melted. Please bring this up again once the
REST apis have matured, maybe I'll get it then. =)
There's some confusion here, between seeking approval from the end
user and seeking approval from the service provider.
All OAuth flows are going to require end user approval at some point,
that's what the protocol is for.
Seeking approval from the service provider is a different story.
There is a huge range of options here. Some service providers will
issue consumer keys to anyone, some will require TOS, some will
require legal contracts, and some will never issue an API key to
anyone who doesn't actually work for them.
> Since the OAuth protocol doesn't
> specify how this consumer key is handled, it's up to each service
> provider to implement their own mechanism thereby seriously limiting
> the standard protocol format unless a mechanism like what you proposed
> get implemented, is it?
I disagree on this point. Registering for a consumer key is ad hoc.
Using that consumer key goes through a well defined protocol. This is
pretty much the norm for authentication protocols.
I'd love to see automated registration happen, but even if it doesn't
OAuth will still be useful. Witness BBAuth/AuthSub/etc, all widely
used, all using ad hoc consumer key registration.
> Unlike openID which only goal is to authenticate a person identity,
> OAuth is designed to grant access to any number of potential APIs
> which require prior knowledge and development to make use of,
> otherwise OAuth by itself isn't useful.
Yes, exactly.
> I think the conclusion I am
> coming to is that OAuth discovery is essentially not useful or
> relevant in real world applications. OAuth protocol yes, OAuth
> discovery, no. Does that make sense?
Not one bit, no. =) OAuth discovery will definitely simplify
configuration by removing the need for developers to cut and paste
URLs. OAuth discovery may end up simplifying consumer key
registration as well. The SAML metadata format was a big win in terms
of ease of configuration for SAML 2.0. I suspect OAuth discovery will
fill a similar gap.
The <Request> element has three attributes.
url [required]: the absolute URL of the service provider request endpoint.
method [optional]: the HTTP method to use to access the
endpoint. May be GET or POST. If unspecifed, defaults to "GET".
param_location [optional]: the location of the OAuth parameters
in the request. May be "url", "header", or "body". If unspecified,
defaults to "header".
Sounds good to me.
Yah, all true. The only place we'll have to agree to disagree is on
whether or not OAuth discovery is useful. I have lower expectations
for OAuth discovery than you do, so I'm not disappointed with what it
offers. =)