More and more institutions are asking SURFnet how to open up a back-end data store to the general public. If there is only one trusted party requiring access to a data set, this is no major problem: simply provide the relevant party with a username and password and they can use these credentials to gain access to the data via a secure https:// connection.
More complex situations tend to arise in practice, however. A typical example is users who wish to print their Flickr photos. Ideally, these users should be able to grant a photo-printing site access to their Flickr account, but in such a way that they can revoke the access later and restrict it to a particular folder. Another example is a mobile app that needs to retrieve personal student schedules from a university timetabling system, but without granting the app access to the student’s e-mail, exam results or course enrolments.
In such complex situations – that involve granting users access to their own data as either written by clients themselves or made available by third parties – access management is much trickier. Multiple parties are involved (the user, the data supplier and the application used), and what users actually want is to grant an application (a website, mobile app, etc.) secure access to a data store on their behalf.
The OAuth protocol provides a solution to exactly these types of use cases. Now already in its second version, this protocol is an open standard developed as part of IETF, to which major cloud-based and other parties such as Microsoft, Google and Amazon have already committed. The full specifications can be found at RFC 6749. Without getting into too much detail, I will describe below roughly how the protocol works. OAuth 2 supports a range of different profiles that serve a variety of use cases. The most commonly used profile, however (and the one that applies to the cases mentioned above), is called the ‘authorisation code’ profile. The other profiles are called the ‘implicit grant’, ‘client credentials grant’ and ‘password credentials grant’ profiles. These authorisation methods are simpler and less frequently used, but are still necessary in some specific situations. A clear description of the differences between the various profiles (or ‘grant types’) can be found in this blog post
Flow of the ‘authorisation code’ profile
The flow of the ‘authorisation code’ profile as it applies to SURFconext (or to federated identities in general) works roughly as follows:
At the bottom are the users, who use an app (such as on a mobile device) to gain access to their institution’s data store or API. In OAuth terms, a data store or API of this type is called a ‘resource server’ (or RS), which delivers (sometimes filtered) resources from the institution’s back-end systems. There is also what is called an ‘authorisation server’ (AS) that processes all OAuth messages, which in this case is connected to an identity federation system (such as SURFconext) to authenticate incoming users.
So what happens when a user wants to request data from a resource server? First, the client asks the authorisation server for an ‘authorisation code’ (1). Before the AS can issue the code, it first needs to know who the user is for whom the code is being issued. To determine this information, the user must first be authorised by SURFconext (2). Following successful authentication, the authorisation server will ask the user for permission to grant the relevant app access to the requested data. Only if the user grants this permission will the AS issue the client with an authorisation code (3). The client can exchange the authorisation code for an ‘access token’ at the authorisation server, which from then on can be used to gain access to the actual data interface (without needing to repeat all of these steps). Note that this process enables an account to be ‘linked’ once within a mobile app, after which the app will always have background access to the requested data without the user having to log in again each time.
Now whenever the client wishes to retrieve data, it contacts the API resource server and presents the issued access token (4). The resource server then verifies the token’s validity with the authorisation server (5), which then provides information on the user to whom the token belongs and in which context (e.g. for which interface) it was issued. Based on this data, the resource server can decide which back-end data the client may access (7) and whether it will provide the data requested by the client (8).
Out-of-the-box Authorisation Server
Implementing such a system effectively and securely is quite a lot of work, as you can see, particularly when we consider that the above description is only one of the available flows and that various ‘corner cases’ also need to be taken into consideration. For those wishing to use OAuth, it is therefore sensible to re-use an out-of-the-box implementation instead of building an authorisation server from scratch. I will talk more about this issue, and in particular about the authorisation server developed by SURFnet, in a later blog post.