DIRK BALFANZ: So, OK.
Welcome everybody to the--
I think it's about the last
session of the day here.
My name is Dirk Balfanz.
I'm a member of the Security
Team at Google, where I work
on authentication, user
authentication issues: things
like 2 factor authentication,
OpenID,
OAuth, things like that.
The title of the session
is ClientLogin #FAIL.
There's a URL down here on the
slide, where you can leave
real time feedback about
the session.
It's goo.gl/2Qxx6.
And the hashtags for this
track are GoogleAPIs in
addition to the io2011.
So what we're going to talk
about in this session are
installed applications, and in
particular, what you need to
do when you need to authenticate
Google APIs from
an installed application.
Traditionally the API you use
to obtain authentication
tokens for installed application
is called
ClientLogin.
But I'm going to explain why
ClientLogin is actually not a
good choice for your users.
I'm going to briefly talk a
little bit about application
specific passwords, which are
sort of a stopgap for
applications that can't move
away from ClientLogin.
But most of the time I'm going
to talk about OAuth, OAuth 2.0
in particular, and how it can
be used for installed
applications.
And I expect to be talking
about 45 minutes or so,
leaving time for questions
at the end.
So--
Excuse me.
So what are installed
applications?
Installed applications are
anything that the user
downloads on their machine,
installs and that are not
bound by the rules of the web.
There's no same origin policy
that this application
needs to abide by.
They have access to a whole
bunch of platform APIs that
you couldn't access otherwise
from a web
application, for example.
So if you have a video editor
that uploads videos to
YouTube, that's an installed
application.
If you have a photo viewer that
can access your Picasa
web albums, that's an installed
application.
Your IMAP clients, your
Thunderbirds, your Mac Mails,
your Talk clients,
and so forth.
Those are all installed
applications.
And the ones that we're
interested in here are the
ones that need to authenticate
to Google APIs.
Your iPhone apps, your Android
apps, those are installed
applications, the native apps
that you get from the Android
market and the App Store,
I guess it's called.
And you guys, as developers,
you probably deal with just
your command line tools that
sometimes also need to
authenticate to Google APIs--
for example, the App Engine
config tool that you use.
And there's a bunch of
screenshots of a variety of
installed applications
on the slide.
So I mentioned previously that
today, what installed
applications often do is when
they need to authenticate to a
Google API, they used this
endpoint that we have called
ClientLogin to exchange,
basically, a username and
password for an auth token.
Then you take the auth token,
and you take it to your
application, your
API endpoint.
And that's how you
authenticate to the API endpoint.
The user experience looks
something like this.
The application draws some
window on the screen
and says, hey user.
What is your username?
What is your password?
The user enters the username
and password.
And then the app takes that to
the ClientLogin endpoint.
Whenever I have a little demo
thing on the slide, I'm going
to try and show you
how this works.
Don't let me go through a slide
that has one of the demo
things on there without
actually doing it.
I might forget.
So I have a little cheat
sheet here also.
You do not want to have
to wait for me typing.
Trust me.
So hitting the ClientLogin
endpoint is
really pretty easy.
All you need is curl
basically.
So it's on google.com/accou
nts/ClientLogin.
If you give it an email,
you give your password.
And you say which service
you want to access.
In this case, CP is the address
book, the contact API.
And that returns a bunch
of auth tokens.
The one that's interesting
here is the
third one down here.
Let me extract that.
So now you have the auth
token that you can use
to access an API.
So again, curl is really all
you need here for this.
You put the auth token in
an authorization header.
It says GoogleLogin
auth=token.
And then we hit the endpoint
for the contact's API.
And you get back a whole
bunch of JSON.
Let me see if I can clean out
the JSON with a little
function here that just sort
of filters stuff out.
Sorry.
OK.
Let me fetch the JSON here.
Is it in there?
Yup.
And so this is names.
It was just a little function
that filters--
goes to the JSON [INAUDIBLE].
So this is the complete address
book of this example
user that I started off with.
There's only two people
in there.
OK, so that's how ClientLogin
works.
But sometimes it doesn't.
There's a bunch of different use
cases in which ClientLogin
stops working.
Here's one of them: CAPTCHAs.
Sometimes the Google log in
system decides to throw a
CAPTCHA at the user
after they log in.
Maybe because the log in
looked suspicious.
We're suspecting that this might
be a bot that has maybe
stolen the password and
is not the real user.
And to try to distinguish
bots from users,
we throw out CAPTCHAs.
And there's actually a provision
in the ClientLogin
protocol to deal
with CAPTCHAs.
The server could signal that
a CAPTCHA solution
by the user is needed.
But many installed applications
either don't
implement that part of the
protocol or maybe implement it
incorrectly.
And as a result, what you have
is that a user, that if they
were to log in through the
web, they would log in.
They would see the CAPTCHA.
They would solve the CAPTCHA.
And they would be on
their merry way.
If they used one of those
applications that maybe
doesn't implement the CAPTCHA
part quite right, they are
actually stuck.
And they can't use
that application.
Another application is 2-Step
Verification, our 2 factor
auth solution that we launched
a couple months ago.
And while I said there was a
provision in the protocol for
CAPTCHAs, there is actually no
programmatic equivalent for
2-Step Verification.
So if you're logging into Google
on the website, you
would type username
and password.
And then you would see as the
next page, a page that asks
you for your one
time password.
And you would enter that.
And then you would be logged in
to your application or into
Google in general.
There's no equivalent of this
on the programmatic side, on
the ClientLogin endpoint.
So users that have signed up for
2-Step Verification cannot
use ClientLogin.
It doesn't work for them.
Here's another example:
OpenID.
Google is a relying party
to, at this point,
Yahoo, HotMail and AOL.
So users that have usernames
that are at yahoo.com, at
hotmail.com, and so forth, can
choose to turn on OpenID.
And what happens when one of
those users goes to the Google
log in page, they actually
get redirected
to Yahoo, for example.
And that's where they type
in their password.
Yahoo becomes what we call
an identity provider.
And then they get redirected
to Google, which plays the
role of the relying party.
And that's how you log in.
And again, if you have a user
like that, ClientLogin doesn't
work for them, because they
actually log in at Yahoo, and
not at Google.
And there's no programmatic
equivalent of this sort of log
in dance that OpenID uses.
Here's another example.
When we make acquisitions, like
YouTube or something like
that, we try to harmonize the
account system so that users
can log in to these new
services on the
Google log in page.
But sometimes there's sort of
some extra set up steps needed
to make sure that the user
can use this new service.
This happened, for example,
with YouTube.
And I think on the first
slide, I had a little
screenshot of a blog post
that shared the
same name as the session.
The YouTube team actually
blogged about this a couple
months ago.
So again, if you are logging in
on the web page, all that's
necessary is you answer a
couple more questions.
You get taken through additional
steps to sign in.
And you're good to go.
But if you were to connect to
ClientLogin, it would just
say, oh you can't log
in to the service.
This account is not in
the right state to
log in for this service.
And there's a bunch of
other examples where
this doesn't work.
I mentioned that Google is a
relying party to Yahoo, AOL
and HotMail, meaning that users
type their password
actually on those sites.
And then they get redirected
to Google and log in there.
We're also relying parties to
thousands and thousands of
other identity providers.
And this is in the Google Apps
world, in the enterprise world
and universities.
So there, an enterprise
or a university runs
their own log in server.
And users go there, log in
over there, type their
password over there.
And then they get redirected.
The protocol used there is
SAML, which is a little
different from OpenID.
But it's basically
the same idea.
And in this case, Google
doesn't even have the
passwords for those users,
so ClientLogin
couldn't possibly work.
A couple more examples: other
account wizards for, for
example, hijacked accounts.
If a user comes to Google and
they type their username and
password, and we have seen some
suspicious activity from
the account that might indicate,
again, that the
account maybe has been taken
over by a hacker, we may
suspend your account.
And instead of logging into
Google, we might say, hey,
answer a few more questions to
make sure that you're really
you and not the attacker that
highjacked your account.
And we call that a
recovery flow.
And again, that recovery
flow exists on the web.
No programmatic equivalent
for it on
the ClientLogin endpoint.
And we may decide in the future
to add more speed bumps
to the log in process.
We might say, well, if you're
logging in from an unusual IP
address for this account, or
from an unusual country from
this account, we might ask you a
few more questions before we
log you in to Google.
And we might actually change
and adjust what
those speed bumps are.
On the web this is really
easy to do.
We just change the web
pages we serve
after the log in page.
But in the programmatic world,
it's hard to do if you have
clients out there that don't
know that Google might be
throwing new speed bumps
at them during log in.
So all those things don't
work in ClientLogin.
So let me show you a demo of
what it looks like if you are
a user for which ClientLogin
doesn't work, but you can log
in on the web just fine.
So this is the Google
homepage.
Nobody's logged in right now.
I click on log in.
And I type a username that
ends in @yahoo.com.
This is one of those
OpenID users.
I don't have to type
in a password here.
If I say sign in, I get
redirected to Yahoo.
And I type my password
over here.
And now I'm logged
in to Google.
And I can use Google services
like Calendar and Picasa Web
and so forth.
OK.
And let me also show you--
I think, at this point--
I also want to show you what
happens if one of those users
tries to use ClientLogin.
Where's my cheat sheet?
Right here.
So if I take the same user,
and I try to hit the
ClientLogin endpoint, there's
the same account name here, I
just get an error back.
So I can log in on the web, but
I can't use ClientLogin.
All right, so we've seen a
bunch of examples where
ClientLogin fails.
So one of the sort of
workarounds that we have are
these things we call
application-specific passwords.
An application-specific
password is a
computer-generated password--
Google will generate
it for the user--
that works just like
a password.
In particular, you can't use
it on the ClientLogin
endpoint, but you can
have many of them.
They're labeled, the usernames,
when they ask
Google to create new ones.
And you can revoke them.
And those are useful for clients
that, for whatever
reason, can't really move away
from ClientLogin or other
protocols that use username
and password based
authentication.
So if you have an iMap client,
a Chat client, Talk client,
old Android devices that aren't
upgraded to the latest
version, Exchange clients, and
so forth, users can go to a
page that is linked from their
account overview page.
And they can ask Google to
generate one of those
application-specific
passwords for them.
And then you take that password,
and you type it in
the password field
of wherever the
application asks for a password.
So that sounds pretty good.
And it works with Legacy Clients
for many of the use
cases that I mentioned
earlier.
It works for users that have
signed up for 2-Step
Verification.
It works for OpenID users.
It could work for SAML users
if the enterprise admin has
switched it on.
But it does provide a pretty
bad user experience,
especially if it's
on some device.
If I want to configure the
exchange client on my iPhone
or something.
I probably would need to walk
up to my desktop and log in.
Go to the accounts page.
Go to the application-specific
passwords page.
Generate one of those
passwords.
Copy it over.
It's not that great.
And some of those use cases that
I talked about actually
still don't work even with
application-specific passwords.
If your account is suspended
because of some hijacking
suspicion, it's suspended.
And you have to go through
a web flow to
recover your password.
If it's one of those set up
situations where the account
is to be set up for YouTube or
something, you have to do that
on the web.
And the application specific
password just won't work.
So really the message is, when
ClientLogin fails, just stop
using ClientLogin.
Just don't do it.
And what you're supposed to
use instead is OAuth.
You may have heard that OAuth
is used, or probably know,
that OAuth is used a lot on the
web for connecting what
are also called relying parties
to service providers.
But it does also work for
installed applications.
And in fact, you don't even
need a web browser.
And I'll demo that
in a moment.
The idea is basically in OAuth
that instead of asking the
user to type in their username
and password directly into the
application, you use
a web browser.
You either launch the web
browser that's available on
the platform and ask the user to
complete the OAuth flow in
the browser.
Or you frame a WebView.
Those are available on all
platforms that I know of.
And you take the user
through the OAuth
flow in that WebView.
So in the browser the
user authenticates.
They may get redirected
to Yahoo or wherever.
They may be asked for
their second factor.
They may be asked
for a CAPTCHA.
They may be asked for all sorts
of things, but at some
point they're going
to be logged in.
And then they see this OAuth
approval screen, where they're
being told what kind of
privileges they're giving to
the installed application.
And then the user has a chance
to click on Allow Access.
And then the installed app ends
up with the OAuth token.
And those OAuth tokens are
really easy to use.
In OAuth 2.0, there's no more
signatures, no more crypto.
It's really all quite easy.
You stick them even in the same
place that ClientLogin
tokens used to go.
It's in the authorization
header.
Put the token right there.
You can use that to access
the Google API endpoints.
The only difference is that
ClientLogin tokens are
typically valid for about
two weeks or so.
OAuth tokens are valid
for about an hour.
So the two week time frame
typically means that when the
user interacts with your
application, they are done
interacting with
the application
before that token expires.
But the one hour expiration
time is not so sure.
So what do you need to do is
actually get a fresh OAuth
token when the OAuth token
stops working.
So what happens is that out of
the OAuth flow, you end up
with two tokens.
There's a refresh token that
doesn't expire-- it lasts
forever until the user
revokes it--
but cannot be used to access
API endpoints.
And then there's the
access token.
That's the thing that you take
to the OAuth endpoint in lieu
of the ClientLogin token.
And that's the thing that
expires after an hour.
So you need to write your code
such that if and when the
access token stops working, use
the refresh token to help
yourself to a new
access token.
And then you use that.
That's the only difference
really to ClientLogin.
And we have explained this in
our developer documentation.
If you search for OAuth 2.0
Google, you get to a page that
not only explains OAuth 2.0 in
general, but in particular
sort of customizes it for the
Google endpoints that we use
for OAuth 2.0.
The next two slides I have
just show you what the UI
typically looks like to the user
when an application uses
OAuth instead of ClientLogin.
So just as a reminder, on the
web if you have a relying
party, it's a web app that, say,
wants to get access to
some parts of the account that
the user has in Google, for
example, the address book.
Then what the relying party,
the web app, does, it says,
hey, I would really like to have
access to your address
book because I want to help you
manage your address book,
for example.
So click if you want to set
up that functionality.
The user clicks that.
They get redirected to Google.
They see a screen like this one
on the slide right now.
And then chances are, they are
already logged in because they
are Google users, and
they're logged in.
So they immediately see
this page right here.
And then they click
on Allow Access.
And then Google redirects back
to that relying party with the
OAuth token in the
redirect URL.
And that's how the relying
party ends up
with the OAuth token.
So what does it look like for
installed applications?
Here's a screenshot from an
app that we ship to our
enterprise customers.
And it runs on Windows.
And you can see it
really doesn't
look that much different.
On the left there is a native
window on Microsoft Windows,
where we explain to the user, if
you click here, we're going
to launch the browser to set
up this application.
And then the next thing the user
knows is that they are
staring at the normal browser,
at the normal OAuth window.
They're probably already
logged in.
So the next thing they see
is this approval screen.
They say Allow Access.
And then the native application
puts itself back
in the foreground and consumes
the OAuth token and takes it
from there.
So we wrote a little library
that we use internally to give
to our teams that write native
apps for Windows.
And we're in the process of
sort of cleaning it up a
little bit so that it's
suitable for public
consumption.
And so, hopefully we will be
able to release this open
source soon so you guys
have some help with
this kind of flow.
Next screenshot is from iOS.
There we actually have a library
available right now
that you can go and download.
A few slides from now,
I'll have a link that
points to the library.
It looks very similar.
I don't actually have
the shot of the app
launching the process.
I guess that would be sort of
the picture on the left of the
first phone here, but
similar idea.
You have an app that says, hey,
I'd like have access to
the address book.
Click here.
The user clicks there.
The next thing they see is
a WebView that takes them
through the OAuth flow.
So in this case, the
user has to log in.
And then after they log
in, they see the
OAuth approval page.
They say, Allow Access.
And then at that point, the
native app that is framing the
WebView, in this case, would
just close the WebView, would
help itself to the token and
would take it from there.
And I actually have a
demo of that that
uses a different library.
And on the iPad--
let me try and switch over and
show you how that works.
I brought my iPad.
Can you guys see that?
OK, great.
And I have an app on here that
you probably have heard about.
It's called Flipboard.
And Flipboard is an app that
sort of curates interesting
news items by connecting to
various accounts that I might
have, Facebook, Twitter,
and so forth.
And one of the accounts
you can add is a
Google Reader account.
So let me show you
how that works.
Add an account.
Google Reader.
And you can see it's
a WebView.
I'm being redirected
to Google.
Let's log in as of those users
for which ClientLogin doesn't
actually work.
[TYPING]
DIRK BALFANZ: So that redirects
me to Yahoo.
[TYPING]
DIRK BALFANZ: So I log in.
This is the approval screen.
These guys actually use
our OAuth 1.0 version
of the OAuth flow.
It's actually a little bit more
complicated because in
OAuth 1.0 there's still crypto
involved and so forth.
And the approval screen is
not quite as pretty.
But they have been having this
in place for awhile, since
before we launched OAuth 2.0.
So you guys probably want to
skip the whole OAuth 1.0
version of this and skip
straight to OAuth 2.0.
But the concept is really
exactly the same.
And I say, Grant Access here.
I get this new section in
Flipboard that is now
connected to my Google
Reader account.
And this worked for an account
for which ClientLogin is not
functional.
OK.
Let's get back to the slides.
So you might have noticed that
sometimes I used an external
browser when I showed
you the screenshots
of the Windows version.
There was an external browser
that was launched.
And sometimes we use WebViews.
On the iOS examples, both the
screenshots I had of Google's
own library, as well
as the Flipboard
example used WebViews.
So when should you use which?
External browser
versus WebView.
So I talked to a bunch
of developers at
Google about this.
And I got sort of sometimes
conflicting opinions on this.
And I tried to sort of
synthesize what I'd learned
into a set of three rules.
And I'm not sure this is
necessarily the final word on
this question.
I'm actually also curious if you
guys have tried this and
have come down one
way or another.
I'm interested in hearing you
guys' opinion on this.
But from the experience that
I have gained sort of
vicariously by talking
to developers.
This is the set of rules
that I came up with.
Rule #1.
Use an external browser like we
did in that screenshot from
the Windows application.
And the main advantage of using
an external browser is
that very, very likely, your
user is already logged in.
And they don't have to go
through the log in process:
typing their password.
Perhaps typing their OTP.
Perhaps when they get redirected
to Yahoo-- you
might have noticed I had to type
my username twice, once
into Google and once
onto Yahoo.
Because OpenID just isn't quite
convenient enough to
carry that over from one
side to the other.
So all those inconveniences
go away.
And the user is very likely
already logged in.
And they just have a one click
sort of approval experience at
this point.
And there's other
benefits too.
The password is not typed
directly into the application.
On the web we certainly do frown
upon it quite a bit, if
a web app is asking for your
Google username and password.
There it's considered
really bad practice.
For installed applications, this
is a little more common.
But really if you can avoid
it, it's just sort of nice
security hygiene
not to do that.
You could also imagine that
maybe you're in an enterprise
setting, and the users use some
sort of plug-in that uses
curb or also whatnot
to authenticate to
their log in server.
And those plug-ins tend to work
in stand-alone browsers,
but not in WebViews.
But more simply, if you just
think of password managers
that users use to autofill their
username and password,
those tend to work in
stand-alone browsers, but not
in WebViews.
Also imagine--
I talked earlier a little bit
about these speed bumps that
service providers sometimes
choose to throw into the log
in process when something
looks unusual.
And one of the things that
they might do is use
risk-based authentication, where
they look at certain
signals from the client.
And those might look different
if you're using a stand-alone
browser versus a WebView.
So if you choose to use a
WebView, you might make it
more likely for your users to go
through extra speed bumps.
So that's Rule #1.
Use an external browser.
Rule #2.
If that doesn't work,
use a WebView.
Why might it not work?
So for example in iOS, if you
launch an external browser,
your application gets
put to sleep.
And you don't really get
a guarantee that it's
ever woken up again.
In addition, there's no
back button on iOS.
If the user decides that, oh,
they didn't really want to go
there, they want to go back,
there's no good way to go back
to the native application.
Because your application is put
to sleep, the way it gets
woken up is by it registering
a URL and handing that URL.
But there's no guarantee that
there isn't some other app
that also registered the
same callback URL.
So, maybe some other app will
end up with your OAuth tokens.
So on iOS we, therefore, often
see solutions where they frame
the WebView and do it
inside a WebView.
And the price you pay is that
you're very likely, as the
user, to have to type in your
username and password because
the cookie jar is separate in
your application from the
cookie jar that the stand-alone
browser uses on
the platform.
And then Rule #3 is, sometimes
use a WebView anyway.
If you know that all those
advantages that I have listed
here under Rule #1 certainly
don't apply to your use case,
then it's OK to use a WebView.
One example of this is the
Android team does this in
their out of box experience.
When you buy a new phone
or tablet, and
you unpack the box.
You turn it on for
the first time.
One of the things you do there,
in the beginning, is
you provision your account.
You type a username
and password.
And at that point, you know that
the user has never used a
stand-alone browser on this
platform to log in.
There's no chance that any of
these advantages from Rule #1
could possibly kick in.
So you might as well use
a WebView in this case.
OK.
So this is sort of my
synthesized rules of when to
use a WebView and when to
use an embedded browser.
So the next two slides I have
are about sort of hands on, I
guess, recommendations
on how to do this.
How to implement this for
installed applications.
And first, I'm going to talk
about desktop platforms.
Windows/OS X.
And there we found a trick that
works sort of across a
variety of platforms, Linux/OS
X, Windows, pretty much the
same way on all the platforms.
And what we do is we scrape
the OAuth token from
a window title.
When you go and register your
native application with the
APIs console at Google, you
say, this is a native
application.
You get a client ID, client
secret, and you're being told
that your redirect URL is this
funny urn, this funny string
here, urn:ietf, blah,
blah, blah.
And then, so you put that
redirect URL, during the OAuth
flow, as your redirect URL.
And when we see that particular
redirect URL--
when the user sees the approvals
page and says, allow
access, instead of redirecting
back to some web app that sits
out there, which we don't have
in this case, we actually
redirect to a page at Google.
And what that page does, it puts
the OAuth token in the
title bar of the browser.
And then the native application,
the installed
application, can sit in the
background and just look
through all the windows that
are open on the desktop and
look for one of the windows that
has that string in the
title bar and scrape
it out of there.
Let me show you how
that works.
It takes a couple seconds
here for the screen
to come back up.
OK.
Where's my cheat sheet?
All right.
So I went and registered
with the APIs console.
I got a client ID and a client
secret, which you see here.
And then what I'll do next
is I'll just launch a web
browser, the web browser that
is native to the platform.
And I point it to the OAuth
2.0 endpoint that said,
accounts.google.
com/o/oauth2/auth.
I have to say what
my client ID is.
And I have to say what
my redirect URI is.
And it's this funny urn that
I mentioned a moment ago.
And I say what API I
want to access to.
And again, this is the
address book API.
So when I do that a browser
gets launched.
Again I'm already logged in,
which is very likely what's
happening to your users also.
And notice how I'm this user
that actually for which
ClientLogin doesn't work.
And when I say, Allow Access,
I am now at a page that has
basically the token
on the page.
But also it put it right here
in the title of the browser.
And you could write your
application in a way-- and
it's not showing me.
Anyway you can kind of see it.
You could write your application
in a way that
says, go through
the OAuth flow.
And when you get to the page
with the funny random stuff on
it, copy that and paste it
into the application.
Or you can write your
application such that it sits
in the background and looks
for this event to happen.
And just to show you how that
might work, I put a little bit
of code together here
that I prepared.
We're going to try and
scrape that token off
that title bar now.
I'm importing a bunch of this--
this is really all
pretty standard stuff.
The only thing I had to actually
go and download is
this app script, Python library,
which is just a
little bit of glue between
Python and AppleScript.
In the real world, you
probably wouldn't use
AppleScript.
But for this demo, it was pretty
easy to get going.
And then I'll make myself
just a few very
simple functions here.
The first one is a function
that, given one of those
AppleScript process objects
returns a list of all the
windows that belong
to that process.
And since that method might
throw, I'm catching that and
returning the empty list. So
it's safe to ask any process
object out there what its
list of windows are.
The next function here is given
a list of window title's
list of strings, it uses regular
expression matching to
see whether one of those looks
like it might have one of
those OAuth thingys in it.
And if so, extracts
it and returns it.
And then the last little
function here that I have is
the one that does
the actual work.
It uses this app script layer,
glue layer, to add to the
AppleScript engine to
connect to an app
called System Events.
And that app is one I can ask
for a list of all the running
processes on the system.
And then I ask each of these
processes for a list of
windows that belong
to the process.
Now I have a list of lists.
So I need to sort of
flatten that down.
That's what this line does.
Now I have a list of windows.
And then I extract the code
from that list of windows.
And so when I call that
function, hopefully we now
just screen scrape that code
off the title bar.
And that is actually not quite
our OAuth token yet.
This is just a one time use code
that you need to exchange
for your OAuth token.
And again, there's a little
method that--
function that shows you
how to do this.
Again we're using curl just to
hit this particular endpoint.
It's on accounts.google.
com/o/oauth2/token.
You put your client ID, your
client secret, and this token
we just scraped.
Where did I put it?
Right here.
And that returns a little bit
of JSON that has the refresh
token, this long-lived token,
the access token, which will
expire in an hour in it.
And we right now are
only interested
in the access token.
And so I'm peeling that
out of the response.
So let's call that method.
And there's our access token.
So you will probably do that
sitting in the background,
trying to scrape the token
off your browser.
So now let's see whether
we can hit an
API with that token.
And there you go.
Actually, let me see.
I have somewhere this thing that
filters through all the--
there you go.
So that's the address book of
this guy that couldn't use
ClientLogin.
We started off with an example
of an account that was using
ClientLogin.
So that's the trick that we
found to work pretty well
across different platforms.
Other practices that are
sometimes recommended are to run
a little web server inside
your installed application.
And then use as the redirect
URI something that says,
http://localhost:port.
We found that to be a
little unreliable,
especially on Windows.
There's often firewalls running
that at the very least
throw up some confusing screens
that users don't quite
know what to deal with that warn
them or perhaps sometimes
even forbid it altogether.
Another practice that is
sometimes recommended is to
use a custom scheme.
So as your redirect your URI
say, something, something,
fubar, colon, slash,
slash, redirect.
Or something like that.
And again, it's a little
unreliable to use this
practice because you don't know
that there isn't another
app that registered
the same redirect.
And now that app on the platform
gets the token
instead of your app.
OK.
So that's how to do it on
a desktop platform.
On iOS I mentioned earlier that
we have a library that
you can download.
There's the link where
you can go.
There's an OAuth 1.0 version
of this that comes actually
with our GData-Objective-C
Library.
But now we have an OAuth 2.0
version also available.
That stand-alone that's
available at this URL.
This library uses a WebView
unlike what I just demoed
where it popped up the
stand-alone browser.
And the trick it uses there to
get to the OAuth token is that
because the application hosts
the WebView, you can register
callbacks every time the URL
changes that the WebView is
asked to go visit.
So there you just--
you intercept at that moment
when after the user hits
Allow, the server serves a 3.02
to the redirect URI with
that token in the URL.
So at that point, the
application can just intercept
it, grab the token out of the
URL and take it from there.
I mentioned earlier that using a
WebView is sort of necessary
in iOS because of some
usability issues.
But you pay the price by
virtually guaranteeing that
the user has to type their
username and password.
So one of the projects I'm
currently working on is to try
to get rid of the necessity
for the user to type their
username and password.
And to use another installed
application on the phone, the
Google Mobile App, as sort of
an account manager, which
would store--
probably in Keychain or
something like that--
credentials for the user.
And so the user wouldn't
have to type them.
And so hopefully we'll
have something
like that in the future.
OK.
I haven't talked about
Android much today.
And the reason I haven't
talked about Android is
because on Android things work
a little differently.
I did mention how one of the
things you do when you use an
Android device in the very
beginning is just provision
Google accounts with it as part
of sort of the out of box
experience.
And then the phone stores not
the password, but sort of the
moral equivalent of a password
for the user.
And as a result, users are
really not used to
applications ever asking
them for their Google
username and password.
Instead what applications do on
Android is they can ask the
operating system, say, dear
operating system, I need an
auth token.
And then the operating
system just provides.
And what the operating system
provides, in this case, is a
ClientLogin token.
And the component that you ask
for the password is called the
AccountManager.
And today when the application
asks for such a token, the
thing that you get back is
a ClientLogin token.
And that's OK.
The problem with ClientLogin
tokens is not so much that you
can't use them with
Google APIs.
The problem with ClientLogin
is that you can't get the
ClientLogin tokens for a
large class of users.
But on Android, we made it so
that even for the kinds of
users for which ClientLogin per
se doesn't work, you can
still ask for ClientLogin
tokens.
And the OS will still give them
to you even for a 2-Step
Verification user, even
for an OpenID user.
So on Android the need to move
away from ClientLogin is a
little less pressing because
the OS can do magic
essentially and can give
you ClientLogin tokens.
Having said that, we are working
on OAuth 2.0 support
on Android, where the
application can say, hey OS, I
would like, not a ClientLogin
token, but an OAuth token.
And then the OS provides just
like it does today with the
ClientLogin tokens.
The screenshot I have on here
on the slide is actually for
the sort of the ClientLogin
version of
what this looks like.
And it typically happens
like this.
The application calls the
AccountManager, which is part
of the OS, and says, hey, give
me a list of all the Google
accounts that are provisioned
on the phone.
Then the AccountManager returns
the list. And the app,
then, displays that list for
the user to choose which
account they would like to use
at this point in time.
The user picks one.
And then the app goes back to
the AccountManager and says,
OK, now I would like a token for
this account that the user
just picked.
And at this point, contact
switches to the
AccountManager.
You can see that the look and
feel is quite different.
The AccountManager shows the
approval screen, and if and
when the user approves, hands
the token back to the
application, which then over
here, is happy and goes ahead
with using that token.
And in OAuth 2.0, this is likely
going to look very,
very similar.
The AccountManager just does
it for the application.
The application doesn't
have to worry
about any of this stuff.
OK.
Next think I want to talk about
is the device flow.
I mentioned very early on that
sometimes you don't even need
a web browser.
And this also works for devices
that have bad user
input methods or maybe no user
input methods available.
Think Picture Frame or
something like that.
So what happens there is that
OAuth provides what we call a
device flow, where the native
application that runs, let's
say on Picture Frame, contacts
Google and gets a user-- and
how do we call-- activation
code, an activation code and a
device code.
It displays the activation code
to the user and says,
hey, why don't you go to Google,
to this certain page
at Google, type in this
activation code.
And once you approve access, the
application that's running
on the device will have access
to whatever account the user
is using at Google.
Let me show you how
that works.
I also have a little code
snippet for that.
Device flow.
So the application starting on
the device would go to this
particular URL, currently
by running--
this is still on Sandbox, so
this isn't launched in
production, but it's available
for testing.
Contact the Sandbox at Google
where it gets back a little
bit of data that has the user
code in it that you would
display to the user and say,
hey, take this user code and
enter it at Google.
It has a device code, which
we're going to use to poll in
the background and ask
Google, hey, has the
user approved yet?
Has the user approved yet?
Has the user approved yet?
And it has also the URL that
the user should go to.
So let's pull out the device
code out of this because we
use it to poll.
And let's see whether the
user is approved yet.
Well, no they haven't.
But let's now assume
that we're maybe
on a different device.
I walk over to the PC in the
corner or on my tablet
or what have you.
And I go to this URL.
I enter the activation code
that the device hopefully
displays to the user.
Where am I?
Here.
And after I do that,
I see, again, the
OAuth approval screen.
I say, Allow Access.
And then you see why this
is not launched
in production yet.
It's still sort of
in testing mode.
But anyway, so now if we try
the same call again, we
actually do get back the result
from the server that
says, yes, approval
has been granted.
Here's your refresh token.
Here's your access token.
And we would take it from there
just like we did when we
scraped that code from
the window title.
So that's the device flow.
It's ready for testing.
There's a email address on the
screen that you can email if
you maybe want to get--
stay in touch with us and know
when this launch is for real.
Or just have questions
about it.
I'm not even sure
that we have the
documentation out publicly.
So if you email that, maybe
someone will just send you an
explanation on how to use it.
All right.
So I think I have maybe
two slides left or so.
OAuth for XMPP, IMAP/POP/SMTP.
So far I've talked about RESTful
APIs that use the
ClientLogin endpoint.
There are other protocols that
don't use ClientLogin, but
that have that same assumption
built into them that the user
authenticates with a username
and a password.
XMPP/IMAP.
In the protocol it says, this
is where the username goes,
this is where the
password goes.
And if you have a user account
that doesn't use a password to
authenticate to the server,
those things break.
We launched a while ago
support for OAuth 1.0
and IMAP and SMTP.
So let's say, an IMAP client
would do in this case, they
would take the user through
the OAuth flow, out of the
OAuth flow in the OAuth 1.0 case
pops an access token and
a token secret.
And then you use the secret to
create the signed assertion of
a bunch of different
parameters.
And you'd put that assertion
where the password normally
would go in XMPP or IMAP.
And we're currently working on
an OAuth 2.0 version of this,
which should be much easier.
You just take the token.
And you put it where the
password would go.
And it should be really easy.
We're also working on the same
thing for XMPP, where we're
skipping the OAuth 1.0
version of this.
We're going to go straight
to OAuth 2.0.
And there is a standardized
way of doing this that is
currently being hashed out in
a bunch of standardization
committees.
And when these guys get their
act together, I assume we'll
support whatever that standard
is that is agreed upon there.
OK.
I think this is pretty much
my last slide here.
One thing that-- a couple of
sort of thoughts in parting is
that installed applications
can't keep secrets.
When you go to the APIs console,
and you register your
app with Google, and you say,
this is an installed
application, you get a
client ID, and you
get a client secret.
That secret isn't
really secret.
Anyone who downloads your
application can reverse
engineer your application
and can find out
what that secret is.
So don't treat the secret
as if it were a secret.
We, certainly, on the
server side, don't.
We have other mechanisms in
place that sort of look out
for behavior that is either
malicious or benign just based
on the client ID.
Never, ever, ever use the same
Client ID and secret for a
native app and a web app.
For web apps, those secrets
actually can stay secret.
And we use them to authenticate,
to strongly
authenticate OAuth clients.
And the last thing I want to
mention that the scopes that
you use to identify the servers
you want to talk to in
OAuth are somewhat more--
there's more of them than we
used to have for ClientLogin.
Some of our teams now have sort
of fine-grained scope,
maybe a read-only scope and a
read/write scope and so forth.
So it's easier to ask just for
the privileges that you need
for your application instead
of asking for too much.
All right.
So to summarize, I started
off explaining a bunch of
different use cases in which
ClientLogin fails
for a class of users.
One of the classes of users
I mentioned was OpenID.
Today when a user that has an
@yahoo.com email address uses
that for the Google
account, they can
opt in to using OpenID.
We may, in the future, decide
that this is such a great
experience not to have to have
yet another password for
Google for the Yahoo users that
we just switch it on for
all of them.
And the same with
AOL and HotMail.
And if and when we decide to do
that, a large fraction of
Google users will just no
longer be able to use
ClientLogin.
That's something to keep
in mind if you're using
ClientLogin currently.
And I mentioned other use cases
in which ClientLogin
also breaks.
I talked a little bit about
application-specific
passwords, but they're really
just a stopgap.
And what you should be doing,
and what I spend most of my
time talking about was OAuth
2.0 and how to use it from
installed applications.
To learn more go to Ryan's
session tomorrow.
He'll talk a little bit more
about OpenID and OAuth.
And as I mentioned earlier,
search for OAuth 2.0 Google,
and you'll get the page where
we explain all of
this in some detail.
All right.
And with that, I'm ready
to take questions.
Again, the feedback URL and the
hashtags are on the slide.
If you have questions, please
use the microphone so they're
being recorded.
Anyone?
OK.
AUDIENCE: You recommended
that applications
don't store any secrets.
What if I'm building an
application where the user
would want the application
to remember the password?
You know, they install it.
They type in the username
and password once.
They click a check box, and
we never ask again.
DIRK BALFANZ: Right.
Well, I wouldn't say that
applications should never
store a secret.
And today many applications
store passwords.
And I think that has certain
advantages not to have to type
the password every time I want
to use the application.
One thing that is nice about
OAuth is that the secret--
this refresh token that
doesn't expire--
that secret that you could
choose to store--
I think that's fine--
it's actually finer
scoped than the
password would have been.
So the secrets that you end
up storing isn't quite as
powerful as the password
would have been.
And it's also revocable if
something goes wrong.
The user realizes, oh this
application is sort of abusive.
They can go and revoke
the token.
So I think it's fine to store a
refresh token, for example,
in the Keychain.
Use good tools that you have
on the platform, Data
Protection API, Keychain
and so forth.
But I think it's OK to put them
there, the refresh tokens.
AUDIENCE: OK.
DIRK BALFANZ: OK.
Everybody wants to go play with
their new Galaxy Tabs?
All right.
Well, thank you.
