the state of oauth2

Post on 06-May-2015

5.736 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides from my talk at State of the Auth in Portland

TRANSCRIPT

The State of OAuth 2Aaron Parecki • @aaronpk • aaronparecki.comState of the Auth • January 2013

aaron.pk/oauth2

Before OAuthApps 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

@aaronpk

aaron.pk/oauth2

Before OAuthServices 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

@aaronpk

aaron.pk/oauth2

Before OAuth 1.0Flickr: “FlickrAuth” frobs and tokens

Google: “AuthSub”

Facebook: requests signed with MD5 hashes

Yahoo: BBAuth (“Browser-Based Auth”)

@aaronpk

Some Current Implementers

The OAuth 2 Spechttp://oauth.net/2/

aaron.pk/oauth2

Definitions

Resource Owner: The User

Resource Server: The API

Authorization Server: Often the same as the API server

Client: The Third-Party Application

@aaronpk

aaron.pk/oauth2

Use CasesWeb-server apps

Browser-based apps

Username/password access

Application access

Mobile apps

@aaronpk

aaron.pk/oauth2

Use Cases – Grant TypesWeb-server apps – authorization_code

Browser-based apps – implicit

Username/password access – password

Application access – client_credentials

Mobile apps – implicit

@aaronpk

aaron.pk/oauth2

Web Server AppsAuthorization Code Grant

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

User visits the authorization page

https://facebook.com/dialog/oauth?response_type=code&client_id=28653682475872&redirect_uri=everydaycity.com&scope=email

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

Server exchanges auth code for an access token

Your server makes the following request

POST https://graph.facebook.com/oauth/access_token

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

@aaronpk

aaron.pk/oauth2

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"}

@aaronpk

aaron.pk/oauth2

Browser-Based Apps

Implicit Grant

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

User visits the authorization page

https://facebook.com/dialog/oauth?response_type=token&client_id=2865368247587&redirect_uri=everydaycity.com&scope=email

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

Browser-Based Apps

Use the “Implicit” grant type

No server-side code needed

Client secret not used

Browser makes API requests directly

@aaronpk

aaron.pk/oauth2

Username/Password

Password Grant

@aaronpk

aaron.pk/oauth2

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.

@aaronpk

aaron.pk/oauth2

Password Grant Type

Only appropriate for your service’s website or your service’s mobile apps.

aaron.pk/oauth2

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" }

@aaronpk

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

Application AccessClient Credentials Grant

@aaronpk

aaron.pk/oauth2

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" }

@aaronpk

aaron.pk/oauth2

Grant Type Summaryauthorization_code:

Web-server apps

implicit: Mobile and browser-based apps

password: Username/password access

client_credentials: Application access

@aaronpk

aaron.pk/oauth2

Grant Types & Response Typesauthorization_code:

response_type=code

implicit: response_type=token

@aaronpk

aaron.pk/oauth2

Grant Type Review

@aaronpk

aaron.pk/oauth2

Authorization CodeUser 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 tokenPOST /tokencode=xxxxxxx&grant_type=authorization_code

@aaronpk

aaron.pk/oauth2

ImplicitUser 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

@aaronpk

aaron.pk/oauth2

PasswordYour server exchanges username/password for access token

POST /tokenusername=xxxxxxx&password=yyyyyyy&grant_type=password

@aaronpk

aaron.pk/oauth2

Client CredentialsYour server exchanges client ID/secret for access token

POST /tokenclient_id=xxxxxxx&client_secret=yyyyyyy&grant_type=client_credentials

@aaronpk

aaron.pk/oauth2

Mobile AppsImplicit Grant

@aaronpk

aaron.pk/oauth2 @aaronpk

aaron.pk/oauth2 @aaronpk

aaron.pk/oauth2

Redirect back to your app

fb2865://authorize/#access_token=BAAEEmo2nocQBAFFOeRTd

@aaronpk

Facebook app redirects back to your app using a custom URI scheme.

Access token is included in the redirect, just like browser-based apps.

aaron.pk/oauth2 @aaronpk

aaron.pk/oauth2

Mobile Applications

Use the “Implicit” grant type

No server-side code needed

Client secret not used

Mobile app makes API requests directly

@aaronpk

aaron.pk/oauth2

