Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
The State of OAuth2
1. The State of
OAuth 2
Aaron Parecki • @aaronpk • aaronparecki.com
State of the Auth • January 2013
2. Before OAuth
Apps stored the user’s password
Apps got complete access to a user’s account
Users couldn’t revoke access to an app except by
changing their password
Compromised apps exposed the user’s password
aaron.pk/oauth2 @aaronpk
3. Before OAuth
Services recognized the problems with password
authentication
Many services implemented things similar to OAuth
1.0
Each implementation was slightly different, certainly
not compatible with each other
aaron.pk/oauth2 @aaronpk
4. Before OAuth 1.0
Flickr: “FlickrAuth” frobs and tokens
Google: “AuthSub”
Facebook: requests signed with MD5 hashes
Yahoo: BBAuth (“Browser-Based Auth”)
aaron.pk/oauth2 @aaronpk
7. Definitions
Resource Owner: The User
Resource Server: The API
Authorization Server: Often the same
as the API server
Client: The Third-Party Application
aaron.pk/oauth2 @aaronpk
10. Web Server Apps
Authorization Code Grant
aaron.pk/oauth2 @aaronpk
11. Create a “Log In” link
Link to:
https://facebook.com/dialog/oauth?response_
type=code&client_id=YOUR_CLIENT_ID&redirect
_uri=REDIRECT_URI&scope=email
aaron.pk/oauth2 @aaronpk
12. Create a “Log In” link
Link to:
https://facebook.com/dialog/oauth?response_
type=code&client_id=YOUR_CLIENT_ID&redirect
_uri=REDIRECT_URI&scope=email
aaron.pk/oauth2 @aaronpk
13. Create a “Log In” link
Link to:
https://facebook.com/dialog/oauth?response_
type=code&client_id=YOUR_CLIENT_ID&redirect
_uri=REDIRECT_URI&scope=email
aaron.pk/oauth2 @aaronpk
14. Create a “Log In” link
Link to:
https://facebook.com/dialog/oauth?response_
type=code&client_id=YOUR_CLIENT_ID&redirect
_uri=REDIRECT_URI&scope=email
aaron.pk/oauth2 @aaronpk
15. Create a “Log In” link
Link to:
https://facebook.com/dialog/oauth?response_
type=code&client_id=YOUR_CLIENT_ID&redirect
_uri=REDIRECT_URI&scope=email
aaron.pk/oauth2 @aaronpk
16. User visits the authorization page
https://facebook.com/dialog/oauth?response_
type=code&client_id=28653682475872&redirect
_uri=everydaycity.com&scope=email
aaron.pk/oauth2 @aaronpk
17. On success, user is redirected back
to your site with auth code
https://example.com/auth?code=AUTH_CODE_HERE
On error, user is redirected back to
your site with error code
https://example.com/auth?error=access_denied
aaron.pk/oauth2 @aaronpk
18. Server exchanges auth code
for an access token
Your server makes the following request
POST
https://graph.facebook.com/oauth/access_to
ken
Post Body:
grant_type=authorization_code
&code=CODE_FROM_QUERY_STRING
&redirect_uri=REDIRECT_URI
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
aaron.pk/oauth2 @aaronpk
19. Server exchanges auth code
for an access token
Your server gets a response like the following
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"e1qoXg7Ik2RRua48lXIV"
}
or if there was an error
{
"error":"invalid_request"
}
aaron.pk/oauth2 @aaronpk
21. Create a “Log In” link
Link to:
https://facebook.com/dialog/oauth?response_
type=token&client_id=CLIENT_ID
&redirect_uri=REDIRECT_URI&scope=email
aaron.pk/oauth2 @aaronpk
22. User visits the authorization page
https://facebook.com/dialog/oauth?response_
type=token&client_id=2865368247587&redirect
_uri=everydaycity.com&scope=email
aaron.pk/oauth2 @aaronpk
23. On success, user is redirected back
to your site with the access token in
the fragment
https://example.com/auth#token=ACCESS_TOKEN
On error, user is redirected back to
your site with error code
https://example.com/auth#error=access_denied
aaron.pk/oauth2 @aaronpk
24. Browser-Based Apps
Use the “Implicit” grant type
No server-side code needed
Client secret not used
Browser makes API requests directly
aaron.pk/oauth2 @aaronpk
26. Password Grant
Password grant is only appropriate for trusted
clients, most likely first-party apps only.
If you build your own website as a client of your
API, then this is a great way to handle logging
in.
aaron.pk/oauth2 @aaronpk
27. Password Grant Type
Only appropriate for your
service’s website or your
service’s mobile apps.
aaron.pk/oauth2
28. Password Grant
POST https://api.example.com/oauth/token
Post Body:
grant_type=password
&username=USERNAME
&password=PASSWORD
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Response:
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"e1qoXg7Ik2RRua48lXIV"
}
aaron.pk/oauth2 @aaronpk
29. Password Grant
User exchanges username and password for a token
No server-side code needed
Client secret only used from confidential clients
(Don’t send client secret from a mobile app!)
Useful for developing a first-party login system
aaron.pk/oauth2 @aaronpk
31. Client Credentials Grant
POST https://api.example.com/1/oauth/token
Post Body:
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Response:
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"e1qoXg7Ik2RRua48lXIV"
}
aaron.pk/oauth2 @aaronpk
32. Grant Type Summary
authorization_code:
Web-server apps
implicit:
Mobile and browser-based apps
password:
Username/password access
client_credentials:
Application access
aaron.pk/oauth2 @aaronpk
35. Authorization Code
User visits auth page
response_type=code
User is redirected to your site with auth code
http://example.com/?code=xxxxxxx
Your server exchanges auth code for access token
POST /token
code=xxxxxxx&grant_type=authorization_code
aaron.pk/oauth2 @aaronpk
36. Implicit
User visits auth page
response_type=token
User is redirected to your site with access token
http://example.com/#token=xxxxxxx
Token is only available to the browser since it’s in the fragment
aaron.pk/oauth2 @aaronpk
37. Password
Your server exchanges username/password for access token
POST /token
username=xxxxxxx&password=yyyyyyy&
grant_type=password
aaron.pk/oauth2 @aaronpk
38. Client Credentials
Your server exchanges client ID/secret for access token
POST /token
client_id=xxxxxxx&client_secret=yyyyyyy&
grant_type=client_credentials
aaron.pk/oauth2 @aaronpk
39. Mobile Apps
Implicit Grant
aaron.pk/oauth2 @aaronpk
42. Redirect back to your app
Facebook app redirects back to your app using
a custom URI scheme.
Access token is included in the redirect, just like
browser-based apps.
fb2865://authorize/#access_token=BAAEEmo2nocQBAFFOeRTd
aaron.pk/oauth2 @aaronpk
44. Mobile Applications
Use the “Implicit” grant type
No server-side code needed
Client secret not used
Mobile app makes API requests directly
aaron.pk/oauth2 @aaronpk
45. Mobile Applications
External user agents are best
Use the service’s primary app for authentication, like
Facebook – provides a superior user experience
Or open native Safari on iPhone, still better than using an
embedded browser
Auth code or implicit grant type
In both cases, the client secret should never be used,
since it is possible to decompile the app which would
reveal the secret
aaron.pk/oauth2 @aaronpk
46. Accessing Resources
So you have an access token. Now
what?
aaron.pk/oauth2 @aaronpk
47. Use the access token to make
requests
Now you can make requests using the access token.
GET https://api.example.com/me
Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia
Access token can be in an HTTP header or a query string
parameter
https://api.example.com/me?access_token=RsT5Ojb
zRn430zqMLgV3Ia
aaron.pk/oauth2 @aaronpk
48. Eventually the access token
may expire
When you make a request with an expired token, you will
get this response
{
"error":"expired_token"
}
Now you need to get a new access token!
aaron.pk/oauth2 @aaronpk
49. Get a new access token using
a refresh token
Your server makes the following request
POST https://api.example.com/oauth/token
grant_type=refresh_token
&reresh_token=e1qoXg7Ik2RRua48lXIV
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Your server gets a similar response as the original call to
oauth/token with new tokens.
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"expires_in":3600,
"refresh_token":"e1qoXg7Ik2RRua48lXIV"
}
aaron.pk/oauth2 @aaronpk
50. Scope
Limiting access to resouces
aaron.pk/oauth2 @aaronpk
54. OAuth 2 scope
Created to limit access to the third party.
The scope of the access request expressed as a list of space-delimited
strings.
In practice, many people use comma-separators instead.
The spec does not define any values, it’s left up to the implementor.
If the value contains multiple strings, their order does not matter, and
each string adds an additional access range to the requested scope.
aaron.pk/oauth2 @aaronpk
57. OAuth 2 scope on Github
https://github.com/login/oauth/authorize?
client_id=...&scope=user,public_repo
user
• Read/write access to profile info only.
public_repo
• Read/write access to public repos and organizations.
repo
• Read/write access to public and private repos and organizations.
delete_repo
• Delete access to adminable repositories.
gist
• write access to gists.
aaron.pk/oauth2 @aaronpk
58. OAuth 2 scope
The challenge is displaying this to the user succinctly in a way they will
actually understand
If you over-complicate it for users, they will just click “ok” until the app
works, and ignore any warnings
Read vs write is a good start for basic services
aaron.pk/oauth2 @aaronpk
60. What I just described is
one possible
implementation
of an OAuth 2 server
aaron.pk/oauth2 @aaronpk
61. Indecision
No required token type
No agreement on the goals of an HMAC-enabled
token type
No requirement to implement token expiration
No guidance on token string size, or any value for that
matter
No strict requirement for registration
Loose client type definition
aaron.pk/oauth2 @aaronpk
62. Indecision (continued)
Lack of clear client security properties
No required grant types
No guidance on the suitability or applicability of grant
types
No useful support for native applications (but lots of lip
service)
No required client authentication method
No limits on extensions
aaron.pk/oauth2 Source: http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ @aaronpk
63. The result:
the OAuth RFC is a
framework, not a protocol
aaron.pk/oauth2 @aaronpk
68. Implementing an OAuth 2
Server
Find a server library already written:
A short list available here: http://oauth.net/2/
Read the OAuth spec in its entirety
Study other implementations like Google
Make decisions based on the security requirements of your
application. In many cases the spec says SHOULD and leaves the
choice up to the implementer.
Understand the security implications of the implementation choices
you make.
aaron.pk/oauth2 @aaronpk
69. Implementing an OAuth 2
Server
Choose which grant types you want to support
Authorization Code – for traditional web apps
Implicit – for browser-based apps and mobile apps
Password – for your own website or mobile apps
Client Credentials – if applications can access resources on their own
Choose whether to support Bearer tokens, MAC or both
If using Bearer tokens, choose whether to use a DB lookup or
use self-container tokens
Define appropriate scopes for your service
aaron.pk/oauth2 @aaronpk
70. Access Tokens
Bearer tokens vs
MAC tokens
aaron.pk/oauth2 @aaronpk
71. Bearer Tokens
GET /1/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer B2mpLsHWhuVFw3YeLFW3f2
Bearer tokens are a cryptography-free way to access protected
resources.
Relies on the security present in the HTTPS connection, since the
request itself is not signed.
Application developers do not need to do any cryptography, they just
pass the token string in the header.
aaron.pk/oauth2 @aaronpk
72. Dangers of Using Bearer Tokens
Requests are not signed, so are vulnerable to reply
attacks if someone intercepts the token.
When storing tokens in cookies, must ensure the
cookie is only sent via an https connection.
If a token is leaked, there is a large potential for
abuse.
aaron.pk/oauth2 @aaronpk
73. Security Recommendations
for Clients Using Bearer Tokens
Safeguard bearer tokens
Validate SSL certificates
Always use https
Don’t store bearer tokens in plaintext cookies
Issue short-lived bearer tokens
Don’t pass bearer tokens in page URLs
aaron.pk/oauth2 @aaronpk
74. MAC Tokens
GET /1/profile HTTP/1.1
Host: api.example.com
Authorization: MAC id="jd93dh9dh39D",
nonce="273156:di3hvdf8”,
mac="W7bdMZbv9UWOTadASIQHagZyirA="
MAC tokens provide a way to make authenticated requests with
cryptographic verification of the request.
Similar to the original OAuth 1.0 method of using signatures.
Application developers must sign each request, preventing forgery
and replay even when requests are sent in the clear.
@aaronpk
75. Bearer, MAC, or Both?
Should you support Bearer tokens, MAC tokens or
both?
MAC tokens are technically safer and more secure
Application developers will prefer working with Bearer
tokens since it is easier
aaron.pk/oauth2 @aaronpk
76. Scalability Concerns
Token lookups from a database can become a
bottleneck.
Can be addressed by heavy use of caching to avoid
DB lookups
Can be addressed by a good master/slave database
architecture
An alternative is to use “self-encoded” tokens where
all the needed information is contained within the
token string itself, avoiding the need to do a database
lookup
aaron.pk/oauth2 @aaronpk
77. Self-Encoded Tokens
The token is a string which is encrypted or signed
The string contains all necessary information to avoid
doing a database lookup
These tokens cannot be revoked, so must expire
frequently (requires heavy use of the
refresh_token grant type)
Can be implemented with either Bearer or MAC
tokens
aaron.pk/oauth2 @aaronpk
78. DB Token Lookups vs
Self-Encoded Tokens
Token table probably looks like
Token
User ID
Expiration Date
Scopes
Instead, encode that into a JSON payload which *is*
the token:
{“user_id”:1000,”exp”:1355429676,”scopes”:[“email
”,”payment”]}
See JSON Web Signature for example of signing this
token
aaron.pk/oauth2 @aaronpk
80. JSON Web Signature
Complete Token Example:
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3M
iOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA
6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ
4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Header, data, signature are base64 encoded and
concatenated with a “period” between each.
aaron.pk/oauth2 @aaronpk
82. oauth.net Website
http://oauth.net
Source code available on Github
github.com/aaronpk/oauth.net
Please feel free to contribute to the website
Contribute new lists of libraries, or help update information
aaron.pk/oauth2 @aaronpk