OAuth Notes

Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes
Evernote: OAuth Client Registration AKA User App Authorization

Eye-Fi OAuth

http://blog.apigee.com/detail/oauth_differences/
dev-staging: crypt OAuth Blowfish Hash
dev-staging: crypt OAuth GPG Hash
http://www.rest.vm/
http://www.rest.vm/phptool.php

http://server.eyefi.vm/oauth/auth.php?client_id…

RESTful Web Services

John Calcote – A simple (but long-winded) guide to REST web services
John Calcote – PUT or POST: The REST of the Story
Sun Cloud API
NetFlix REST API Conventions
NetFlix REST API Reference
Google API
Foursquare API
Yahoo OAuth Authorization Model (OAuth 1.0)
DISQUS API (OAuth 2.0 Draft 20)

Eye-Fi OAuth Flow

  1. Client obtains client_id and client_secret from EyeFi (api key/secret).
  2. Client makes this call to give permissions to the app:
    https://oauth.loop.net/oauth/authorize.php?client_id=xxxx&scope=xxxx,xxxx,xxxx&redirect_uri=xxxx&response_type=code
  3. Eyefi Server Send a “code” back to the redirect_uri:
    https://redirect_uri/?code=xxxxx
  4. The client: Then makes a call to the access_token url with the code passed in from previous step:
    https://oauth.loop.net/oauth/access_token.php?code=xxxx&client_id=xxxx&client_secret=xxxx&grant_type=authorization_code

    And as a response eyefi sends a json response with access_token and refresh_token with corresponding expiration_time. Access token is now usable with our apis ( if the auth key is a part of the access token).

  5. If the access token has expired the client refreshes the access_token:
    https://oauth.loop.net/oauth/access_token.php?refresh_token=xxxx&client_id=xxxx&client_secret=xxxx&grant_type=refresh_token

    And as a response eyefi sends a json response with new access_token and refresh_token with corresponding expiration_time.

OAuth 1.0

OAuth 1.0 was published in December 2007.
OAuth 1.0 Revision A was published in June 2008.
OAuth 1.0 was published as RFC 5849 in April 2010.

OAuth 2.0

27signals supports Draft 05.
Facebook and oauth2-ruby support Draft 00.

OAuth 2.0 Draft 26

   +--------+                               +---------------+
|        |--(A)- Authorization Request ->|   Resource    |
|        |                               |     Owner     |
|        |<-(B)-- Authorization Grant ---|               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(C)-- Authorization Grant -->| Authorization |
| Client |                               |     Server    |
|        |<-(D)----- Access Token -------|               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(E)----- Access Token ------>|    Resource   |
|        |                               |     Server    |
|        |<-(F)--- Protected Resource ---|               |
+--------+                               +---------------+

1.1 Roles

resource owner
An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.
resource server
The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
client
An application making protected resource requests on behalf of the resource owner and with its authorization. The term client does not imply any particular implementation characteristics (e.g. whether the application executes on a server, a desktop, or other devices).
authorization server
The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.

4.0 Obtaining Authorization

  1. Authorization Code Grant
  2. Implicit Grant
  3. Resource Owner Password Credentials Grant
  4. Client Credentials Grant
  5. OAuth 2.0 Authorization Protocol: Bearer Tokens
  6. HTTP Authentication: MAC Access Authentication
  7. OAuth 2.0 Threat Model and Security Considerations
  1. Autherization Server MUST require client_id and response_type
  2. Autherization Server SHOULD store client_id and redirect_uri (possibly an array of URIs)
  3. Eye-Fi’s Autherization Server SHOULD store client_id, api_secret & redirect_uri (possibly an array of URIs)
  4. Autherization Server SHOULD require state & response_type

4.1 Authorization Code Grant


+----------+
| resource |
|   owner  |
|          |
+----------+
     ^
     |
    (B)
+----|-----+          Client Identifier      +---------------+
|         -+----(A)-- & Redirection URI ---->|               |
|  User-   |                                 | Authorization |
|  Agent  -+----(B)-- User authenticates --->|     Server    |
|          |                                 |               |
|         -+----(C)-- Authorization Code ---<|               |
+-|----|---+                                 +---------------+
  |    |                                         ^      v
 (A)  (C)                                        |      |
  |    |                                         |      |
  ^    v                                         |      |
+---------+                                      |      |
|         |>---(D)-- Authorization Code ---------'      |
|  Client |          & Redirection URI                  |
|         |                                             |
|         |<---(E)----- Access Token -------------------'
+---------+       (w/ Optional Refresh Token)

https://dev.eyefi.vm/tools/rest/oauth.php?client_id=1234567890&response_type=code&scope=public&state=auth-token

