Wednesday, March 23, 2011

OAuth Flows - Extended

Updated: Revised flow to add javascript implicit flow.

I received a lot of interesting comments on my previous post, "Does OAuth Have Legs". That post was about trying to understand what was meant by legs in OAuth. It included a useful diagram which I have since updated based on feedback. The revised diagram is available below (click to enlarge).
A couple of notes:
  • The flows depicted are from the perspective of what a client app has to do to access a protected resource.
  • The general consensus was that "legs" was meant to refer to parties and not the number of steps though co-incidentally, it was often the same. The consensus on the OAuth mailing list seems to be to now refer to, 2-party or 3-party flows.
  • Each party has one or more "roles" as defined in OAuth: Resource role (the resource being requested), Token Service Role (the server issuing access tokens), and Authorization Service Role (the server that determines if the end-user has granted permission, and if not obtains it).
  • The Implicit Request (OAuth v13, sec 4.2) is actually a dual-role request. It requires that the authorizing server also issue tokens. I have put this in a separate "dual-role" box in the diagram.
  • There may be additional exchanges not shown in the diagram such as logging in the user in order to obtain authorization. These are not shown since they are out of scope of the OAuth specification and should not impact the client (i.e. because authorization is obtained from the user using an external browser).

Wednesday, March 9, 2011

Lightweight Web Services

