- Is an authorization framework
- Enables a third-party app to obtain limited access to an HTTP service
- on behalf of a resource owner by orchestrating an approval interaction
- or on its own behalf
- Is designed only for
HTTP
- Supports several flows appropriate for different topologies/scenarios
- Developed by the IETF
- Next generation of OAuth (now known as OAuth 1)
- Unlike its predecessor OAuth 2.0 relies completely on TLS
- No signature/encryption
- Except for JWT Bearer Tokens
- No backward compatibility
- 31 drafts between 2010 and 2012
- Finalized in RFC 6749
- Widely accepted and used by the community
- Open ID Connect
- An identity layer on top of OAuth 2.0
- Assisted Token Flow
- Designed to make the life easier for single-page apps
- Could be used in normal web apps as well
- Still in draft
- Not implemented yet by providers and clients
- Device Flow
- Still in draft but widely used
- For devices and embedded systems without a browser
- Bearer Token Usage RFC 6750
- This Python library implements most of these specs and is a good starting point
-
Client provides user's credentials to access protected resources
-
Several issues
- Clients has to store the password, typically in plain-text
- Servers need to support password authentication
- Usually client gains an all or nothing access
- Any intention to revoke access from one client revokes all clients
- Only feasible way is changing the password
- Compromise of any third-party client results in compromise of users' password
- A new authorization layer
- Separating the role of client from that of resource owner
- Access token
- String denoting a specific
- scope
- lifetime
- other access attributes
- Issued to clients by the authorization server
- with approval of the resource owner
- String denoting a specific
- An end-user grants a printing service access to her protected photos stored at a photo-sharing service
- Without sharing her username and password with the printing service.
- Instead, she authenticates directly with a server trusted by the photo-sharing service
- That server issues the printing service delegation-specific credentials.
-
Resource Owner
: End-User -
Client
: Printing Service -
Authorization Server
: Trusted Server -
Resource Server
: Photo-Sharing Service -
Access Token
: Delegation-specific credentials
Resource Owner
- An entity capable of granting access to a protected resource.
Client
- An app making protected resource requests on behalf of the resource owner and with its authorization
- Just a term, does not imply the nature of the app
Authorization Server
- The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization
Resource Server
- The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens
- Before getting into details of each role let us look at the abstract flow
-
The client requests authorization from the resource owner.
-
The authorization request can be made
- directly to the resource owner (as shown)
-
or preferably indirectly via the authorization server as an intermediary
- We will see this flow later
-
The initial and the most important step
-
Branching factor
- The flow and consequently other steps depend on it
-
Credential representing the resource owner’s authorization
-
Will be used by the client to obtain the final access token
-
Four standard types:
authorization code
implicit
resource owner password credentials
client credentials
-
Extensible
- Resource owner only authenticates with the authorization server like other flows
- Ability to authenticate the client
- Transmission of the access token directly to the client without passing it through the resource owner’s user-agent.
-
Client
constructs a URI by adding the following params to theauthorization endpoint
of theAuthorization Server
-
Client
then redirects theUser Agent
to this URI -
Params
response_type
: must becode
for this flowclient_id
: id of theclient
, registered inAuthorization Server
redirect_uri
scope
: Access copestate
: An opaque value used by the client to maintain state between the request and callback
GET
/authorize?response_type=code&client_id={ID}&state={STATE}&redirect_uri=https://client.com/callback
Host: server.example.com
-
Authorization Server
issues anauthorization code
and delivers it to theClient
-
Delivery to the
redirect_uri
specified in step A -
Params
code
- MUST expire shortly after it is issued
- maximum lifetime of 10 minutes is RECOMMENDED.
- The client MUST NOT it more than once.
- If used more than once the
Authorization Server
MUST deny the request
state
- If it was present in step A
- MUST BE the exact value received from the client
HTTP/1.1 302 Found
Location: https://client.com/callback?code={CODE}&state={STATE}
HTTP/1.1 302 Found
Location: https://client.com/callback?error={ERROR_TYPE}&error_description={DESCRIPTION}&state={STATE}
- Error types
invalid_request
: missing required paramsunauthorized_client
: client not authorized to use this flowaccess_denied
: resource owner or authorization server denied the requestunsupported_response_type
: flow not supportedinvalid_scope
: invalid, unknown, or malformed scopeserver_error
: unexpected server errortemporarily_unavailable
: acts as a503 Service Unavailable
- because
503
status cannot be returned to the client via a redirect
- because
state
- If it was present in step A
- MUST BE the exact value received from the client
-
Client
makes aPOST
request to thetoken endpoint
with the following parameters in the body -
grant_type
: MUST beauthorization_code
for this flow -
code
: Authorization code received in Step C -
redirect_uri
: MUST match the value given in Step A -
client_id
: REQUIRED if the client is confidential- MUST match Step A
-
client_secret
: REQUIRED if the client is confidential -
Client authentication can be done with HTTP
Basic Auth
if the client has a password
POST /token
Host: server.com
-
Headers
-
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
- Only if client has a
password
- Only if client has a
-
Content-Type: application/x-www-form-urlencoded
-
-
Body
grant_type=authorization_code&code={CODE}&redirect_uri=https://client.com/callback&client_id={ID}&client_secret={SECRET}
Authorization Server
MUST
- require authentication for confidential clients
- authenticate the client if authentication is included
- ensure
authorization code
was issued to the same client - if the client is public ensure code was issued to "client_id" in the request
- verify validity of the
Authorization Code
- ensure
redirect_uri
is present and matches if it was included in Step A
OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value"
}
- Now we are ready to take a closer look at each role
-
Usually an end-user
-
All a user needs to know about the OAuth framework
- A third-party app (
Client
) will make requests on their behalf - They have to provide credentials only to the source (
Authorization Server
) - They should never give their credentials to the third-party app
- They can revoke the access at any time at source (
Authorization Server
) - Access scopes, if any, and their semantics
- A third-party app (
-
Advanced users
- How to configure an app (
Client
)- Client id and secret
- Client's redirection URI, if any or if needed
- Allowed scopes
- The flow used by the Client
- If multiple flows are supported by the Client
- How to configure an app (
-
Verifying
- Authenticity of the
Access Token
- Validity of the
Access Token
- The scope
- Denying access if requested resource is beyond the scope
- Authenticity of the
-
The method used to validate is left to implementations
- Most web/HTTP frameworks have support for extracting OAuth access tokens from the request
- Token verification is usually left as an abstract operation
-
Depending on the type of
Access Token
verification can be done- By interacting with the
Authorization Server
- In the
Resource Server
itself
- By interacting with the
-
See Bearer Token Usage RFC 6750 for more info
Confidential
- Capable of keeping confidentiality of their credentials
- On a secure server
- Alternatively, capable of secure authentication by other means
Public
- Incapable of maintaining the confidentiality of credentials
- Native or on-device apps
- Single-page or browser-based apps
- No other means of secure authentication
- Incapable of maintaining the confidentiality of credentials
-
Needs to implement the full spec of the flow(s) used
-
Registered in
Authorization Server
-
Needs a secure secret if
Confidential
-
Has to use the
state
param to keep a state between steps of the flow- This is also recommended to prevent cross-site forgery (CSRF) attacks
-
Securely store the
Access Token
and not expose it by any means -
Expose a
Redirection URI
if needed by the flow -
Much easier to implement compared to the
Authoriztion Server
- A multitude of open source libraries
- Needs to implement the full spec and the extensions
- A subset of the spec if advertised as such
- Supports manual or automatic
Client
registration - Capable of revoking
Access Token
s - Should allow multiple
Redirection URI
s for aClient
- Most implementation support wildcards in URIs
- Only absolute URIs are allowed
- Extra care not to end up as an open redirector in hackers' hands
- Should support
scopes
according to the spec
-
Authorization Endpoint
- Used to interact with
Resource Owner
and obtain an authorization grant - Server needs to first verify the identity of the
Resource Owner
GET
method must be supportedPOST
support is optional and allowed
- Used to interact with
-
Token Endpoint
- Used by the
Client
to obtain anAccess Token
- By presenting its
Authorization Grant
orRefresh Token
- By presenting its
- MUST enforce TLS
- Used by the
- Credentials used to obtain access tokens.
- Issued to the
Client
byAuthorization Server
- To obtain a new access token when the current one expires
- Optional, fully in the discretion of
Authorization Server
- Not supported for all flows
-
For
Public
clients with a particularRedirection URI
- Typically in-browser apps
- If not a browser app
- Handle redirects
- Talk HTTP and extract params from response
-
Refresh tokens NOT supported
-
Access token is received as the result of the authorization request
- Encoded in the fragment part of the
Redirection URI
- May be (most probably) exposed to the
Resource Owner
- May be exposed to other apps on the same device
- Encoded in the fragment part of the
-
Misuse of
Access Token
to ImpersonateResource Owner
-
Clients can't know if the access token was issued to them or not
/callback#access_token={VALID-BUT-MALICIUOS-TOKEN}
-
Alternatives
- Assisted Token Flow
- Use the
Authoriztion Code
flow with backend's help
-
Client
constructs a URI by adding the following params to theauthorization endpoint
of theAuthorization Server
-
Client
then redirects theUser Agent
to this URI -
Params
response_type
: must betoken
for this flowclient_id
: id of theclient
, registered inAuthorization Server
redirect_uri
scope
: Access copestate
: An opaque value used by the client to maintain state between the request and callback
GET
/authorize?response_type=token&client_id={ID}&state={STATE}&redirect_uri=https://client.com/callback
Host: server.example.com
-
Authorization Server
adds the following params to theRedirection URI
fragment partaccess_token
token_type
expires_in
: lifetime in secondsscope
- If omitted, it means all requested
scopes
are granted - MUST be present, if only a subset of requested scopes is granted
- If omitted, it means all requested
state
-
NO
Refresh Token
is allowed for this flow- The server MUST NOT issue refresh token
302 Found
Location: http://single-page.com/callback#access_token={TOKEN}&state={STATE}&token_type={TYP}&expires_in=3600
-
Resource Owner
has high trust in theClient
- Device operating system or a highly privileged app
-
Should be used only if no other flow is viable
- Even mobile operating systems and first-part apps use other flows these days
-
Good choice for migrating legacy clients using HTTP Basic
-
Still much better than storing the credentials
-
POST
request totoken endpoint
with following params -
grant_type
: MUST bepassword
for this flow -
username
: The resource owner username -
password
: The resource owner password -
scope
: OPTIONAL Access scope -
Client authentication can be done with HTTP
Basic Auth
if the client has a password
POST /token
Host: server.com
-
Headers
-
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
- Only if client has a
password
- Only if client has a
-
Content-Type: application/x-www-form-urlencoded
-
-
Body
grant_type=password&username={USERNAME}&password={PWD}
OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}
-
On-Premise
-
Cloud
- (Auth0)[https://auth0.com/]