The flow illustrated in Figure 3 includes the following steps:

(A)  The client initiates the flow by directing the resource owner's
    user-agent to the authorization endpoint.  The client includes
    its client identifier, requested scope, local state, and a
    redirection URI to which the authorization server will send the
    user-agent back once access is granted (or denied).
(B)  The authorization server authenticates the resource owner (via
    the user-agent) and establishes whether the resource owner
    grants or denies the client's access request.
(C)  Assuming the resource owner grants access, the authorization
    server redirects the user-agent back to the client using the
    redirection URI provided earlier (in the request or during
    client registration).  The redirection URI includes an
    authorization code and any local state provided by the client
    earlier.
(D)  The client requests an access token from the authorization
    server's token endpoint by including the authorization code
    received in the previous step.  When making the request, the
    client authenticates with the authorization server.  The client
    includes the redirection URI used to obtain the authorization
    code for verification.
(E)  The authorization server authenticates the client, validates the
    authorization code, and ensures the redirection URI received
    matches the URI used to redirect the client in step (C).  If
    valid, the authorization server responds back with an access
    token and optionally, a refresh token.

4.1.1 Authorization Request

response_type
	REQUIRED. Value MUST be set to "code".
client_id
	REQUIRED. The client identifier as described in Section 2.2.
redirect_uri
	OPTIONAL. As described in Section 3.1.2.
scope
	OPTIONAL. The scope of the access request as described by Section 3.3.
state
	RECOMMENDED. An opaque value used by the client to maintain state between the request and callback.
	The authorization server includes this value when redirecting the user-agent back to the client.
	The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

4.1.2 Authorization Response

code
     REQUIRED.  The authorization code generated by the
     authorization server.  The authorization code MUST expire
     shortly after it is issued to mitigate the risk of leaks.  A
     maximum authorization code lifetime of 10 minutes is
     RECOMMENDED.  The client MUST NOT use the authorization code
     more than once.  If an authorization code is used more than
     once, the authorization server MUST deny the request and SHOULD
     revoke (when possible) all tokens previously issued based on
     that authorization code.  The authorization code is bound to
     the client identifier and redirection URI.
state
     REQUIRED if the "state" parameter was present in the client
     authorization request.  The exact value received from the
     client.

4.1.2.1 Error Response

error
     REQUIRED.  A single error code from the following:
     invalid_request
           The request is missing a required parameter, includes an
           invalid parameter value, includes a parameter more than
           once, or is otherwise malformed.
     unauthorized_client
           The client is not authorized to request an authorization
           code using this method.
     access_denied
           The resource owner or authorization server denied the
           request.
     unsupported_response_type
           The authorization server does not support obtaining an
           authorization code using this method.
     invalid_scope
           The requested scope is invalid, unknown, or malformed.
     server_error
           The authorization server encountered an unexpected
           condition which prevented it from fulfilling the request.
     temporarily_unavailable
           The authorization server is currently unable to handle
           the request due to a temporary overloading or maintenance
           of the server.
error_description
     OPTIONAL.  A human-readable UTF-8 encoded text providing
     additional information, used to assist the client developer in
     understanding the error that occurred.
error_uri
     OPTIONAL.  A URI identifying a human-readable web page with
     information about the error, used to provide the client
     developer with additional information about the error.
state
     REQUIRED if a "state" parameter was present in the client
     authorization request.  The exact value received from the
     client.

4.1.x Authorization Example

// CLIENT REGISTRATION AKA USER APP AUTHORIZATION //
< GET /oauth/registration.php?client_id=12344567890
	&redirect_uri=http://oauth.loop.net/2.0.php&response_type=code
	&scope=public,bulk&state=auth_token&sig=123412341234 HTTP/1.1
< Host: www.loop.net

// SUCCESS
> HTTP/1.1 302 Found
> Location: http://oauth.loop.net/2.0.php \
	?code=b76abfcc0f45bed3f217f9e70b965232&state=auth_token

// FAILURE
> HTTP/1.1 302 Found
> Location: http://oauth.loop.net/2.0.php?error= \
	(invalid_request|unauthorized_client|etc.) \
	&error_description=OPTIONAL_UTF-8_ENCODED_TEXT \
	&error_uri=OPTIONAL_HUMAN-READABLE_WEB_PAGE_URI&state=auth_token
--------------------------------------------------------------------------------
// REQUEST ACCESS TOKEN
< GET /oauth?grant_type=authorization_code&client_id=12344567890 \
	&code=b76abfcc0f45bed3f217f9e70b965232 \
	&redirect_uri=http://oauth.loop.net/2.0.php \
	&sig=123412341234&state=access_token HTTP/1.1
< Host: oauth.loop.net

