Recently, Pedro Félix sent me some questions on an internal mailing list regarding the recent sample I pushed out for integrating OAuth 2 into Web API (if you haven’t checked out Pedro’s blog, you should go and do that). I thought they were really good questions/comments, so I wanted to share them here, along with my responses, and invite you into the conversation. Some of the “Qs” are comments, but in the name of keeping the format simple, I’ve just broadly adopted the Q/A format.
Regarding the “A Brief Disclaimer” section, OAuth’s primary goal is delegated *authorization* on resource access. IMHO, your scenario fits well into this goal. The key observation is that the *resource* under access control is the *user’s identity*. Instead of the user *pushing* its identity to the service (e.g. Basic authentication or a federation protocol such as SAML), the service *pulls* this identity (just a resource from the OAuth view point) from a trusted-third party (Facebook).
I agree that it fits – However, I don’t yet believe that treating an OAuth resource server role as an identity provider “fits well” for 2 main reasons:
- It seems wasteful to establish an OAuth session (using “session” since an access token as valid – and as such must be stored on the authZ or resource server) so that it can be used just long enough to get a piece of identity information. For that scenario, the push model of federated identity tokens seems like a better fit.
- Because OAuth is really an authorization protocol, and because the major players like Facebook act as both the authZ server and the resource server role, every application that wants to have Facebook authenticate its users (each “relying party”) needs to register a pho Facebook application with its own app key and secret – or use a broker like ACS that does this for you and sends you an identity token. Again, doable, but feels to me like a misuse of OAuth.
I’m unable to fit this scenario into any of the typical OAuth use cases/profiles. Typically, the OAuth client
- is a webapp interacting with the user via a browser
- is an active client running on the user’s machine
In this scenario, the OAuth client is a web service, being accessed by a service client on the user’s machine:
The scenario is a modification of a standard OAuth server flow. Web API is the OAuth client, Facebook is the AuthZ and resource server. Web API fits into the definition of a confidential client here and as such, I’m using an auth code grant type. Where this breaks off from the more typical OAuth flow (which would generally be a Web application) is in the fact that the UX is a single page, AJAX-driven app, so there’s an additional protocol (term used loosely) happening between the jQuery code and the Web API.
IMHO, it would be better to start with simpler scenarios
- web api as a resource server, using an external authz server (e.g. AppFabric’s ACS)
- web api as an authz server, using various grant_type (password, client_credentials, saml,…)
I called those out at the bottom of the post and these are the scenarios that I’m working through now – For people unfamiliar with the world of federated identity, though, I would argue that they are not inherently simpler scenarios.
On OAuthFacebookOpHandler, I don’t think that attaching the principal to the current thread is a good idea on this brave new world of asynchrony – the underlying thread may change several times. A better solution would
- Attach the principal to the current request message (the threads may change on a request, but the request message doesn’t)
- Return the principal as an http parameter, so that it can be used as an input parameter on downstream handlers and on operations
both good ideas – will update