Posts tagged Google

Last week I was in San Francisco for the 16th Internet Identity Workshop to disseminate the Linkey project and engage with those in the online identity communities.

The event was sponsored by many big names including Microsoft, Ping Identity, Google, Janrain, Yubico, Cisco, OneID and NetIQ. In attendance were employees from all of the sponsor companies as well as delegates ranging from freelance developers to information compliance officers at big companies to authors of many Internet specifications and protocols such as OpenID, OAuth and SAML. About half of hundred or so delegates had travelled from outside North America including about ten of us from Europe. Surprisingly I was the only delegate representing an educational institution.

The conference itself was un-conference style – i.e. each morning delegates would volunteer sessions which were then slotted into the timetable. A full list of all of the sessions can be found here. The sessions people put forward tended to either be very technical or were higher level, almost philosophical discussions.

Here is a list of sessions I attended (session notes can be found here):

  • T1G: Native Apps – SSO
  • T2B: Strong 2-Factor For All – Google and FIDO Alliance
  • T3C: The OAuth Complicit Flow
  • T4G: Identity Federation: Failed Consumer Experiences and WHat We Can Do About It
  • W1H: OAUTH Client Registration
  • W3B: OAuth 2 Bootstrapping from device to browser (technical)
  • W4B: Google’s Auth goals for the next 5 years
  • Google are strongly committed to OAuth!!!!
  • W5I: OAuth 2 Federation – RS trust external AS
  • TH2E: Practical DATA PROTECTION – Avoidance? EU and US ?
  • TH3A: RESPECT CONNECT “Facebook Connect for Personal Clouds” OR “Social Login that Doesn’t Suck”
  • TH4F: Self-Hosted Personal Clouds (FreedomBox and Raspberry PI)

The two main overarching topics throughout the event were “privacy” and “data ownership”. There were also a number of sessions about security, with one session that I attended by Google about 2-factor authentication resulting in quite heated discussion (namely because the work Google and the FIDO Alliance is not public and there is a high fee for membership).

Another interesting session was called “The OAuth Complicit Flow” (notes here) which had the premise of “what if the an OAuth authorisation server asked you to agree to “allow this application to connect to your account and murder someone” and there was no deny button. The discussion dealt with the issue of some applications asking for too many permissions, users not reading through the approve screens (similar to how users just accept EULA agreements) and applications refusing to let users access them unless they agree to allowing the application share stuff on their Facebook wall, or see the user’s friend list. Potential solutions that came out of this discussion was “reactive” permission requests as opposed to “preemptive” permissions – similar to how some iOS apps don’t ask for permission to send push notifications unless you click a button in the settings for that app.

I got the opportunity to have a chat with Mike Jones from Microsoft who has been leading much of the work on the OAuth 2.0 and OpenID Connect specifications. He answered a few questions I had about edge cases in implementations and he was interested in the PHP libraries I’d developed as part of the project.

I didn’t have the opportunity to talk at length about Linkey but in all the sessions I attended I tried to take part and I had some really interesting discussions with people about some of work that we’re doing in HE around open data and open APIs (including work on OAuth) and I was able to talk about some of the issues we faced with implementing OAuth in enterprise environments (because of incompatibility and lack of understanding compared to SAML).

I feel that the conference was definitely worth attending and I would encourage JISC and other interested parties in the education sectors to try and attend the next Internet Identity Workshop as I left feeling that we’re dealing with some very similar problems that even the very large organisations present such as Oracle are dealing with.

One of the other PHP libraries I’ve been working for Linkey is a PHP library that makes working with other OAuth 2.0 identity providers “stupidly easy”. I think I’ve done that and it’s time to announce the initial release – https://github.com/lncd/OAuth2-client.

So lets say you want to allow users to sign-in to their Facebook account:

$provider = new \OAuth2\Client\Provider\Facebook(array(
    'clientId'  =>  'XXXXXXXX',
    'clientSecret'  =>  'XXXXXXXX',
    'redirectUri'   =>  'http://your-registered-redirect-uri/'
));