There has been growing interest in a group of protocols, namely HTTP, REST, OAuth, and JSON, and how they can support web services. REST and JSON, have been around for a while, but one of the puzzling problems was how to handle authentication in REST especially for non-browser based clients using HTTP. So far the only options have been BASIC authentication or SSL/TLS mutual authentication. So far, neither of which have been adequate (but that's a whole other blog post). However, more recently OAuth2 emerged, and offers some possibilities - especially for access to user controlled resources.

Another reason for interest in these protocols has been the emergence of cloud services and smart phones. Instead of using traditional web services such as WS-*, cloud service providers are opting for lighter weight, more quick to implement approaches that focus on basic HTTP. Smart phones with increasingly popular 'app stores' and their obvious need to be lightweight also figure heavily in this surge in interest OAuth, REST, and JSON. It occurs to me that the common theme here is a drive towards something I'll call "lightweight web services".

Pragmatic cloud proponents argue that WS-* and other specifications like SAML, ID-WSF and so on have all become bloated and unworkable. They are just too much for application developers to handle. Why not get 'lightweight' and use specifications like the PortableContacts spec to transfer personal information? Traditionalists argue about security, privacy and other important aspects. In contrast, lightweight web services focus on transport layer security to do most of its work.

Are proponents trading off security, inter-operability, and flexibility for one-shot-at-a-time lightweight services? Let's take a look at the key technologies/standards that comprise lightweight web services so far and talk about some of the challenges/drivers going forwards...

HTTP is the foundation upon which Lightweight Web Services are built. The founding protocol on the web, HTTP is getting a new look as new application clients begin using HTTP rather than just browsers. Driven by social media and the emergence of smart-phone applications and cloud services, HTTP is now the foundation protocol upon which both browsers and application clients are accessing resources and services on the web.

REST has been around for a while. Before it was popular, early web systems used REST like calls in the 90s (before it was called REST). REST creates simple, easy to document APIs that are more URL centric that seem to be more friendly to developers. The emergence of social network APIs (e.g. the Facebook Graph APIs) are good examples. It seems that many developers would rather trade discovery based code generation (e.g. facilitated by WSDLs) for simple-to-read web site documentation and manual code writing against a simple REST API.

JSON or JavaScript Object Notation is the new XML. It enables simple results from REST based service calls to be returned to clients. From wikipedia...
"It is derived from the JavaScript programming language for representing simple data structures and associative arrays, called objects. Despite its relationship to JavaScript, it is language-independent, with parsers available for most programming languages."
OAuth2, originally a method of delegating authorization to access web services (typically used in social media), OAuth2 is quickly becoming a badly needed authentication/authorization services for non-browser web application clients. While browser authentication had quickly migrated from BASIC Authentication (defined by RFC 2617) to Forms based authentication supported by cookies, OAuth provides new browser-less client applications a needed method to authenticate to web services using the HTTP Authorization header.

Shaping Lightweight Web Services
Lightweight web services have come on so strong proponents have generated "need it yesterday" demand for features that aren't yet defined or standardized. Some features are critical and while others are debatable. At present, there is still no standardized authentication token suitable for non-browser web service clients; no signing and/or encryption of content (other than TLS); no concept of message handling and much more. Are we rushing to re-invent here because of the design to have a single tool for all jobs? Or is this just a case of building out REST services to a supportable, secure level of some sort?

The lightweight web has so far been a loosely associated set of technologies with some interesting design patterns in common. As enterprises are quickly joining the community, it seems important that lightweight web services gain a more formal status with discussion in a new working group.

I invite everyone to help further define what are Lightweight Web Services and to help define a WG to help steer the development of relevant IETF and non-IETF standards that make up lightweight web services.

Tuesday, March 1, 2011

OAuth: New Chain Grant Type

I posted a new Internet Draft, the "Chain" grant draft today for the consideration of the OAuth2 working group. The specification defines a new grant type that enables an OAuth protected service to in turn act as an OAuth client to another OAuth protected service. The grant type allows the first server to exchange the current oauth access token for a new token valid on the target service. This grant type makes it possible for multiple connected services to interact in a message bus or chain.

Introduction
The use case for this proposal springs from inter-service communication or messaging scenarios. Currently many applications use SOAP based services, such as in WS-SecureConversation which have ways to handle authorization and identity propagation between service end-points.

Now, that REST is becoming popular, the question arises as to how to properly propagate identity without heavier SOAP messages. Since REST relies solely on HTTP, how do you pass identity assertions?

Aside: Note that I'm not saying REST is better or worse than SOAP, merely that REST needs a way to propagate identity just like SOAP.

OAuth seems to have some answers to this question by allowing services to use tokens to access protected resources. It also allows for SAML Assertions to be exchanged for OAuth bearer tokens. But what happens if multiple services are chained together in a bus? What happens when the next pairwise exchange that needs to occurs? The original user and/or SAML bearer assertion is no longer available.

As currently specified, the OAuth framework handles only one client-service pair relationship, it cannot handle multiple 'chained' service calls.

Let's take a look at the following scenario:
In the above picture, we see a user, accessing a web site that offers banking statement aggregation. The user, having previously authenticated to "Bank Svc" (the Bank), indicates to the Aggregator that they would like to include information from the Bank. The Aggregator site accesses the token service for the Bank. The Bank Auth/Token Service, takes into account the user context (UC), the client credentials (C1C), and a requested scope and if successful, returns an access token (AT1).

Note: for those paying attention, there is often a 3-legged flow involving the end-user, but I am simplifying for brevity.

Once the access token AT1 is returned, the Aggregator is free to access the Bank as authorized by the user and the Bank's Authorization Service.

So far, we have demonstrated a successful capability to access a REST based service using a token that embodies both a user context, a client context, and a scope. But what happens, as is common in messaging systems, if the Bank in turn wants to access another service provider (e.g. Trader). Since there is no longer any direct user involvement, can the Bank obtain an access token for the Trader service?

The Chain Grant Profile
In this scenario, the Bank is acting under some high level of trust with the Trader service. E.g. the Bank owns the Trader service. In this case, the Trader is willing to trust the Bank application to indicate that it has the authorization to work on behalf of a user. In this flow, the Bank application contacts the authorization service for the Trader, and requests an access token using a new grant_type called "chain". In the "chain" grant type, instead of passing a user context, or an authorization code, the client instead passes an access token received from the Aggregator.

In this flow, the Bank provides its own client context (C2C) for its application (now acting as an OAuth client), and the access token (AT1) that it received from the aggregator is included in a POST to the Trader authorization/token service. This allows the Trader's authorization/token service to either parse AT1 or contact the Bank's authorization service for more information. In this case, AT1 embodies both the original user context (UC) plus the Aggregator (C1C). After successful processing, the Trader authorization service issues AT2, which combines C2C and AT1 as shown below.

In multi-node scenarios, this process could be repeated indefinitely leaving a traceable security path to the originating user along a pair-wise trust path between services.

Token Issues
One thing the draft specification does not address is how the trader's OAuth authorization/token service is able to parse the bank's authorization token (AT1). This likely will be handled in upcoming OAuth token specifications standardizing formats and claims included in tokens.

As always...comments and feedback are appreciated.