# [The OAuth 2.0 Authorization Framework](http://www.ietf.org/rfc/rfc6749.txt) This document is intended to be a simplified version of the [OAuth 2.0](http://www.ietf.org/rfc/rfc6749.txt) specification. In particular it has been written with implementors in mind, and as such attempts to trim the spec down to just what you need to implement an OAuth provider or client. It is necessarily not complete, but attempts to introduce spec requirements in the same order in which the protocol proceeds in practise, with everything you need to know about each protocol endpoint brought together in one place rather than scattered across a large document. Caveat emptor: some details have been deliberately left out because the author considered them detrimental to an easy understanding of how the protocol should be used. Almost everything in the spec is suffixed with, 'or, do whatever you want,' so I doubt this has done much to damage the document's accuracy. It is recommended that implementors read the _Security Considerations_ in the original specification. ## Roles There are four entities in OAuth: * Resource owner - an entity capable of granting access to protected resources * Resource server - a server storing and mediating access to protected resources * Client - an application that wants access to the resource owner's resources * Authorization server - server that issues tokens to clients ## Protocol flow +--------+ +---------------+ | |--(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 ---| | +--------+ +---------------+ ## Grant types * Authorization code * Implicit * Resource owner password credentials * Client credentials * Extension types ### Authorization code The client redirects to the authorization server, which authenticates the resource owner and obtains authorization, then redirects to the client with an authorization code. The client then exchanges the code for an access token by supplying its credentials. This allows client to authenticate separately and means the access token never is exposed to the resource owner's user agent. ### Implicit Optimized for in-browser JS clients. Instead of an authorization code, an access token is issued immediately without client authentication. Identity is handled using redirect URI. Because the access token is returned via a redirect rather than as the result of a server-side call, it is exposed to the resource owner and any other software with access to the user agent. ### Resource owner password credentials Username and password are used instead of an authorization code to obtain an access token. Should only be used for highly trusted clients or when other types are not available. Username and password are only used to get an access token and are not stored. This flow can also be used to migrate legacy systems to OAuth by exchanging stored user credentials for an access token. ### Client credentials The client supplies its own credentials to get an access token. Used when the client and resource owner are the same entity. This flow must only be used by confidential clients (defined below). ### Extension types The client gets an access token by declaring it's using an extension type, identified by an absolute URI, and supplying any parameters required by that type. In earlier drafts of the spec this mechanism was referred to as 'assertions' but its scope has since broadened. ## Access and refresh tokens Both types of tokens are opaque to the client. Access tokens may be identifiers used to retrive authorization data, or self-contain the data using a signed representation. Refresh tokens are identifiers. More detailed information on different token types appears at the end of this document. ### Using refresh tokens +--------+ +---------------+ | |--(A)------- Authorization Grant --------->| | | | | | | |<-(B)----------- Access Token -------------| | | | & Refresh Token | | | | | | | | +----------+ | | | |--(C)---- Access Token ---->| | | | | | | | | | | |<-(D)- Protected Resource --| Resource | | Authorization | | Client | | Server | | Server | | |--(E)---- Access Token ---->| | | | | | | | | | | |<-(F)- Invalid Token Error -| | | | | | +----------+ | | | | | | | |--(G)----------- Refresh Token ----------->| | | | | | | |<-(H)----------- Access Token -------------| | +--------+ & Optional Refresh Token +---------------+ ## HTTP redirection Though 302 is used in the spec, any workable method of redirecting the client is acceptable. ## Client registration Clients must provide: * Client type * Confidential - can keep their credentials secure, e.g. server-side apps * Public - cannot keep credentials secure, e.g. JS/native apps * Redirect URI(s) * If the client cannot pre-regsiter its complete redirect URI, it must at least register the scheme, authority and path. The client can still vary the query string in this URI when obtaining authorization. * The client can register multiple redirect URIs. * The provider should never redirect to an unregistered URI. * Server-defined metadata e.g. name, website, description, logo All public clients, and confidential clients using the implicit grant type, must pre-register with the provider. The provider should (not must) require other client types to register as well. On registration, client receives: * Client identifier - unique string identifying the client, not secret * Client credentials - if confidential client, get a password, key pair, etc. Providers may issue credentials to public clients but should not trust them. Providers may elect to respond to unregistered clients at their own discretion, for example see the [remoteStorage](http://remotestorage.io/) protocol. ## Protocol endpoints An OAuth provider must have: * An _authorization endpoint_, which the client redirects to when it needs the user to grant authorization. * Used by the _authorization code_ and _implicit_ flows * May include `application/x-www-form-urlencoded` query component * Must not include fragment component * Must respond to `GET`, may respond to `POST` * A _token endpoint_, which the client uses to obtain access tokens * Used by all flows except the _implicit_ grant type * May include `application/x-www-form-urlencoded` query component * Must not include fragment component * Must respond to `POST` An OAuth client must have: * A _redirection endpoint_, which the provider redirects to with the user's authorization code * May include `application/x-www-form-urlencoded` query component * Must not include fragment component * Must respond to `GET` * Used by the _authorization code_ and _implicit_ flows In general, all endpoints must be accessed over TLS to protect credentials transferred over the wire. (This requirement is a MUST for the provider and a SHOULD for the client.) Query parameters must not appear more than once in any request, and should be ignored if sent without a value. Unknown parameter names should be ignored. ## Obtaining the owner's authorization In the _authorization code_ and _implicit_ flows, the client begins by redirecting the user agent to the provider's _authorization endpoint_. It includes the following parameters: * `response_type` - required, can be one of: * `code` causes the provider to issue an authorization code, which the client must send to the _token endpoint_ along with its credentials to obtain an access token. * `token` causes the provider to issue an access token immediately (implicit flow). The client can immediately use this token without authenticating through the _token endpoint_. * Extension types may be defined that contain space (`%20`) delimited unorderd list of values. The meaning of these is defined in other specs. * `client_id` - required, the client's unique identifier. * `redirect_uri` - required unless the client has registered a single complete _redirection endpoint_. If it has registered multiple endpoints, an incomplete endpoint or no endpoint at all, this parameter is required. When present, the provider must check that at least one of the client's registered URIs matches this value. (See [RFC3986 section 6](http://tools.ietf.org/html/rfc3986#section-6).) * `scope` - optional, space-separated list of scope names. The provider should show the owner a readable list of the scopes the client has asked for. If no scope is requested, the provider must assume an implicit default scope or treat the request as invalid. * `state` - optional (but recommended) string value used by the client to maintain state between the request and the callback. The provider must echo this value unmodified when it redirects back to the client. Can be used to prevent cross-site request forgery (CSRF). ### Response format The provider returns its response either by displaying a page to the resource owner (in the case of some types of error) or by redirecting to the client's _redirection endpoint_. The response contains a series of parameters expressed in `application/x-www-form-urlencoded` format. These parameters appear in the query string if the client sent `response_type=code`, or in the fragment if the client sent `response_type=token`. Since some user agents do not support fragments in the `Location` header, it may be necessary to redirect via other means, for example a `form` whose `action` refers to the required URI. ### Success response If the client's authorization request was valid, and the resource owner successfully authenticates and grants access, the provider redirects back to the client's _redirection endpoint_. It should warn the resource owner if the _redirection endpoint_ does not use TLS since leaking a code or access token affects the security of the protected resources. This is particularly important if the client is using the provider as a 3rd-party authentication service a-la 'Sign in with Facebook'. The provider includes the following url-encoded parameters in the redirect URI sent to the client: * `code` - required if the client sent `response_type=code`. A unique token representing the owner's access grant to the client. It is recommended this token expire after at most 10 minutes, but the code _must_ expire at some point. The client cannot use this code more than once to obtain an access token. If the token is used more than once the provider should revoke tokens derived from it, if possible. * `access_token` - required if the client sent `response_type=token`. A token representting the resource owner's access grant to the client, encapsulating the grant's scope(s) and duration. The client uses this token to access protected resources. * `token_type` - required if the client sent `response_type=token`. Case- insensitive value that tells the client what type of token is being issued and how to use it. * `expires_in` - recommended if the client sent `response_type=token`. The lifetime in seconds of the access token. If omitted, the provider should document the default value. * `scope` - if applicable, a space-separated list of the scopes that the resource owner granted the client access to. This may be a subset of the scopes requested by the client, based on the provider's policies and the resource owner's instructions. The server must include this if it differs from what the client requested. * `state` - the same value that the client included in the authorization request. If the client responds to the _redirection endpoint_ with an HTML page (rather than redirecting further), it should not include any 3rd-party JavaScript in the page since the authorization code or access token is visible to all JS code via the `window.location` object. ### Error response If the authorization request fails due to an invalid `redirect_uri` or `client_id`, the provider must inform the resource owner of the error and must not redirect to the supplied URI. If the request is invalid for any other reason (e.g. the resource owner denied the request), and the provider has enough information to redirect to the client, it should do so. The provider will include the following url-encoded parameters when redirecting to the client. Chars in these parameters must be in the range `%x20-21 / %x23-5B / %x5D-7E`. * `error` - required, one of: * `invalid_request` - the request was missing a required parameter, includes invalid values or is otherwise malformed * `unauthorized_client` - the client cannot request authorization via this method * `access_denied` - the resource owner denied the request * `unsupported_response_type` - the requested `response_type` is not supported * `invalid_scope` - the requested `scope` is invalid, unknown, or malformed * `server_error` - the server encountered an unhandled error during processing * `temporarily_unavailable` - current unable to handle the request * `error_description` - optional text explanation of the error * `error_uri` - URI of a page giving more information about the error * `state` - the same value that the client included in the authorization request e.g. HTTP/1.1 302 Found Location: https://client.example.com/cb?error=access_denied&state=xyz ## Obtaining an access token In all flows except the _implicit_ grant type, the client calls the provider's _token endpoint_ to exchange some set of credentials for an access token. This typically involves the client authenticating to guard against codes and tokens being leaked or clients being compromised. ### Client authentication Client can use HTTP Basic authentication when obtaining an access token. It uses its url-encoded `client_id` as the username and its url-encoded `client_secret` as the password. e.g.: Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3 The client can include `client_id` and `client_secret` in the request body. Clients should only do this if they're incapable of using HTTP Basic auth. e.g.: POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded;charset=UTF-8 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw The client must not put `client_id` or `client_secret` in the URI when authenticating. This request must be performed using TLS. The server must protect the `client_secret` against brute force attacks. If the client was never issued with a `client_secret` (e.g. because it's a public client) it only needs to send `client_id` in the token request. This should not be treated as trustworthy and should only be used for informing the user, gathering stats, etc. The server may support other authentication mechanisms if it wants to. ### Request parameters As well its authentication credentials, the client passes the following url-encoded parameters in the body of the POST request: * `grant_type` - required, one of: * `authorization_code` if the client used `response_type=code` previously * `password` if using the _resource owner password credentials_ flow * `client_credentials` if using the _client credentials_ flow * `refresh_token` if the client was previously issued with a refresh token * An absolute URI indicates an extension type * `code` - required if `grant_type=authorization_code`. The value of the `code` parameter given to the client by the provider in the previous step. * `username` - required if `grant_type=password`. * `password` - required if `grant_type=password`. * `redirect_uri` - required if this value was included in the authorization request. Must be identical to the previous value. Not required if there was no authorization request, for example if `grant_type=password`. * `scope` - optional, space-separated list of scope names. If no scope is requested, the provider must assume an implicit default scope or treat the request as invalid. The client includes the scope as this stage if there was no previous authorization request, for example if `grant_type=password`. If using an extension type, the client must include whichever parameters are required by that type, for example for SAML 2.0 assertions: POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded;charset=UTF-8 grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2- bearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU The provider must, where applicable: * authenticate the client if it was issued with credentials * check the authorization code was issued to that client * verify the authorization code is valid * check the refresh token is valid and was issued to that client * if the `redirect_uri` param was used in the authorization request, check it is present in the token request and has the same value * validate the given scope(s) * carry out any validation required by an extension type ### Response format The provider must return a JSON document using the `application/json` content type and the `Cache-Control: no-store` and `Pragma: no-cache` headers. The client must ignore parameters it does not recognize. The status code is 200 for a successful response, and 400 or 401 for an error response. e.g.: HTTP/1.1 200 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" } ### Success response If the request is valid, the server issues a 200 response containing a JSON document with the following fields: * `access_token` - a token representting the resource owner's access grant to the client, encapsulating the grant's scope(s) and duration. The client uses this token to access protected resources. * `token_type` - required, case-insensitive value that tells the client what type of token is being issued and how to use it. This will either be a registered name (e.g. `bearer`, `mac`) or an absolute URI. * `expires_in` - recommended, the lifetime in seconds of the access token. If omitted, the provider should document the default value. * `refresh_token` - optional, a token that can be used to obtain new access tokens using the same authorization grant. * `scope` - if applicable, a space-separated list of the scopes that the resource owner granted the client access to. This may be a subset of the scopes requested by the client, based on the provider's policies and the resource owner's instructions. The server must include this if it differs from what the client requested. ### Error response If the request is not valid, the server issues a 400 response containing a JSON document with the following fields: * `error` - required, one of: * `invalid_request` - the request was missing a required parameter, includes invalid values or is otherwise malformed * `invalid_client` - the client did not authenticate successfully. The provider may return a 401 to indicate which authentication methods are supported. If the client attempted to authenticate via the `Authorization` header, the provider must respond with a 401 and use the `WWW-Authenticate` header matching the authentication scheme used by the client. * `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. * `unauthorized_client` - the client cannot request authorization via this grant type * `unsupported_grant_type` - the requested `grant_type` is not supported * `invalid_scope` - the requested `scope` is invalid, unknown, or malformed * `error_description` - optional text explanation of the error * `error_uri` - URI of a page giving more information about the error ## Accessing a protected resource Once the client has obtained an access token it can use it to make authenticated requests on the resource owner's behalf. The resource server checks the token is valid, not expired, and carries sufficient scope to access/modify the requested resource. The method by which the token is embedded in the request depends on the `token_type` the token was issued with, but typically involves data transferred in the `Authorization` header. The particular syntax, as well as the format of error responses, is defined by other specs. Clients must not use token types that they do not understand. Some examples of standardized token types follow. ### [Bearer tokens](http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer) These tokens have `token_type=bearer`. They are opaque values that either encode the authorization using a cryptographic signature, or are identifiers that refer to authorization information stored on the provider's servers. If the latter, they should have negligible probability (must be less than 2^-128, preferably less than 2^-160) of being guessed. #### Request format Bearer tokens may be transmitted using the `Authorization` header using the `Bearer` scheme. They must only be transmitted via TLS. They are confined to the character set used in base64-encoding, but are not actually encoded as such before transmission - they are included literally in the request. GET /resource/1 HTTP/1.1 Host: example.com Authorization: Bearer mF_9.B5f-4.1JqM They may be embedded in the body of an `application/x-www-form-urlencoded` request using the `access_token` parameter, if all the following are true: * The request includes the header `Content-Type: application/x-www-form-urlencoded` * The entity body is correctly url-encoded * The entity body is single-part (e.g. no file uploads) * The entity body consists only of ASCII characters * The HTTP verb has defined semantics for the body, e.g. `GET` is not allowed Finally, the token may be included as a query string parameter. Clients must send the header `Cache-Control: no-store` with such requests, and the provider should return the header `Cache-Control: private` with 200 responses. Clients should use, in order of preference for security reasons: the `Authorization` header, entity body encoding, then query-string encoding. They should use each scheme only if they are incapable of using more desirable scheme. Providers should make sure tokens do not appear in HTTP logs. #### Error responses If the token is not valid for accessing the requested resource, the provider returns an error using the `WWW-Authenticate` header, e.g.: HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="The access token expired" The header uses the `Bearer` scheme and may include the following parameters. The provider should not include specific error information if the request contained no (or unrecognized) authentication data. * `realm` * `scope` - a space-separated list of scopes required to access the resource * `error` - if the request contained an access token that was not valid, this value can be one of the following. Associated status codes are given in brackets. * `invalid_request` [400] - required parameter missing, request malformed * `invalid_token` [401] - the token is expired, revoked, malformed, etc. * `insufficient_scope` [403] - the token does not have all the scope(s) required to access the resource * `error_description` - human-readable explanation of the `error` * `error_uri` - URI of a page containing more information about the error In addition to the statuses 400, 401 and 403 listed above, the server may return 405 (Method Not Allowed) in response to a failed request. ### [MAC tokens](http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac) These tokens have `token_type=mac` and are issued as a token along with the `mac_key` and `mac_algorithm` parameters. They must be issued over TLS. HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token":"SlAV32hkKG", "token_type":"mac", "expires_in":3600, "refresh_token":"8xLOxBtZp8", "mac_key":"adijq39jdlaska9asud", "mac_algorithm":"hmac-sha-256" } `access_token` and `mac_key` are opaque values. `mac_algorithm` may be one of `hmac-sha-1` or `hmac-sha-256`; this tells the client how to calculate MACs when using this token type. These values must not include characters other than `%x20-21 / %x23-5B / %x5D-7E`. #### Request format MAC tokens are transmitted using the `Authorization` header using the `MAC` scheme. The client calculates a MAC based on the access token parameters and the properties of the request, and embeds the result in this header, e.g.: GET /resource/1?b=1&a=2 HTTP/1.1 Host: example.com Authorization: MAC id="h480djs93hd8", ts="1336363200", nonce="dj83hs9s", mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM=" ext="an optional value" These requests can be made over a plaintext connection. The client constructs the request as follows. It first generates the current Unix timestamp (`ts`) and a random string (`nonce`). It then generates a _normalized request string_ (NRS) by concatenating the follow values separated by a newline `0x0A` character: * The current Unix timestamp `ts` * The nonce `nonce` * The uppercase HTTP method e.g. `GET`, `POST`, etc. * The request URI * The hostname as contained in the `Host` header * The port number as contained in the `Host` header, or the default port number for the request scheme (80 for HTTP, 443 for HTTPS) * The value of the `ext` `Authorization` field if present For example the HTTP request POST /request?b5=%3D%253D&a3=a&c%40=&a2=r%20b&c2&a3=2+q HTTP/1.1 Host: example.com Hello World! along with the timestamp `264095:7d8f3e4a`, nonce `7d8f3e4a` and `ext` value `a,b,c` produces the NRS: 264095\n 7d8f3e4a\n POST\n /request?b5=%3D%253D&a3=a&c%40=&a2=r%20b&c2&a3=2+q\n example.com\n 80\n a,b,c\n The client then calculates `mac = HMAC(key, text)` where `HMAC` is either `hmac-sha-1` or `hmac-sha-256` as required by the provider, `key` is the issued `mac_key` and `text` is the NRS value. It then constructs the `Authorization` header value by including the `ts`, `nonce`, `mac`, `ext` and `id` values, where `id` is the value of `access_token` issued by the provider that identifies the key being used so the provider can verify it. The provider must verify the MAC by using the `id` to look up the key in its database and recalculating the MAC by the above steps. It must check that the `(ts,nonce,mac)` combination has never been received before. It must also verify that the token has not expired, has not been revoked, and covers the scope(s) required by the requested resource. The server can reject requests whose timestamps are beyond a certain threshold, so that it does not have to store an indefinite number of MACs to prevent replay attacks. The first time the provider receives a request with a given key identifier `id`, it stores the _request time delta_, the difference between the request timestamp `ts` and the server's clock. For every subsequent request using the same `id`, it calculates the _adjusted request time_ by applying the delta to the request timestamp to adjust the time to its own clock. If the adjusted time is too far in the past (allowing for reasonable network latency) the request is rejected. #### Error response If the token verification fails, the provider returns a 401 response with the `WWW-Authenticate` header, e.g.: HTTP/1.1 401 Unauthorized WWW-Authenticate: MAC error="The MAC credentials expired"