Skip to content

Instantly share code, notes, and snippets.

@iaintshine
Last active August 29, 2015 14:11
Show Gist options
  • Save iaintshine/29ac64f33efb6adc9db5 to your computer and use it in GitHub Desktop.
Save iaintshine/29ac64f33efb6adc9db5 to your computer and use it in GitHub Desktop.
OAuth 2 server authorization algorithms

Bearer token authorisation:

Errors (status code, error code, description):

HTTP status code error code (error) description (message) WWW-Authenticate
401 (unauthorized) token_missing Request lacks any authentication information. Bearer realm="OAuth API”
400 (bad request) invalid_request The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed. Bearer realm="OAuth API", error="#{code}", error_description="#{message}”
401 (unauthorized) invalid_token The access token provided is expired, revoked, malformed, or invalid for other reasons. Bearer realm="OAuth API", error="#{code}", error_description="#{message}”
401 (unauthorised) insufficient_scope The request requires higher privileges than provided by the access token. Bearer realm="OAuth API", error="#{code}", error_description="#{message}”
401 (unauthorised) invalid_developer_key The developer key provided is expired, revoked, malformed, or invalid for other reasons. DevKey realm="Admin OAuth API", error="#{code}", error_description="#{message}"
400 (bad request) tokens_mismatch The tokens provided are not compatible. Probably provided for different users. DevKey realm="Admin OAuth API", error="#{code}", error_description="#{message}"

Generic algorithm:

# check if authorisation header is present
unless authorization_header.present? # env[HTTP_AUTHORIZATION].present?
	raise :token_missing
end

# extract bearer token
bearer_token_param = authorization_header.extract_bearer_token
access_token = AccessToken.authenticate bearer_token_param

# check if access token is valid
raise :invalid_token unless access_token.valid?

Client credentials authorization (using application/x-www-form-urlencoded media type):

Request

The client makes a request to the token endpoint (/oauth/token) by using application/x-www-form-urlencoded format (media type). Only the following parameters can be used:

name required description example
grant_type REQUIRED Value Must be set to client_credentials client_credentials
scope OPTIONAL The scope of the access request read write openid

If Authorization header (Authorization Base base64(client_id:client_secret)) is not used client_id and client_secret Must be used.

e.g.

POST /oauth/token HTTP/1.1
Host: api.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json

grant_type=client_credentials&client_id=client_a&client_secret=secretpass

Response

The authorization server MUST

  • require client authentication (client credentials)
  • authenticate the client

Valid response e.g.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	“access_token” : “#{json web token}”,
	“token_type” : “Bearer”,
	“expires_in” : 3600,
	“refresh_token” : “#{json web token}”,
	“scope” : “read write openid”, 
}
name required description example
access_token REQUIRED The access token issued by the authorisation server. aCCessTokeN
token_type REQUIRED The type of the token issued (bearer) bearer
expires_in RECOMMENDED The lifetime in seconds of the access token. 3600
scope OPTIONAL If identical to the scope requested by the client, otherwise REQUIRED read write openid

NOTICE The authorisation server Must include the HTTP Cache-Control response header field with a value of no-store in any response containing tokens, credentials, or other sensitive information, as well as the Pragma response header field with a value of no-cache.

NOTICE: A refresh token is NOT included

Errors (status code, error code, description):

HTTP status code error code (error) description (message)
400 (bad request) invalid_request The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.
401 (unauthorised) invalid_client Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the "Authorization" request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the "WWW-Authenticate" response header field matching the authentication scheme used by the client.
400 (bad request) invalid_grant The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
400 (bad request) unauthorized_client The authenticated client is not authorised to use this authorisation grant type.
400 (bad request) unsupported_grant_type The authorisation grant type is not supported by the authorisation server.
400 (bad request) invalid_scope The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner.
400 (bad request) insecure_transport The OAuth 2 Must utilize https protocol.

e.g.

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	“error” : “invalid_request”,
	“error_description” : “The request is missing a required parameter, includes an
               unsupported parameter value (other than grant type),
               repeats a parameter, includes multiple credentials,
               utilizes more than one mechanism for authenticating the
               client, or is otherwise malformed.”,
	“error_uri” : “https://api.example.com/uaa/oauth/errors/invalid_request”
}

Algorithm:

# validate incoming request
issue **insecure_transport** unless https protocol used

issue **invalid_request** unless media_type equals to the **application/x-www-form-urleconded**
issue **invalid_request** if grant_type param missing
issue **invalid_request** if client authentication via Authorization header AND via client_id and client_secret params
issue **invalid_request** if other params than expected

# validate grant type
issue **unsupported_grant_type**  unless grant type is supported by this authorisation server

# validate client credentials
issue **invalid_client** AND set **WWW-Authenticate** if unknown client OR no client authentication credentials OR unsupported authentication method (e.g. client_id and client_secret are passed using url query parameters instead of authorisation header or post query params)