if ( ! isset($_GET['code'])) {

    // If we don't have an authorization code then get one
    $provider->authorize();

} else {

    try {

        // Try to get an access token (using the authorization code grant)
        $t = $provider->getAccessToken('authorization_code', array('code' => $_GET['code']));

        try {

            // We got an access token, let's now get the user's details
            $userDetails = $provider->getUserDetails($t);

            foreach ($userDetails as $attribute => $value) {
                var_dump($attribute, $value) . PHP_EOL . PHP_EOL;
            }

        } catch (Exception $e) {

            // Failed to get user details

        }

    } catch (Exception $e) {

        // Failed to get access token

    }
}

Simple right? If you take out the try/catch statements then it essentially boils down to this:

$provider = new \OAuth2\Client\Provider\<provider name>(array(
    'clientId'  =>  'XXXXXXXX',
    'clientSecret'  =>  'XXXXXXXX',
    'redirectUri'   =>  'http://your-registered-redirect-uri/'
));

if ( ! isset($_GET['code'])) {

    $provider->authorize();

} else {

    $token = $provider->getAccessToken('authorization_code', array('code' => $_GET['code']));
    $userDetails = $provider->getUserDetails($token);
}

The library automatically manages the state parameter to help mitigate cross-site request forgery attacks (where supported by the end-IdP).

At the time of writing there is built in support for Facebook, Google and Github but adding support for other identity providers is trivial – you just need to extend the IdentityProvider class.

I will add support for more providers soon. There also aren’t any unit tests currently but they are coming.

The library is hooked up to Packagist so just add "lncd/oauth2-client": “*” to your composer.json file.

Last night I took part in the Life, Identity, and Everything Google developer chat with Tim Bray and Breno de Madeiros.

Tim Bray is the Developer Advocate, and Breno de Madeiros is the tech lead, in the group at Google that does authentication and authorization APIs; specifically, those involving OAuth and OpenID. Breno also has his name on the front of a few of the OAuth RFCs. We’re going to talk for a VERY few (less than 10) minutes on why OAuth is a good idea, and a couple of things we’re working on right now to help do away with passwords. After that, ask us anything.

Here is the video of the chat:

To summarise the event they said that Google are committed to OAuth 2.0 and OpenID. They intend on all Google APIs supporting OAuth 2.0 and they believe it has helped developers develop for Android because support for the OAuth dance is baked into the Android APIs making it very simple to integrate with it.

They also feel that Mozilla Persona is a promising (but complicated) protocol; however they feel that on mobile devices it will cause problems in terms of the user flow.

I asked two questions which Tim and Breno answered:

”What do you think the future of OAuth is? Eran Hammer publicly quit as the editor and claiming the v2.0 specification is “more complex, less interoperable, less useful, more incomplete, and most importantly, less secure”. Will there be OAuth 3?”

and

“Could a ./well-known/oauth file published at each providers endpoint help with interoperability? This file would describe their implementation responds with json or text, which grants are supported, etc”

Tim Bray, a developer at Google who I disagreed with in a previous post has just posted on his blog that the team he is currently working in is going to shortly be announcing some of their early work and thinkings soon.

He says problems they’ve identified and they want to try and solve include:

  • The username/password dance sucks and doesn’t scale, particularly on mobile.
  • People putting up apps and sites regard identity — getting people signed up & signed in — purely as a tax; something they gotta do, but unrelated to what they care about.
  • Most developers don’t understand identity standards like OAuth, or the related crypto and signing technologies, don’t want to learn them, and shouldn’t have to.
  • If you can get new arrivals signed up quicker with less work, that’s a good thing.
  • If you can get people you know signed in quicker, ideally with one click, that’s a good thing.
  • People are paranoid and really don’t want to be in the headlines for next week’s embarrassing password leak.
  • People don’t want to think about privacy and tracking and transparency, but the risk of not doing so (just) exceeds the pain.
  • People like the notion of outsourcing the icky identity work, but are nervous about putting all their eggs in the Facebook’s or Google’s or Yahoo’s or whoever’s basket.
  • On the other hand, having a cluster of Sign in with… buttons on your landing page dilutes your brand and feels like watching NASCAR on TV.

I’m looking forward to seeing what they come up with.

