58
Securing APIs with OAuth 2.0 Kai Hofstetter

Securing APIs with OAuth 2.0

Embed Size (px)

Citation preview

Securing APIs

with OAuth 2.0Kai Hofstetter

Kai Hofstetter

Senior Software Developer at 1&1

[email protected]

@KaiHofstetter

https://github.com/KaiHofstetter

There is a Need for Securing APIs!

0

2.000

4.000

6.000

8.000

10.000

Growth in Web APIs since 2005

API Count

Source: http://www.slideshare.net/programmableweb/web-api-growthsince2005

Authenticating is Good Thing

• Make sure you know who is calling you

• Split access rights to API across different clients

Mobile READ

Control Panel FULL

Operating and Support SPECIAL BULK

• Be able to cut-off or throttle misbehaving clients

without affecting all others

Meet the OAuth 2.0 Players

Meet the OAuth 2.0 Players

The Resource Owner

Meet the OAuth 2.0 Players

The Resource Server

Meet the OAuth 2.0 Players

The Client

Meet the OAuth 2.0 Players

The Authorization Server

Client Credentials Grant

• There is no direct association to a given user

...some configuration data

• Information is public

…tweets on Twitter

• User is already authenticated e.g. using some kind of session

token

• Twitter Search API

Examples

Client Credentials Grant

Request an AccessToken

POST .../token

Authorization: Basic czZCaGRSa3F0...

grant_type=client_credentials

Client AuthS

ResourceS

Client Credentials Grant

Request an AccessToken

Issue an AccessToken

200 OK

{

"access_token":"2YotnFZcMWpAA",

"token_type":"Bearer",

"expires_in":3600

}

Client AuthS

ResourceS

Client Credentials Grant

Request an AccessToken

Issue an AccessToken

Use AccessToken in API call Validate AccessToken

API Call ...

Authorization: Bearer YotnFZFEjr1zCsicMWpAA

Client AuthS

ResourceS

Client Credentials Grant

Request an AccessToken

Issue an AccessToken

Use AccessToken in API call Validate AccessToken

Positive responseData

API Call ...

Authorization: Bearer YotnFZFEjr1zCsicMWpAA

Client AuthS

ResourceS

The Client Credentials Grant

• Easy to implement as a client

• A trivial HTTP POST with credentials will return an

AccessToken in JSON

• Just for confidential clients, which can keep a secret

• Warning about the Bearer token:

Whoever has that AccessToken is authorized, so don‘t go

about passing it along to other apps!

• No magical signatures, certificates or encryption...

...though HTTPS is an absolute MUST

Access Request Scope

• Principle of least privilege:

The less access rights the better!

• Request minimum needed rights

• Permit only minimum needed rights

Access Token Scope

POST .../token

Authorization: Basic czZCaGRSa3F0...

grant_type=client_credentials&scope=read_calendar

200 OK

{

"access_token":"2YotnFZcMWpAA",

"token_type":"Bearer",

"expires_in":3600,

"scope":"read_calendar"

}

Client Access Token Request

Authorization Server Response

Access Token Scope

• Defines the access rights of the client

• Scopes are case-sensitive and space-delimited

• Client can optionally add scopes to the access token

request.

• Authorization Service determines the actual access

token scope

It‘s Time for a Demo!

https://flic.kr/p/jAZdRp

The Foosball Booking Service

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Icons: https://www.iconfinder.com/iconsets/social-media-8

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Hi Google Calendar!

I am Bob with the

password “foobar”

Authenticating the User

is Good Thing

…but sharing credentials is the root of all evil

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Hi Google Calendar!

I am Bob with the

password “foobar”

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Hi! I’d like to add

an entry to the

Calendar of Bob.

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Hi! I’d like to add

an entry to the

Calendar of Bob.

Bob, should the

App be allowed to

do that?

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Hi! I’d like to add

an entry to the

Calendar of Bob.

Bob, should the

App be allowed to

do that?

Sure!

Authenticating the User

is Good Thing

Scenario: A ‘Booking Service’ wants to add

dates to your Google Calendar, as reminders

Hi! I’d like to add

an entry to the

Calendar of Bob.

Bob, should the

App be allowed to

do that?

Sure!

App, use this token

to prove that Bob

granted you access

The Authorization Code Grant

• Application requests an AccessToken

• Users browser gets redirected to grant access

• An AuthorizationCode is returned

• Application exchanges the AuthorizationCode for a

real AccessToken

• Client passes the AccessToken as part of the API

call

Authorization Code Grant

Backend Authorization

Server

Resource

Server

• The application redirects the browser of the user to

the Authorization Server.

• The Authorization Server authenticates the user and

asks him to approve the request.

• Upon successful approval, the Authorization Server

sends an AuthorizationCode as part of the redirect to

the app backend

Backend Authorization

Server

Resource

Server

Authorization Code Grant

• The app backend then exchanges the

AuthorizationCode for a regular AccessToken

Backend Authorization

Server

Resource

Server

Authorization Code Grant

• The app backend then uses the AccessToken to call

the Resource Server

Backend Authorization

Server

Resource

