What happened was, HR wanted to set up a partner to offer benefits for active Googlers only, and thus we discovered an OAuth 2-based trick that I bet will work in lots of other situations too.
The scenario · HR wanted to set up this financial-services company (let’s call them “FSCo”) with a special deal for Googlers. So FSCo needed a way to test whether someone’s an employee. But the financial services might survive their employment, so FSCo also needs an independent relationship with the people who use them.
Here’s how it works · Suppose some Googler, let’s say Ed Xample, wants to sign up.
The full step-by-step follows, but the short form for those who are hip to the OAuth 2 jargon: FSCo runs a basic OAuth 2 code flow, set up so they get a refresh token. Then they can check whether Ed is still a Googler by using the refresh token, which magically stops working when Ed quits or gets fired or dies. Hey-presto!
Now let’s do the details.
Ed Xample drops by FSCo’s site. FSCo gets him to sign up for an account with them using his personal address, say “email@example.com”.
FSCo gets that account set up, then says “Now you need to prove you’re a Googler. What’s your email there?” Ed fills in “firstname.lastname@example.org”.
FSCo’s back-end starts an OAuth 2 flow with accounts.google.com, of the flavor described in Using OAuth 2.0 for Login, but the details matter, especially the construction of the Authentication URI; check the Advanced Topics section:
Since FSCo is security-conscious, they cook up a “state” value that
encodes some session state, and provide it in the
Since FSCo is doing this server-to-server, they
Since they know Ed’s email address, they say
email@example.com; this means that even if Ed is
signed with multiple Google accounts (which Googlers often are), he
won’t see the account-chooser screen.
The scope argument has to start with
openid email because
FSCo wants to get an ID Token back with an email address in it.
Since FSCo wants a refresh token, they say
So, the Authentication URI they send off to Google might look something
like this (with white space for readability):
https://accounts.google.com/o/oauth2/auth?FSco’s registered Client ID
&FSCo’s registered redirect URI
&FSCo’s clever state value
At this point, if Ed isn’t logged in as firstname.lastname@example.org, he’ll have to do that, and in any case he’ll see an approval screen asking him if it’s OK to share his status with FSCo. Let’s assume he’s logged in and he approves.
Now FSCo’s back-end does the rest of the OAuth dance (read the docs, I’m not giving the step-by-step), getting an “authorization code” from Google and swapping it for goodies including an ID Token and a Refresh token.
Since FSCo is security-conscious, it double-checks the value of the
state parameter, validates the ID Token, makes sure the
aud field matches its Client ID. There are libraries
for most programming languages that take care of this.
Once the dance is complete and everything checks out, FSCo updates its database to remember that for the long-lived “email@example.com” account, the Google address is “firstname.lastname@example.org” and here’s the refresh-token value which proves that. The refresh token value never expires, and FSCo should store it in a safe placefor the long term.
Whenever FSCo wants to find out if Ed is still working at Google, they swap the refresh token for an access token. I suspect in many of these scenarios they won’t actually look at or use the access token, they’ll just make sure that the swap worked.
This swap is a server-to-server back-end thing, you don’t have to pester Ed to get involved.
The thing that makes this work is that when Ed leaves Google, the refresh token will stop working. Now, there are some corner cases: Ed could manually invalidate the token in his account settings. Also, Google might invalidate it if Ed’s account had been seriously hacked or for some other security reason.
So if the swap fails, FSCo should tell Ed and he tells them either that nope, he’s no longer a Googler, or yes he is, so please re-run the script above to get a new refresh token.
This is good! · Ed gets pestered just once, FSCo gets a robust indicator of his employment status, and everything happens over nice safe secure encrypted channels.
For general use? · So, I asked around my group at Google, saying “This looks like a useful pattern, would it be OK to tell the world?” A couple of points came up: First, it’s only going to work with an enterprise that’s an OAuth 2-compliant Identity Provider; but that’ll be pretty common down the road, I think.
Second, someone pointed out that the refresh-token-doesn’t-work-when-employee-leaves isn’t exactly in the OAuth 2 spec. I’m not convinced; RFC 6749 says “The authorization server MUST validate the refresh token”; the callout to RFC4949 to define “validate” just says “Establish the soundness or correctness”, and it seems to me that no sane implementation is going to accept a token for an account that’s gonzo. Right?
OAuth 2, there are lots of reasons to like it.