securing apis with oauth 2.0
TRANSCRIPT
Kai Hofstetter
Senior Software Developer at 1&1
@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
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
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
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…
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
• 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