# validate client credentials if they match
issue **invalid_grant** if client credentials are invalid

# validate if client is authorised to this authorisation grant type 
issue **unauthorized_client** unless authenticated client is authorised to use this grant type

# validate scope
issue **invalid_scope** unless scopes are well formed and valid (exists, and are allowed for this client) 
issue **invalid_scope** unless scopes are included in the client’s authorities array 

Refresh token authorization (using application/x-www-form-urlencoded media type):

Request

The client makes a request to the token endpoint (/oauth/token) by using application/x-www-form-urlencoded format (media type). Only the following parameters can be used:

name required description example
grant_type REQUIRED Value Must be set to refresh_token refresh_token
refresh_token REQUIRED The refresh token issued to the client. RefReShToKen
scope OPTIONAL The scope of the access request. The requested scope MUST NOT include any scope not originally granted by the resource owner, and if omitted is treated as equal to the scope originally granted by the resource owner. read write openid
client_id OPTIONAL The client id client_a
client_secret OPTIONAL The client secret AABBCCDD

If Authorization header (Authorization Base base64(client_id:client_secret)) is not used client_id and client_secret Must be used.

e.g.

POST /uaa/oauth/token HTTP/1.1
Host: api.example.com
Authorization: Basic base64(client_id:cliend_secret)
Content-Type: application/x-www-form-urlencoded
Accept: application/json

grant_type=refresh_token&refresh_token=abcdefghijklmnop

Response

The authorization server MUST

  • require client authentication (client credentials)
  • authenticate the client (if client authentication is included)
  • validate refresh token

Notice : since this access token request utilises the resource owner’s password, the authorisation server protects the endpoint against brute force attacks using rate-limitation (up to 5 invalid attempts and than must wait for 5 minutes until next attempt, alerts are generated as well).

Valid response e.g.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	“access_token” : “#{json web token}”,
	“token_type” : “Bearer”,
	“expires_in” : 3600,
	“scope” : “read write openid”
}
name required description example
access_token REQUIRED The access token issued by the authorisation server. aCCessTokeN
token_type REQUIRED The type of the token issued (bearer) bearer
expires_in RECOMMENDED The lifetime in seconds of the access token. 3600
scope OPTIONAL If identical to the scope requested by the client, otherwise REQUIRED read write openid

NOTICE The authorisation server Must include the HTTP Cache-Control response header field with a value of no-store in any response containing tokens, credentials, or other sensitive information, as well as the Pragma response header field with a value of no-cache.

Errors (status code, error code, description):

HTTP status code error code (error) description (message)
400 (bad request) invalid_request The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.
401 (unauthorised) invalid_client Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the "Authorization" request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the "WWW-Authenticate" response header field matching the authentication scheme used by the client.
400 (bad request) invalid_grant The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
400 (bad request) unauthorized_client The authenticated client is not authorised to use this authorisation grant type.
400 (bad request) unsupported_grant_type The authorisation grant type is not supported by the authorisation server.
400 (bad request) invalid_scope The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner.
400 (bad request) insecure_transport The OAuth 2 Must utilize https protocol.

e.g.

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	“error” : “invalid_request”,
	“error_description” : “The request is missing a required parameter, includes an
               unsupported parameter value (other than grant type),
               repeats a parameter, includes multiple credentials,
               utilizes more than one mechanism for authenticating the
               client, or is otherwise malformed.”,
	“error_uri” : “https://api.example.com/uaa/oauth/errors/invalid_request”
}

Algorithm:

# validate incoming request
issue **insecure_transport** unless https protocol used

issue **invalid_request** unless media_type equals to the **application/x-www-form-urleconded**
issue **invalid_request** if grant_type param missing
issue **invalid_request** if refresh_token missing
issue **invalid_request** if client authentication via Authorization header AND via client_id and client_secret params
issue **invalid_request** if other params than expected

# validate grant type
issue **unsupported_grant_type**  unless grant type is supported by this authorisation server (it is - so never issued)

# validate client credentials
issue **invalid_client** AND set **WWW-Authenticate** if unknown client OR no client authentication credentials OR unsupported authentication method (e.g. client_id and client_secret are passed using url query parameters instead of authorisation header or post query params)

# validate if client is authorised to this authorisation grant type 
issue **unauthorized_client** unless authenticated client is authorised to use this grant type

# refresh token validation validation
issue **invalid_grant** unless refresh token valid

# validate scope
issue **invalid_scope** unless scopes are well formed and valid (exists, and are allowed for this client)
issue **invalid_scope** if scopes includes any scope that was not originally granted by the resource owner.

Incorrect values of either client_id or client_secret MUST issue invalid_client error with The client credentials are invalid description message. The case is valid for every grant type other than client_credentials where incorrect client credentials MUST issue invalid_grant.

For reference see OAuth2 Box REST API