Server

Authorization Code Grant

Looks Complicated? Not Really...

Step 1:

Requests a token by redirecting the browser to the

Authorization Server

GET /authorize?response_type=code&client_id=s6BhdRkqt3&

state=xyz&redirect_uri=https%3A%2F%2Fclient...

3 Simple Steps for the Client

Looks Complicated? Not Really...

https://client...?code=SplxlO...&state=xyz

3 Simple Steps for the Client

Step 2:

The AuthorizationCode is sent to the redirect_uri as

query parameter…

Looks Complicated? Not Really...

POST .../token

Authorization: Basic czZCaGRSa3F0...

grant_type=authorization_code&code=SplxlO...&

redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

3 Simple Steps for the Client

Step 3:

Exchanges the AuthorizationCode for an AccessToken

Demo!

The Authorization Code Grant

• Requesting application never sees the credentials

• Application gets access to the users data without sharing the

password

• The browser never has the AccessToken, only a harmless

AuthorizationCode

• The application has to provide credentials when exchanging

the AuthorizationCode for an AccessToken

…making a lost AuthorizationCode useless!

The Story of Refresh Tokens

The RefreshTokens are issued along side of AccessTokens:

{

"access_token":"2Yotn…AA",

"token_type":"Bearer",

"expires_in":3600,

"refresh_token":"tGzv3JOkF0…"

}

RefreshTokens can be used to request a new AccessToken:

POST .../token

Authorization: Basic czZCaGRSa3F0...

grant_type=refresh_token&refresh_token=tGzv3JOkF0...

Refresh Tokens

• …are used to request new AccessTokens once these have

expired

• …are a MUST for long-living access rights, e.g. when the

user should not be bothered with constant re-authentication

• …are credentials which should just be shared between the

client and the authorization server

Long Living AccessTokens

are a Bad Idea

Security

• The longer the AccessToken lives, the longer it can be misused

• A short-lived AccessToken forces the application to re-authenticate

Performance

• Short lived AccessTokens are cached by the Authorization Server

• Costly re-authentication is only done when generating a new token

e.g. using the RefreshToken

Implicit Grant

• Clients, which can not keep a secret

• Public client applications

e.g. JavaScript browser applications

Implicit Grant

• Application requests an AccessToken

• Users browser gets redirected to grant access

• The AccessToken is returned

Implicit Grant

Authorization

Server

Resource

Server

• The application redirects the browser of the user to

the Authorization Server.

• The Authorization Server authenticates the user and

asks him to approve the request.

• Upon successful approval, the Authorization Server

sends an AccessToken as part of the redirect url.

Authorization

Server

Resource

Server

Implicit Grant

• The browser uses the AccessToken to call the

Resource Server

Authorization

Server

Resource

Server

Implicit Grant

Implicit Grant

Request a token by redirecting the browser to the

Authorization Server

GET /authorize?response_type=token&client_id=s6BhdRkqt3&

state=xyz&redirect_uri=https%3A%2F%2Fclient...

The AccessToken is sent to the redirect_uri as

fragment identifier…

https://client...#access_token=2Yotn&state=xyz&token_type=bearer

&expires_in=3600…

Demo!

Implicit Grant

• Client doesn’t have a secret and is not authenticated

• Only the user is authenticated

• User has to ensure that the client is trustable

• Only short living access tokens!

• No refresh tokens!

User has to re-authenticate if the access token has expired!

• Clients from the same vendor as the application

• Clients which might not support redirects

• Clients which are highly trusted to receive the user

credentials

e.g. Mobile app of the same vendor

Resource Owner Password Credentials Grant

Resource Owner Password Credentials Grant

Request an AccessToken

POST .../token

Authorization: Basic czZCaGRSa3F0...

grant_type=password&username=john…&

password=A3…

Client AuthS

Resource Owner Password Credentials Grant

Request an AccessToken

Issue an AccessToken

200 OK

{

"access_token":"2YotnFZcMWpAA",

"token_type":"Bearer",

"expires_in":3600,

"refresh_token":"tGzv3JOkF0X…"

}

Client AuthS

Demo!

• No need to store user credentials

• No redirect for user authentication needed

No user experience break by opening a browser

• User credentials are shared!

Client must be highly trustable!

Resource Owner Password Credentials Grant

• Client access token revocation request:

• Later added spec

• Rarely implemented in the wild.

Access Token Revocation

POST .../revoke

Authorization: Basic czZCaGRSa3F0...

token=45ghiuk…&token_type_hint=refresh_token

Summary

OAuth 2.0 is

• a framework, not a strict protocol

• extensible with own token types, grants…

• easy to implement

• no magic encryption or signatures

• HTTPS is a must

Links

• OAuth 2.0 Spechttps://tools.ietf.org/html/rfc6749

• Oauth 2.0 Bearer Token Spechttps://tools.ietf.org/html/rfc6750

• OAuth 2.0 Token Revocation Spechttps://tools.ietf.org/html/rfc7009

• Spring Security OAuthhttp://projects.spring.io/spring-security-oauth/

• Sampleshttps://github.com/KaiHofstetter