The following sequence describes how the OAuth 2.0 web-server flow works. The web-server flow is the most common OAuth flow which most implementations support.

Before we begin there is some terminology that needs to be understood:

  • Resource owner (a.k.a. the User)
    An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.
  • Resource server
    The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
  • Client
    An application making protected resource requests on behalf of the resource owner and with its authorisation. The term client does not imply any particular implementation characteristics (e.g. whether the application executes on a server, a desktop, or other devices).
  • Authorisation server
    The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorisation.

The web-server flow

1) The client redirects the user to the authentication server with the following information

  • The client’s ID (client_id)
  • A redirect URI where the user will returned to after they’ve authenticated with the authentication server and approved the client (redirect_uri)
  • The type of response that the client accepts (response_type)
  • A list of data which the client wishes to access on behalf of the user (scope)
  • A state parameter which is an anti-CSRF token (state)
	HTTP/1.1 302 Found
	Location: https://auth-server.tld/authorise?response_type=code
	&client_id=6BZF3wT52E7PaIlF1luRrKM4LMfkl649
	&redirect_uri=http://client.tld/signin/redirect
	&scope=basic,contacts
	&state=84Y632oM3j

2) The user signs into the authentication server and, if they haven’t already, approves the client to access their data. The user is informed which data the client wishes to access (defined by the scope parameter). If the user has already approved the application the server will check if the scope parameter matches that of the previous request and if it doesn’t will ask the user to sign in again.

3) The authentication server redirects the user back to the client (based on the redirect_uri parameter) with an authorisation code and the anti-CSRF token in the query string

	HTTP/1.1 302 Found Location: http://client.tld/signin/redirect
	?code=Al0wQaeTYsji97oRWk2l6Y940wdca3J2
	&state=84Y632oM3j

4) The client then exchanges the authorisation code for an access token by authenticating itself with the authentication server

	POST http://auth-server.tld/access_token HTTP/1.1
	Content-Type: application/x-www-form-urlencoded
	client_id=6BZF3wT52E7PaIlF1luRrKM4LMfkl649
	&client_secret=Al0wQaeTYsji97oRWk2l6Y940wdca3J2
	&redirect_uri=http://client.tld/signin/redirect
	&code=Al0wQaeTYsji97oRWk2l6Y940wdca3J2
	&grant_type=authorization_code

5) The authorisation server will perform the following validation:

  • Check that the client_id and client_secret are valid parameters
  • Check that the [authorisation] code matches the client_id and the redirect_uri

If the parameter pass the validation checks then the authentication server will respond with the access token that the client needs to access the user’s data. The server may also include a refresh token in the response.

	HTTP/1.1 200 OK
	Content-Type: application/json;charset=UTF-8
	Cache-Control: no-store
	Pragma: no-cache
	
	{
		"access_token":"2YotnFZFEjr1zCsicMWpAA",
		"expires_in":3600,
		"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
	}

Accessing resources

Once the client has the access token it can then make requests to the resource server for the user’s data

	POST http://resource-server.tld/user/details HTTP/1.1
	Content-Type: application/x-www-form-urlencoded
	
	access_token=2YotnFZFEjr1zCsicMWpAA

Angst against OAuth

Tim Bray, a developer at Google wrote in a recent blog post that he believes:

The new technology coming down the pipe, OAuth 2 and friends, is way too hard for developers; there need to be better tools and services if we’re going to make this whole Internet thing smoother and safer.

As someone who has been working with OAuth 2.0 for almost 18 months now I disagree with Tim’s position that OAuth 2.0 is “way too hard” for developers. The web-server flow essentially is a simple two step process:

  1. A redirection from the client to the authorisation server
  2. A POST request to the authorisation server to swap the authorisation code for an access token

I find it hard to believe that those two simple steps are too much for developers to implement in their applications.

It’s true that OAuth 1.0a was a pain to implement – just take a look at Twitter’s OAuth 1.0a guide to see how complicated it is in compared to the v2.0 flow I’ve described above – however as more and more service providers offer OAuth 2.0 endpoints I believe that developers will realise how easy it is to actually implement.