Mobile ApplicationsExternal 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

@aaronpk

aaron.pk/oauth2

Accessing ResourcesSo you have an access token.

Now what?

@aaronpk

aaron.pk/oauth2

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=RsT5OjbzRn430zqMLgV3Ia

@aaronpk

aaron.pk/oauth2

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!

@aaronpk

aaron.pk/oauth2

Get a new access token using a refresh tokenYour 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" }

@aaronpk

aaron.pk/oauth2

ScopeLimiting access to resouces

@aaronpk

aaron.pk/oauth2

Limiting Access to Third Parties

@aaronpk

aaron.pk/oauth2

Limiting Access to Third Parties

@aaronpk

aaron.pk/oauth2

Limiting Access to Third Parties

@aaronpk

aaron.pk/oauth2

OAuth 2 scopeCreated 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.

@aaronpk

aaron.pk/oauth2

OAuth 2 scope on Facebookhttps://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream

@aaronpk

aaron.pk/oauth2

OAuth 2 scope on Facebook

@aaronpk

aaron.pk/oauth2

OAuth 2 scope on Githubhttps://github.com/login/oauth/authorize? client_id=...&scope=user,public_repo

@aaronpk

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

OAuth 2 scopeThe 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

@aaronpk

aaron.pk/oauth2

So what’s wrong?

@aaronpk

aaron.pk/oauth2

What I just described is one possible

implementation of an OAuth 2 server

@aaronpk

aaron.pk/oauth2

IndecisionNo 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

@aaronpk

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

@aaronpkaaron.pk/oauth2 Source: http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/

aaron.pk/oauth2

The result: the OAuth RFC is a

framework, not a protocol

@aaronpk

aaron.pk/oauth2 @aaronpk

aaron.pk/oauth2 @aaronpk

OAuth 2 ServersImplementing an OAuth 2

Server

@aaronpkaaron.pk/oauth2

Implementing an OAuth 2 Server

aaron.pk/oauth2

Implementing an OAuth 2 ServerFind 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.

@aaronpk

aaron.pk/oauth2

Implementing an OAuth 2 ServerChoose which grant types you want to support

Authorization Code – for traditional web apps Implicit – for browser-based apps and mobile appsPassword – for your own website or mobile appsClient 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@aaronpk

Access TokensBearer tokens vs

MAC tokens

@aaronpkaaron.pk/oauth2

Bearer Tokens

GET /1/profile HTTP/1.1 Host: api.example.com Authorization: Bearer B2mpLsHWhuVFw3YeLFW3f2

@aaronpk

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

aaron.pk/oauth2

Dangers of Using Bearer TokensRequests 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.

@aaronpk

aaron.pk/oauth2

Security Recommendationsfor Clients Using Bearer TokensSafeguard 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

@aaronpk

MAC TokensGET /1/profile HTTP/1.1 Host: api.example.com Authorization: MAC id="jd93dh9dh39D", nonce="273156:di3hvdf8”, mac="W7bdMZbv9UWOTadASIQHagZyirA="

@aaronpk

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.

aaron.pk/oauth2

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

@aaronpk

aaron.pk/oauth2

Scalability ConcernsToken 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

@aaronpk

aaron.pk/oauth2

Self-Encoded TokensThe 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

@aaronpk

aaron.pk/oauth2

DB Token Lookups vs Self-Encoded TokensToken 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

@aaronpk

aaron.pk/oauth2

JSON Web Signaturehttp://tools.ietf.org/html/draft-ietf-jose-json-web-signature-07

@aaronpk

{ "typ":"JWT", "alg":"HS256”}

{ "usr":"username", "exp":1300819380, "scope":["profile"]}

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9

Data Base64 Encoded

eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ

Signature dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOE

aaron.pk/oauth2

JSON Web Signature

@aaronpk

Complete Token Example:

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

Header, data, signature are base64 encoded and concatenated with a “period” between each.

aaron.pk/oauth2 @aaronpk

oauth.net

aaron.pk/oauth2

oauth.net Websitehttp://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

@aaronpk

aaron.pk/oauth2 @aaronpk

github.com/aaronpk/oauth.net

Thanks.

Aaron Parecki

@aaronpk

aaronparecki.com

github.com/aaronpk

top related