// SUCCESS
> HTTP/1.1 200 OK
> Content-Type: application/json;charset=UTF-8
> Cache-Control: no-store
> Pragma: no-cache
>
> {
>     "access_token":"8ec96f151afdda11a7d776409f70bc3be47ba852",
>     "token_type":"bulk-public",
>     "expires_in":86400,
>     "refresh_token":"OGVjOTZmMTUxYWZkZGExMWE3ZDc3NjQwOWY3MGJjM2JlNDdiYTg1Mg%3D%3D",
>     "example_parameter":"example_value"
> }

access_token+

hash_hmac('sha1', '/account/update?', md5(api_secret), )

crypt($string, $salt);

// FAILURE
> HTTP/1.1 400 Bad Request
> Content-Type: application/json;charset=UTF-8
> Cache-Control: no-store
> Pragma: no-cache
>
> {
>     "error":"invalid_request"
> }
--------------------------------------------------------------------------------
// REFRESH TOKEN //
< GET /oauth?client_id=12344567890&grant_type=refresh_token \
	&redirect_uri=http://oauth.loop.net/2.0.php \
	&refresh_token=OGVjOTZmMTUxYWZkZGExMWE3ZDc3NjQwOWY3MGJjM2JlNDdiYTg1Mg%3D%3D \
	&sig=123412341234&state=refresh_token HTTP/1.1
< Host: oauth.loop.net

4.2 Implicit Grant

The implicit grant type is used to obtain access tokens (it does not support the issuance of refresh tokens) and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language such as JavaScript.

+----------+
| Resource |
|  Owner   |
|          |
+----------+
     ^
     |
    (B)
+----|-----+          Client Identifier     +---------------+
|         -+----(A)-- & Redirection URI --->|               |
|  User-   |                                | Authorization |
|  Agent  -|----(B)-- User authenticates -->|     Server    |
|          |                                |               |
|          |<---(C)--- Redirection URI ----<|               |
|          |          with Access Token     +---------------+
|          |            in Fragment
|          |                                +---------------+
|          |----(D)--- Redirection URI ---->|   Web-Hosted  |
|          |          without Fragment      |     Client    |
|          |                                |    Resource   |
|     (F)  |<---(E)------- Script ---------<|               |
|          |                                +---------------+
+-|--------+
  |    |
 (A)  (G) Access Token
  |    |
  ^    v
+---------+
|         |
|  Client |
|         |
+---------+

4.3 Resource Owner Password Credentials Grant

  1. Username and password sent to authorization server.
  2. Authorization server returns access token and optional refresh token.

Access Token Request

+----------+
| Resource |
|  Owner   |
|          |
+----------+
     v
     |    Resource Owner
    (A) Password Credentials
     |
     v
+---------+                                  +---------------+
|         |>--(B)---- Resource Owner ------->|               |
|         |         Password Credentials     | Authorization |
| Client  |                                  |     Server    |
|         |<--(C)---- Access Token ---------<|               |
|         |    (w/ Optional Refresh Token)   |               |
+---------+                                  +---------------+

grant_type
	REQUIRED. Value MUST be set to "password".
username
	REQUIRED. The resource owner username, encoded as UTF-8.
password
	REQUIRED. The resource owner password, encoded as UTF-8.
scope
	OPTIONAL. The scope of the access request as described by Section 3.3.

4.4 Client Credentials Grant

+---------+                                  +---------------+
|         |                                  |               |
|         |>--(A)- Client Authentication --->| Authorization |
| Client  |                                  |     Server    |
|         |<--(B)---- Access Token ---------<|               |
|         |                                  |               |
+---------+                                  +---------------+

grant_type
	REQUIRED. Value MUST be set to "client_credentials".
scope
	OPTIONAL. The scope of the access request as described by Section 3.3.

3.3. Access Token Scope

The authorization and token endpoints allow the client to specify the scope of the access request using the “scope” request parameter. In turn, the authorization server uses the “scope” response parameter to inform the client of the scope of the access token issued.

The value of the scope parameter is expressed as a list of space-delimited, case sensitive strings. The strings are defined by the authorization server. If the value contains multiple space-delimited strings, their order does not matter, and each string adds an additional access range to the requested scope.

scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

The authorization server MAY fully or partially ignore the scope requested by the client based on the authorization server policy or the resource owner’s instructions. If the issued access token scope is different from the one requested by the client, the authorization server MUST include the “scope” response parameter to inform the client of the actual scope granted.

If the client omits the scope parameter when requesting authorization, the authorization server MUST either process the request using a pre-defined default value, or fail the request indicating an invalid scope. The authorization server SHOULD document its scope requirements and default value (if defined).