Resource owner password credentials authorization (using application/x-www-form-urlencoded media type):

Request

The client makes a request to the token endpoint (/oauth/token) by using application/x-www-form-urlencoded format (media type). Only the following parameters can be used:

name required description example
grant_type REQUIRED Value Must be set to password password
username REQUIRED The resource owner username. foobar
password REQUIRED The resource owner password. pass1234
scope OPTIONAL The scope of the access request read write openid
client_id OPTIONAL The client id client_a
client_secret OPTIONAL The client secret AABBCCDD

If Authorization header (Authorization Base base64(client_id:client_secret)) is not used client_id and client_secret Must be used.

e.g.

POST /oauth/token HTTP/1.1
Host: api.example.com
Authorization: Basic base64(client_id:cliend_secret)
Content-Type: application/x-www-form-urlencoded
Accept: application/json

grant_type=password&username=foobar&password=pass1234

Response

The authorization server MUST

  • require client authentication (client credentials)
  • authenticate the client (if client authentication is included)
  • validate resource owner password credentials

Notice : since this access token request utilises the resource owner’s password, the authorisation server protects the endpoint against brute force attacks using rate-limitation (up to 5 invalid attempts and than must wait for 5 minutes until next attempt, alerts are generated as well).

Valid response e.g.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	“access_token” : “#{json web token}”,
	“token_type” : “Bearer”,
	“expires_in” : 3600,
	“refresh_token” : “#{json web token}”,
	“scope” : “read write openid”, 
	# custom parameters
	“user_id” : 1,
	# JSON Metadata for OAuth Responses 1.0 (N. Sakimura)
	“_links” : {
		“self” : { 
			“href” : “https://api.example.com/oauth/token”,
			“content-type” : “application/x-www-form-urlencoded” 
		},
		“userinfo” : {
			“href” : “https://api.example.com/openid/userinfo”,
			“Authorize” : “#{token_type} #{access_token}”
		} 
	}
}
name required description example
access_token REQUIRED The access token issued by the authorisation server. aCCessTokeN
token_type REQUIRED The type of the token issued (bearer) bearer
expires_in RECOMMENDED The lifetime in seconds of the access token. 3600
refresh_token OPTIONAL The refresh token, which can be used to obtain new access token. RefResHTokeN
scope OPTIONAL If identical to the scope requested by the client, otherwise REQUIRED read write openid

NOTICE The authorisation server Must include the HTTP Cache-Control response header field with a value of no-store in any response containing tokens, credentials, or other sensitive information, as well as the Pragma response header field with a value of no-cache.

Errors (status code, error code, description):

HTTP status code error code (error) description (message)
400 (bad request) invalid_request The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.
401 (unauthorised) invalid_client Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the "Authorization" request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the "WWW-Authenticate" response header field matching the authentication scheme used by the client.
400 (bad request) invalid_grant The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
400 (bad request) unauthorized_client The authenticated client is not authorised to use this authorisation grant type.
400 (bad request) unsupported_grant_type The authorisation grant type is not supported by the authorisation server.
400 (bad request) invalid_scope The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner.
400 (bad request) insecure_transport The OAuth 2 Must utilize https protocol.

e.g.

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	“error” : “invalid_request”,
	“error_description” : “The request is missing a required parameter, includes an
               unsupported parameter value (other than grant type),
               repeats a parameter, includes multiple credentials,
               utilizes more than one mechanism for authenticating the
               client, or is otherwise malformed.”,
	“error_uri” : “https://api.example.com/oauth/errors/invalid_request”
}

Algorithm:

# validate incoming request
issue **insecure_transport** unless https protocol used

issue **invalid_request** unless media_type equals to the **application/x-www-form-urleconded**
issue **invalid_request** if grant_type param missing
issue **invalid_request** if username or password missing
issue **invalid_request** if client authentication via Authorization header AND via client_id and client_secret params
issue **invalid_request** if other params than expected

# validate grant type
issue **unsupported_grant_type**  unless grant type is supported by this authorisation server

# validate client credentials
issue **invalid_client** AND set **WWW-Authenticate** if unknown client OR no client authentication credentials OR unsupported authentication method (e.g. client_id and client_secret are passed using url query parameters instead of authorisation header or post query params)
issue **invalid_client** AND set **WWW-Authenticate** if client credentials are invalid

# validate if client is authorised to this authorisation grant type 
issue **unauthorized_client** unless authenticated client is authorised to use this grant type

# validate scope
issue **invalid_scope** unless scopes are well formed and valid (exists, and are allowed for this client)

# resource owner credentials validation
check if username and password is valid
if not then issue **invalid_grant** error

Incorrect values of either client_id or client_secret MUST issue invalid_client error with The client credentials are invalid description message. The case is valid for every grant type other than client_credentials where incorrect client credentials MUST issue invalid_grant.

For reference see OAuth2 Box REST API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment