OpenID Connect supports Self-Issued OpenID Providers - personal, self-hosted OPs that issue self-signed ID Tokens. Self-Issued OPs use the special Issuer Identifier https://self-issued.me.
The messages used to communicate with Self-Issued OPs are mostly the same as those used to communicate with other OPs. Specifications for the few additional parameters used and for the values of some parameters in the Self-Issued case are defined in this section.
| TOC |
If the input identifier for the discovery process contains the domain self-issued.me, dynamic discovery is not performed. Instead, then the following static configuration values are used:
{ "authorization_endpoint": "openid:", "issuer": "https://self-issued.me", "scopes_supported": ["openid", "profile", "email", "address", "phone"], "response_types_supported": ["id_token"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "request_object_signing_alg_values_supported": ["none", "RS256"] }
NOTE: The OpenID Foundation plans to host the OpenID Provider site https://self-issued.me/, including its WebFinger service, so that performing discovery on it returns the above static discovery information, enabling RPs to not need any special processing for discovery of the Self-Issued OP. This site will be hosted on an experimental basis. Production implementations should not take a dependency upon it without a subsequent commitment by the OpenID Foundation to host the site in a manner intended for production use.
| TOC |
When using a Self-Issued OP, registration is not required. The Client can proceed without registration as if it had registered with the OP and obtained the following Client Registration Response:
- client_id
- redirect_uri value of the Client.
- client_secret_expires_at
- 0
NOTE: The OpenID Foundation plans to host the (stateless) endpoint https://self-issued.me/registration/1.0/ that returns the response above, enabling RPs to not need any special processing for registration with the Self-Issued OP. This site will be hosted on an experimental basis. Production implementations should not take a dependency upon it without a subsequent commitment by the OpenID Foundation to host the site in a manner intended for production use.
| TOC |
OpenID Connect defines the following Authorization Request parameter to enable Clients to provide additional registration information to Self-Issued OpenID Providers:
- registration
- OPTIONAL. This parameter is used by the Client to provide information about itself to a Self-Issued OP that would normally be provided to an OP during Dynamic Client Registration. The value is a JSON object containing Client metadata values, as defined in Section 2.1 of the OpenID Connect Dynamic Client Registration 1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” November 2014.) [OpenID.Registration] specification. The registration parameter SHOULD NOT be used when the OP is not a Self-Issued OP.
None of this information is REQUIRED by Self-Issued OPs, so the use of this parameter is OPTIONAL.
The registration parameter value is represented in an OAuth 2.0 request as a UTF-8 encoded JSON object (which ends up being form-urlencoded when passed as an OAuth parameter). When used in a Request Object value, per Section 6.1 (Passing a Request Object by Value), the JSON object is used as the value of the registration member.
The Registration parameters that would typically be used in requests to Self-Issued OPs are policy_uri, tos_uri, and logo_uri. If the Client uses more than one Redirection URI, the redirect_uris parameter would be used to register them. Finally, if the Client is requesting encrypted responses, it would typically use the jwks_uri, id_token_encrypted_response_alg and id_token_encrypted_response_enc parameters.
| TOC |
The Client sends the Authentication Request to the Authorization Endpoint with the following parameters:
- scope
- REQUIRED. scope parameter value, as specified in Section 3.1.2 (Authorization Endpoint).
- response_type
- REQUIRED. Constant string value id_token.
- client_id
- REQUIRED. Client ID value for the Client, which in this case contains the redirect_uri value of the Client. Since the Client's redirect_uri URI value is communicated as the Client ID, a redirect_uri parameter is NOT REQUIRED to also be included in the request.
- id_token_hint
- OPTIONAL. id_token_hint parameter value, as specified in Section 3.1.2 (Authorization Endpoint). If the ID Token is encrypted to the Self-Issued OP, the sub (subject) of the signed ID Token MUST be sent as the kid (Key ID) of the JWE. Encrypting content to Self-Issued OPs is currently only supported when the OP's JWK key type is RSA and the encryption algorithm used is RSA1_5.
- claims
- OPTIONAL. claims parameter value, as specified in Section 5.5 (Requesting Claims using the "claims" Request Parameter).
- registration
- OPTIONAL. This parameter is used by the Client to provide information about itself to a Self-Issued OP that would normally be provided to an OP during Dynamic Client Registration, as specified in Section 7.2.1 (Providing Information with the "registration" Request Parameter).
- request
- OPTIONAL. Request Object value, as specified in Section 6.1 (Passing a Request Object by Value). The Request Object MAY be encrypted to the Self-Issued OP by the Client. In this case, the sub (subject) of a previously issued ID Token for this Client MUST be sent as the kid (Key ID) of the JWE. Encrypting content to Self-Issued OPs is currently only supported when the OP's JWK key type is RSA and the encryption algorithm used is RSA1_5.
Other parameters MAY be sent. Note that all Claims are returned in the ID Token.
The entire URL MUST NOT exceed 2048 ASCII characters.
The following is a non-normative example HTTP 302 redirect response by the Client, which triggers the User Agent to make an Authentication Request to the Self-Issued OpenID Provider (with line wraps within values for display purposes only):
HTTP/1.1 302 Found Location: openid://? response_type=id_token &client_id=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile &state=af0ifjsldkj &nonce=n-0S6_WzA2Mj ®istration=%7B%22logo_uri%22%3A%22https%3A%2F%2F client.example.org%2Flogo.png%22%7D
| TOC |
OpenID Connect defines the following Claim for use in Self-Issued OpenID Provider Responses:
- sub_jwk
- REQUIRED. Public key used to check the signature of an ID Token issued by a Self-Issued OpenID Provider, as specified in Section 7 (Self-Issued OpenID Provider). The key is a bare key in JWK [JWK] (Jones, M., “JSON Web Key (JWK),” July 2014.) format (not an X.509 certificate value). The sub_jwk value is a JSON object. Use of the sub_jwk Claim is NOT RECOMMENDED when the OP is not Self-Issued.
The Self-Issued OpenID Provider response is the same as the normal Implicit Flow response with the following refinements. Since it is an Implicit Flow response, the response parameters will be returned in the URL fragment component, unless a different Response Mode was specified.
| TOC |
To validate the ID Token received, the Client MUST do the following:
The following is a non-normative example of a base64url decoded Self-Issued ID Token (with line wraps within values for display purposes only):
{ "iss": "https://self-issued.me", "sub": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", "aud": "https://client.example.org/cb", "nonce": "n-0S6_WzA2Mj", "exp":<PHONE_NUMBER>, "iat":<PHONE_NUMBER>, "sub_jwk": { "kty":"RSA", "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e":"AQAB" } }
| TOC |
A Subject Identifier is a locally unique and never reassigned identifier within the Issuer for the End-User, which is intended to be consumed by the Client. Two Subject Identifier types are defined by this specification:
- public
- This provides the same sub (subject) value to all Clients. It is the default if the provider has no subject_types_supported element in its discovery document.
- pairwise
- This provides a different sub value to each Client, so as not to enable Clients to correlate the End-User's activities without permission.
The OpenID Provider's Discovery document SHOULD list its supported Subject Identifier types in the subject_types_supported element. If there is more than one type listed in the array, the Client MAY elect to provide its preferred identifier type using the subject_type parameter during Registration.
| TOC |
When pairwise Subject Identifiers are used, the OpenID Provider MUST calculate a unique sub (subject) value for each Sector Identifier. The Subject Identifier value MUST NOT be reversible by any party other than the OpenID Provider.
Providers that use pairwise sub values and support Dynamic Client Registration (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” November 2014.) [OpenID.Registration] SHOULD use the sector_identifier_uri parameter. It provides a way for a group of websites under common administrative control to have consistent pairwise sub values independent of the individual domain names. It also provides a way for Clients to change redirect_uri domains without having to reregister all of their users.
If the Client has not provided a value for sector_identifier_uri in Dynamic Client Registration (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” November 2014.) [OpenID.Registration], the Sector Identifier used for pairwise identifier calculation is the host component of the registered redirect_uri. If there are multiple hostnames in the registered redirect_uris, the Client MUST register a sector_identifier_uri.
When a sector_identifier_uri is provided, the host component of that URL is used as the Sector Identifier for the pairwise identifier calculation. The value of the sector_identifier_uri MUST be a URL using the https scheme that points to a JSON file containing an array of redirect_uri values. The values of the registered redirect_uris MUST be included in the elements of the array.
Any algorithm with the following properties can be used by OpenID Providers to calculate pairwise Subject Identifiers:
Three example methods are:
| TOC |
This section defines a set of Client Authentication methods that are used by Clients to authenticate to the Authorization Server when using the Token Endpoint. During Client Registration, the RP (Client) MAY register a Client Authentication method. If no method is registered, the default method is client_secret_basic.
These Client Authentication methods are:
- client_secret_basic
- Clients that have received a client_secret value from the Authorization Server authenticate with the Authorization Server in accordance with Section 2.3.1 of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] using the HTTP Basic authentication scheme.
- client_secret_post
- Clients that have received a client_secret value from the Authorization Server, authenticate with the Authorization Server in accordance with Section 2.3.1 of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] by including the Client Credentials in the request body.
- client_secret_jwt
- Clients that have received a client_secret value from the Authorization Server create a JWT using an HMAC SHA algorithm, such as HMAC SHA-256. The HMAC (Hash-based Message Authentication Code) is calculated using the octets of the UTF-8 representation of the client_secret as the shared key.
- The Client authenticates in accordance with JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) [OAuth.JWT] and Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) [OAuth.Assertions]. The JWT MUST contain the following REQUIRED Claim Values and MAY contain the following OPTIONAL Claim Values:
- iss
- REQUIRED. Issuer. This MUST contain the client_id of the OAuth Client.
- sub
- REQUIRED. Subject. This MUST contain the client_id of the OAuth Client.
- aud
- REQUIRED. Audience. The aud (audience) Claim. Value that identifies the Authorization Server as an intended audience. The Authorization Server MUST verify that it is an intended audience for the token. The Audience SHOULD be the URL of the Authorization Server's Token Endpoint.
- jti
- REQUIRED. JWT ID. A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties; any such negotiation is beyond the scope of this specification.
- exp
- REQUIRED. Expiration time on or after which the ID Token MUST NOT be accepted for processing.
- iat
- OPTIONAL. Time at which the JWT was issued.
- The JWT MAY contain other Claims. Any Claims used that are not understood MUST be ignored.
- The authentication token MUST be sent as the value of the [OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) client_assertion parameter.
- The value of the [OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) client_assertion_type parameter MUST be "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", per [OAuth.JWT] (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.).
- private_key_jwt
- Clients that have registered a public key sign a JWT using that key. The Client authenticates in accordance with JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) [OAuth.JWT] and Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) [OAuth.Assertions]. The JWT MUST contain the following REQUIRED Claim Values and MAY contain the following OPTIONAL Claim Values:
- iss
- REQUIRED. Issuer. This MUST contain the client_id of the OAuth Client.
- sub
- REQUIRED. Subject. This MUST contain the client_id of the OAuth Client.
- aud
- REQUIRED. Audience. The aud (audience) Claim. Value that identifies the Authorization Server as an intended audience. The Authorization Server MUST verify that it is an intended audience for the token. The Audience SHOULD be the URL of the Authorization Server's Token Endpoint.
- jti
- REQUIRED. JWT ID. A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties; any such negotiation is beyond the scope of this specification.
- exp
- REQUIRED. Expiration time on or after which the ID Token MUST NOT be accepted for processing.
- iat
- OPTIONAL. Time at which the JWT was issued.
- The JWT MAY contain other Claims. Any Claims used that are not understood MUST be ignored.
- The authentication token MUST be sent as the value of the [OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) client_assertion parameter.
- The value of the [OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.) client_assertion_type parameter MUST be "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", per [OAuth.JWT] (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” July 2014.).
For example (with line wraps within values for display purposes only):
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=i1WsRn1uB1& client_id=s6BhdRkqt3& client_assertion_type= urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=PHNhbWxwOl ... ZT- none
- The Client does not authenticate itself at the Token Endpoint, either because it uses only the Implicit Flow (and so does not use the Token Endpoint) or because it is a Public Client with no Client Secret or other authentication mechanism.
| TOC |
Depending on the transport through which the messages are sent, the integrity of the message might not be guaranteed and the originator of the message might not be authenticated. To mitigate these risks, ID Token, UserInfo Response, Request Object, and Client Authentication JWT values can utilize JSON Web Signature (JWS) (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” July 2014.) [JWS] to sign their contents. To achieve message confidentiality, these values can also use JSON Web Encryption (JWE) (Jones, M., Rescorla, E., and J. Hildebrand, “JSON Web Encryption (JWE),” July 2014.) [JWE] to encrypt their contents.
When the message is both signed and encrypted, it MUST be signed first and then encrypted, per Section 16.14 (Signing and Encryption Order), with the result being a Nested JWT, as specified in [JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” July 2014.). Note that all JWE encryption methods perform integrity checking.
The OP advertises its supported signing and encryption algorithms in its Discovery document, or may supply this information by other means. The RP declares its required signing and encryption algorithms in its Dynamic Registration request, or may communicate this information by other means.
The OP advertises its public keys via its Discovery document, or may supply this information by other means. The RP declares its public keys via its Dynamic Registration request, or may communicate this information by other means.
| TOC |
The signing party MUST select a signature algorithm based on the algorithms supported by the recipient.
- Asymmetric Signatures
- When using RSA or ECDSA Signatures, the alg Header Parameter value of the JOSE Header MUST be set to an appropriate algorithm as defined in JSON Web Algorithms (Jones, M., “JSON Web Algorithms (JWA),” July 2014.) [JWA]. The private key used to sign the content MUST be associated with a public key used for signature verification published by the sender in its JWK Set document. If there are multiple keys in the referenced JWK Set document, a kid value MUST be provided in the JOSE Header. The key usage of the respective keys MUST support signing.
- Symmetric Signatures
- When using MAC-based signatures, the alg Header Parameter value of the JOSE Header MUST be set to a MAC algorithm, as defined in JSON Web Algorithms (Jones, M., “JSON Web Algorithms (JWA),” July 2014.) [JWA]. The MAC key used is the octets of the UTF-8 representation of the client_secret value. See Section 16.19 (Symmetric Key Entropy) for a discussion of entropy requirements for client_secret values. Symmetric signatures MUST NOT be used by public (non-confidential) Clients because of their inability to keep secrets.
See Section 16.20 (Need for Signed Requests) for Security Considerations about the need for signed requests.
| TOC |
Rotation of signing keys can be accomplished with the following approach. The signer publishes its keys in a JWK Set at its jwks_uri location and includes the kid of the signing key in the JOSE Header of each message to indicate to the verifier which key is to be used to validate the signature. Keys can be rolled over by periodically adding new keys to the JWK Set at the jwks_uri location. The signer can begin using a new key at its discretion and signals the change to the verifier using the kid value. The verifier knows to go back to the jwks_uri location to re-retrieve the keys when it sees an unfamiliar kid value. The JWK Set document at the jwks_uri SHOULD retain recently decommissioned signing keys for a reasonable period of time to facilitate a smooth transition.
| TOC |
The encrypting party MUST select an encryption algorithm based on the algorithms supported by the recipient.
- Asymmetric Encryption: RSA
- The public key to which the content was encrypted MUST be a public key used for encryption published by the recipient in its JWK Set document. If there are multiple keys in the referenced JWK Set document, a kid value MUST be provided in the JOSE Header. Use the supported RSA encryption algorithm to encrypt a random Content Encryption Key to be used for encrypting the signed JWT. The key usage of the respective keys MUST include encryption.
- Asymmetric Encryption: Elliptic Curve
- Create an ephemeral Elliptic Curve public key for the epk element of the JOSE Header. The other public key used for the key agreement computation MUST be a public key published by the recipient in its JWK Set document. If there are multiple keys in the referenced JWK Set document, a kid value MUST be provided in the JOSE Header. Use the ECDH-ES algorithm to agree upon a Content Encryption Key to be used for encrypting the signed JWT. The key usage of the respective keys MUST support encryption.
- Symmetric Encryption
- The symmetric encryption key is derived from the client_secret value by using a left truncated SHA-2 hash of the octets of the UTF-8 representation of the client_secret. For keys of 256 or fewer bits, SHA-256 is used; for keys of 257-384 bits, SHA-384 is used; for keys of 385-512 bits, SHA-512 is used. The hash value MUST be left truncated to the appropriate bit length for the AES key wrapping or direct encryption algorithm used, for instance, truncating the SHA-256 hash to 128 bits for A128KW. If a symmetric key with greater than 512 bits is needed, a different method of deriving the key from the client_secret would have to be defined by an extension. Symmetric encryption MUST NOT be used by public (non-confidential) Clients because of their inability to keep secrets.
See Section 16.21 (Need for Encrypted Requests) for Security Considerations about the need for encrypted requests.
| TOC |
Rotating encryption keys necessarily uses a different process than the one for signing keys because the encrypting party starts the process and thus cannot rely on a change in kid as a signal that keys need to change. The encrypting party still uses the kid Header Parameter in the JWE to tell the decrypting party which private key to use to decrypt, however, the encrypting party needs to first select the most appropriate key from those provided in the JWK Set at the recipient's jwks_uri location.
To rotate keys, the decrypting party can publish new keys at its jwks_uri location and remove from the JWK Set those that are being decommissioned. The jwks_uri SHOULD include a Cache-Control header in the response that contains a max-age directive, as defined in RFC 2616 (Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1,” June 1999.) [RFC2616], which enables the encrypting party to safely cache the JWK Set and not have to re-retrieve the document for every encryption event. The decrypting party SHOULD remove decommissioned keys from the JWK Set referenced by jwks_uri but retain them internally for some reasonable period of time, coordinated with the cache duration, to facilitate a smooth transition between keys by allowing the encrypting party some time to obtain the new keys. The cache duration SHOULD also be coordinated with the issuance of new signing keys, as described in Section 10.1.1 (Rotation of Asymmetric Signing Keys).
| TOC |
OpenID Connect defines the following scope value to request offline access:
- offline_access
- OPTIONAL. This scope value requests that an OAuth 2.0 Refresh Token be issued that can be used to obtain an Access Token that grants access to the End-User's UserInfo Endpoint even when the End-User is not present (not logged in).
When offline access is requested, a prompt parameter value of consent MUST be used unless other conditions for processing the request permitting offline access to the requested resources are in place. The OP MUST always obtain consent to returning a Refresh Token that enables offline access to the requested resources. A previously saved user consent is not always sufficient to grant offline access.
Upon receipt of a scope parameter containing the offline_access value, the Authorization Server:
The use of Refresh Tokens is not exclusive to the offline_access use case. The Authorization Server MAY grant Refresh Tokens in other contexts that are beyond the scope of this specification.
| TOC |
A request to the Token Endpoint can also use a Refresh Token by using the grant_type value refresh_token, as described in Section 6 of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749]. This section defines the behaviors for OpenID Connect Authorization Servers when Refresh Tokens are used.
| TOC |
To refresh an Access Token, the Client MUST authenticate to the Token Endpoint using the authentication method registered for its client_id, as documented in Section 9 (Client Authentication). The Client sends the parameters via HTTP POST to the Token Endpoint using Form Serialization, per Section 13.2 (Form Serialization).
The following is a non-normative example of a Refresh Request (with line wraps within values for display purposes only):
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded client_id=s6BhdRkqt3 &client_secret=some_secret12345 &grant_type=refresh_token &refresh_token=8xLOxBtZp8 &scope=openid%20profile
The Authorization Server MUST validate the Refresh Token, MUST verify that it was issued to the Client, and must verify that the Client successfully authenticated it has a Client Authentication method.
| TOC |
Upon successful validation of the Refresh Token, the response body is the Token Response of Section <IP_ADDRESS> (Successful Token Response) except that it might not contain an id_token.
If an ID Token is returned as a result of a token refresh request, the following requirements apply:
The following is a non-normative example of a Refresh Response:
HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token": "TlBN45jURg", "token_type": "Bearer", "refresh_token": "9yNOxJtZa5", "expires_in": 3600 }
| TOC |
If the Refresh Request is invalid or unauthorized, the Authorization Server returns the Token Error Response as defined in Section 5.2 of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749].
| TOC |
Messages are serialized using one of the following methods:
This section describes the syntax of these serialization methods; other sections describe when they can and must be used. Note that not all methods can be used for all messages.
| TOC |
In order to serialize the parameters using the Query String Serialization, the Client constructs the string by adding the parameters and values to the query component of a URL using the application/x-www-form-urlencoded format as defined by [W3C.REC‑html401‑19991224] (Raggett, D., Hors, A., and I. Jacobs, “HTML 4.01 Specification,” December 1999.). Query String Serialization is typically used in HTTP GET requests. The same serialization method is also used when adding parameters to the fragment component of a URL.
The following is a non-normative example of this serialization (with line wraps within values for display purposes only):
GET /authorize? response_type=code &scope=openid &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1 Host: server.example.com
| TOC |
Parameters and their values are Form Serialized by adding the parameter names and values to the entity body of the HTTP request using the application/x-www-form-urlencoded format as defined by [W3C.REC‑html401‑19991224] (Raggett, D., Hors, A., and I. Jacobs, “HTML 4.01 Specification,” December 1999.). Form Serialization is typically used in HTTP POST requests.
The following is a non-normative example of this serialization (with line wraps within values for display purposes only):
POST /authorize HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded response_type=code &scope=openid &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
| TOC |
The parameters are serialized into a JSON object structure by adding each parameter at the highest structure level. Parameter names and string values are represented as JSON strings. Numerical values are represented as JSON numbers. Boolean values are represented as JSON booleans. Omitted parameters and parameters with no value SHOULD be omitted from the object and not represented by a JSON null value, unless otherwise specified. A parameter MAY have a JSON object or a JSON array as its value.
The following is a non-normative example of this serialization:
{ "access_token": "SlAV32hkKG", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "8xLOxBtZp8" }
| TOC |
Processing some OpenID Connect messages requires comparing values in the messages to known values. For example, the Claim Names returned by the UserInfo Endpoint might be compared to specific Claim Names such as sub. Comparing Unicode strings, however, has significant security implications.
Therefore, comparisons between JSON strings and other Unicode strings MUST be performed as specified below:
In several places, this specification uses space delimited lists of strings. In all such cases, a single ASCII space character (0x20) MUST be used as the delimiter.
| TOC |
This specification defines features used by both Relying Parties and OpenID Providers. It is expected that some OpenID Providers will require static, out-of-band configuration of RPs using them, whereas others will support dynamic usage by RPs without a pre-established relationship between them. For that reason, the mandatory-to-implement features for OPs are listed below in two groups: the first for all OPs and the second for "Dynamic" OpenID Providers.
| TOC |
All OpenID Providers MUST implement the following features defined in this specification. This list augments the set of features that are already listed elsewhere as being "REQUIRED" or are described with a "MUST", and so is not, by itself, a comprehensive set of implementation requirements for OPs.
- Signing ID Tokens with RSA SHA-256
- OPs MUST support signing ID Tokens with the RSA SHA-256 algorithm (an alg value of RS256), unless the OP only supports returning ID Tokens from the Token Endpoint (as is the case for the Authorization Code Flow) and only allows Clients to register specifying none as the requested ID Token signing algorithm.
- Prompt Parameter
- OPs MUST support the prompt parameter, as defined in Section 3.1.2 (Authorization Endpoint), including the specified user interface behaviors such as none and login.
- Display Parameter
- OPs MUST support the display parameter, as defined in Section 3.1.2 (Authorization Endpoint). (Note that the minimum level of support required for this parameter is simply that its use must not result in an error.)
- Preferred Locales
- OPs MUST support requests for preferred languages and scripts for the user interface and for Claims via the ui_locales and claims_locales request parameters, as defined in Section 3.1.2 (Authorization Endpoint). (Note that the minimum level of support required for these parameters is simply to have their use not result in errors.)
- Authentication Time
- OPs MUST support returning the time at which the End-User authenticated via the auth_time Claim, when requested, as defined in Section 2 (ID Token).
- Maximum Authentication Age
- OPs MUST support enforcing a maximum authentication age via the max_age parameter, as defined in Section 3.1.2 (Authorization Endpoint).
- Authentication Context Class Reference
- OPs MUST support requests for specific Authentication Context Class Reference values via the acr_values parameter, as defined in Section 3.1.2 (Authorization Endpoint). (Note that the minimum level of support required for this parameter is simply to have its use not result in an error.)
| TOC |
In addition to the features listed above, OpenID Providers supporting dynamic establishment of relationships with RPs that they do not have a pre-configured relationship with MUST also implement the following features defined in this and related specifications.
- Response Types
- These OpenID Providers MUST support the id_token Response Type and all that are not Self-Issued OPs MUST also support the code and id_token token Response Types.
- Discovery
- These OPs MUST support Discovery, as defined in OpenID Connect Discovery 1.0 (Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0,” November 2014.) [OpenID.Discovery].
- Dynamic Registration
- These OPs MUST support Dynamic Client Registration, as defined in OpenID Connect Dynamic Client Registration 1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” November 2014.) [OpenID.Registration].
- UserInfo Endpoint
- All dynamic OPs that issue Access Tokens MUST support the UserInfo Endpoint, as defined in Section 5.3 (UserInfo Endpoint). (Self-Issued OPs do not issue Access Tokens.)
- Public Keys Published as Bare Keys
- These OPs MUST publish their public keys as bare JWK keys (which MAY also be accompanied by X.509 representations of those keys).
- Request URI
- These OPs MUST support requests made using a Request Object value that is retrieved from a Request URI that is provided with the request_uri parameter, as defined in Section 3.1.2 (Authorization Endpoint).
| TOC |
Some OpenID Connect installations can use a pre-configured set of OpenID Providers and/or Relying Parties. In those cases, it might not be necessary to support dynamic discovery of information about identities or services or dynamic registration of Clients.
However, if installations choose to support unanticipated interactions between Relying Parties and OpenID Providers that do not have pre-configured relationships, they SHOULD accomplish this by implementing the facilities defined in the OpenID Connect Discovery 1.0 (Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0,” November 2014.) [OpenID.Discovery] and OpenID Connect Dynamic Client Registration 1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” November 2014.) [OpenID.Registration] specifications.
| TOC |
In general, it is up to Relying Parties which features they use when interacting with OpenID Providers. However, some choices are dictated by the nature of their OAuth Client, such as whether it is a Confidential Client, capable of keeping secrets, in which case the Authorization Code Flow may be appropriate, or whether it is a Public Client, for instance, a User Agent Based Application or a statically registered Native Application, in which case the Implicit Flow may be appropriate.
When using OpenID Connect features, those listed as being "REQUIRED" or are described with a "MUST" are mandatory to implement, when used by a Relying Party. Likewise, those features that are described as "OPTIONAL" need not be used or supported unless they provide value in the particular application context. Finally, when interacting with OpenID Providers that support Discovery, the OP's Discovery document can be used to dynamically determine which OP features are available for use by the RP.
| TOC |
| TOC |
When using the Authorization Code or Hybrid flows, an ID Token is returned from the Token Endpoint in response to a Token Request using an Authorization Code. Some implementations may choose to encode state about the ID Token to be returned in the Authorization Code value. Others may use the Authorization Code value as an index into a database storing this state.
| TOC |
The nonce parameter value needs to include per-session state and be unguessable to attackers. One method to achieve this for Web Server Clients is to store a cryptographically random value as an HttpOnly session cookie and use a cryptographic hash of the value as the nonce parameter. In that case, the nonce in the returned ID Token is compared to the hash of the session cookie to detect ID Token replay by third parties. A related method applicable to JavaScript Clients is to store the cryptographically random value in HTML5 local storage and use a cryptographic hash of this value.
| TOC |
When response parameters are returned in the Redirection URI fragment value, the Client needs to have the User Agent parse the fragment encoded values and pass them to on to the Client's processing logic for consumption. User Agents that have direct access to cryptographic APIs may be able to be self-contained, for instance, with all Client code being written in JavaScript.
However, if the Client does not run entirely in the User Agent, one way to achieve this is to post them to a Web Server Client for validation.
The following is an example of a JavaScript file that a Client might host at its redirect_uri. This is loaded by the redirect from the Authorization Server. The fragment component is parsed and then sent by POST to a URI that will validate and use the information received.
Following is a non-normative example of a Redirect URI response:
GET /cb HTTP/1.1 Host: client.example.org HTTP/1.1 200 OK Content-Type: text/html <script type="text/javascript"> // First, parse the query string var params = {}, postBody = location.hash.substring(1), regex = /([^&=]+)=([^&]*)/g, m; while (m = regex.exec(postBody)) { params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } // And send the token over to the server var req = new XMLHttpRequest(); // using POST so query isn't logged req.open('POST', 'https://' + window.location.host + '/catch_response', true); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); req.onreadystatechange = function (e) { if (req.readyState == 4) { if (req.status == 200) { // If the response from the POST is 200 OK, perform a redirect window.location = 'https://' + window.location.host + '/redirect_after_login' } // if the OAuth response is invalid, generate an error message else if (req.status == 400) { alert('There was an error processing the token') } else { alert('Something other than 200 was returned') } } }; req.send(postBody);
| TOC |
| TOC |
Implementers should be aware that this specification uses several IETF specifications that are not yet final specifications. Those specifications are:
While every effort will be made to prevent breaking changes to these specifications, should they occur, OpenID Connect implementations should continue to use the specifically referenced draft versions above in preference to the final versions, unless using a possible future OpenID Connect profile or specification that updates some or all of these references.
| TOC |
Implementers may want to be aware that, as of the time of this writing, Google's deployed OpenID Connect implementation issues ID Tokens that omit the required https:// scheme prefix from the iss (issuer) Claim Value. Relying Party implementations wishing to work with Google will therefore need to have code to work around this, until such time as their implementation is updated. Any such workaround code should be written in a manner that will not break at such point Google adds the missing prefix to their issuer values.
| TOC |
These related OPTIONAL specifications MAY be used in combination with this specification to provide additional functionality:
These implementer's guides are intended to serve as self-contained references for implementers of basic Web-based Relying Parties:
| TOC |
This specification references the security considerations defined in Section 10 of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749], and Section 5 of OAuth 2.0 Bearer Token Usage (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.) [RFC6750]. Furthermore, the OAuth 2.0 Threat Model and Security Considerations (Lodderstedt, T., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.) [RFC6819] specification provides an extensive list of threats and controls that apply to this specification as well, given that it is based upon OAuth 2.0. ISO/IEC 29115 (International Organization for Standardization, “ISO/IEC 29115:2013 -- Information technology - Security techniques - Entity authentication assurance framework,” March 2013.) [ISO29115] also provides threats and controls that implementers need to take into account. Implementers are highly advised to read these references in detail and apply the countermeasures described therein.
In addition, the following list of attack vectors and remedies are also considered.
| TOC |
If appropriate measures are not taken, a request might be disclosed to an attacker, posing security and privacy threats.
In addition to what is stated in Section 5.1.1 of [RFC6819] (Lodderstedt, T., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.), this standard provides a way to provide the confidentiality of the request end to end through the use of request or request_uri parameters, where the content of the request is an encrypted JWT with the appropriate key and cipher. This protects even against a compromised User Agent in the case of indirect request.
| TOC |
A malicious Server might masquerade as the legitimate server using various means. To detect such an attack, the Client needs to authenticate the server.
In addition to what is stated in Section 5.1.2 of [RFC6819] (Lodderstedt, T., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.), this standard provides a way to authenticate the Server through either the use of Signed or Encrypted JWTs with an appropriate key and cipher.
| TOC |
An Attacker might generate a bogus token or modify the token contents (such as Claims values or the signature) of an existing parseable token, causing the RP to grant inappropriate access to the Client. For example, an Attacker might modify the parseable token to extend the validity period; a Client might modify the parseable token to have access to information that they should not be able to view.
There are two ways to mitigate this attack:
| TOC |
Access Tokens are credentials used to access Protected Resources, as defined in Section 1.4 of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749]. Access Tokens represent an End-User's authorization and MUST NOT be exposed to unauthorized parties.
| TOC |
The server response might contain authentication data and Claims that include sensitive Client information. Disclosure of the response contents can make the Client vulnerable to other types of attacks.
The server response disclosure can be mitigated in the following two ways:
| TOC |
A response might be repudiated by the server if the proper mechanisms are not in place. For example, if a Server does not digitally sign a response, the Server can claim that it was not generated through the services of the Server.
To mitigate this threat, the response MAY be digitally signed by the Server using a key that supports non-repudiation. The Client SHOULD validate the digital signature to verify that it was issued by a legitimate Server and its integrity is intact.
| TOC |
Since it is possible for a compromised or malicious Client to send a request to the wrong party, a Client that was authenticated using only a bearer token can repudiate any transaction.
To mitigate this threat, the Server MAY require that the request be digitally signed by the Client using a key that supports non-repudiation. The Server SHOULD validate the digital signature to verify that it was issued by a legitimate Client and the integrity is intact.
| TOC |
An Attacker uses the Access Token generated for one resource to obtain access to a second resource.
To mitigate this threat, the Access Token SHOULD be audience and scope restricted. One way of implementing it is to include the identifier of the resource for whom it was generated as audience. The resource verifies that incoming tokens include its identifier as the audience of the token.
| TOC |
An Attacker attempts to use a one-time use token such as an Authorization Code that has already been used once with the intended Resource. To mitigate this threat, the token SHOULD include a timestamp and a short validity lifetime. The Relying Party then checks the timestamp and lifetime values to ensure that the token is currently valid.
Alternatively, the server MAY record the state of the use of the token and check the status for each request.
| TOC |
In addition to the attack patterns described in Section <IP_ADDRESS> of [RFC6819] (Lodderstedt, T., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.), an Authorization Code can be captured in the User Agent where the TLS session is terminated if the User Agent is infected by malware. However, capturing it is not useful as long as either Client Authentication or an encrypted response is used.
| TOC |
Token Substitution is a class of attacks in which a malicious user swaps various tokens, including swapping an Authorization Code for a legitimate user with another token that the attacker has. One means of accomplishing this is for the attacker to copy a token out one session and use it in an HTTP message for a different session, which is easy to do when the token is available to the browser; this is known as the "cut and paste" attack.
The Implicit Flow of OAuth 2.0 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] is not designed to mitigate this risk. In Section 10.16, it normatively requires that any use of the authorization process as a form of delegated End-User authentication to the Client MUST NOT use the Implicit Flow without employing additional security mechanisms that enable the Client to determine whether the ID Token and Access Token were issued for its use.
In OpenID Connect, this is mitigated through mechanisms provided through the ID Token. The ID Token is a signed security token that provides Claims such as iss (issuer), sub (subject), aud (audience), azp (authorized party), at_hash (access token hash), and c_hash (code hash). Using the ID Token, the Client is capable of detecting the Token Substitution Attack.
The c_hash in the ID Token enables Clients to prevent Authorization Code substitution. The at_hash in the ID Token enables Clients to prevent Access Token substitution.
Also, a malicious user may attempt to impersonate a more privileged user by subverting the communication channel between the Authorization Endpoint and Client, or the Token Endpoint and Client, for example by swapping the Authorization Code or reordering the messages, to convince the Token Endpoint that the attacker's authorization grant corresponds to a grant sent on behalf of a more privileged user.
For the HTTP binding defined by this specification, the responses to Token Requests are bound to the corresponding requests by message order in HTTP, as both the response containing the token and requests are protected by TLS, which will detect and prevent packet reordering.
When designing another binding of this specification to a protocol incapable of strongly binding Token Endpoint requests to responses, additional mechanisms to address this issue MUST be utilized. One such mechanism could be to include an ID Token with a c_hash Claim in the token request and response.
| TOC |
A timing attack enables the attacker to obtain an unnecessary large amount of information through the elapsed time differences in the code paths taken by successful and unsuccessful decryption operations or successful and unsuccessful signature validation of a message. It can be used to reduce the effective key length of the cipher used.
Implementations SHOULD NOT terminate the validation process at the instant of the finding an error but SHOULD continue running until all the octets have been processed to avoid this attack.
| TOC |
There are various crypto related attacks possible depending on the method used for encryption and signature / integrity checking. Implementers need to consult the Security Considerations for the JWT (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” July 2014.) [JWT] specification and specifications that it references to avoid the vulnerabilities identified in these specifications.
| TOC |
Signatures over encrypted text are not considered valid in many jurisdictions. Therefore, for integrity and non-repudiation, this specification requires signing the plain text JSON Claims, when signing is performed. If both signing and encryption are desired, it is performed on the JWS containing the signed Claims, with the result being a Nested JWT, as specified in [JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” July 2014.). Note that since all JWE encryption algorithms provide integrity protection, there is no need to separately sign the encrypted content.
| TOC |
OpenID Connect supports multiple Issuers per Host and Port combination. The issuer returned by discovery MUST exactly match the value of iss in the ID Token.
OpenID Connect treats the path component of any Issuer URI as being part of the Issuer Identifier. For instance, the subject "1234" with an Issuer Identifier of "https://example.com" is not equivalent to the subject "1234" with an Issuer Identifier of "https://example.com/sales".
It is RECOMMENDED that only a single Issuer per host be used. However, if a host supports multiple tenants, multiple Issuers for that host may be needed.
| TOC |
In the Implicit Flow, the Access Token is returned in the fragment component of the Client's redirect_uri through HTTPS, thus it is protected between the OP and the User Agent, and between the User Agent and the RP. The only place it can be captured is the User Agent where the TLS session is terminated, which is possible if the User Agent is infected by malware or under the control of a malicious party.
| TOC |
Implementations MUST support TLS. Which version(s) ought to be implemented will vary over time, and depend on the widespread deployment and known security vulnerabilities at the time of implementation. At the time of this writing, TLS version 1.2 [RFC5246] (Dierks, T. and E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.2,” August 2008.) is the most recent version, but has very limited actual deployment, and might not be readily available in implementation toolkits. TLS version 1.0 [RFC2246] (Dierks, T. and C. Allen, “The TLS Protocol Version 1.0,” January 1999.) is the most widely deployed version, and will give the broadest interoperability.
To protect against information disclosure and tampering, confidentiality protection MUST be applied using TLS with a ciphersuite that provides confidentiality and integrity protection.
Whenever TLS is used, a TLS server certificate check MUST be performed, per RFC 6125 (Saint-Andre, P. and J. Hodges, “Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS),” March 2011.) [RFC6125].
| TOC |
Access Tokens might not be revocable by the Authorization Server. Access Token lifetimes SHOULD therefore be kept to single use or very short lifetimes.
If ongoing access to the UserInfo Endpoint or other Protected Resources is required, a Refresh Token can be used. The Client can then exchange the Refresh Token at the Token Endpoint for a fresh short-lived Access Token that can be used to access the resource.
The Authorization Server SHOULD clearly identify long-term grants to the User during Authorization. The Authorization Server SHOULD provide a mechanism for the End-User to revoke Access Tokens and Refresh Tokens granted to a Client.
| TOC |
In Section 10.1 (Signing) and Section 10.2 (Encryption), keys are derived from the client_secret value. Thus, when used with symmetric signing or encryption operations, client_secret values MUST contain sufficient entropy to generate cryptographically strong keys. Also, client_secret values MUST also contain at least the minimum of number of octets required for MAC keys for the particular algorithm used. So for instance, for HS256, the client_secret value MUST contain at least 32 octets (and almost certainly SHOULD contain more, since client_secret values are likely to use a restricted alphabet).
| TOC |
In some situations, Clients might need to use signed requests to ensure that the desired request parameters are delivered to the OP without having been tampered with. For instance, the max_age and acr_values provide more assurance about the nature of the authentication performed when delivered in signed requests.
| TOC |
In some situations, knowing the contents of an OpenID Connect request can, in and of itself, reveal sensitive information about the End-User. For instance, knowing that the Client is requesting a particular Claim or that it is requesting that a particular authentication method be used can reveal sensitive information about the End-User. OpenID Connect enables requests to be encrypted to the OpenID Provider to prevent such potentially sensitive information from being revealed.
| TOC |
| TOC |
The UserInfo Response typically contains Personally Identifiable Information (PII). As such, End-User consent for the release of the information for the specified purpose should be obtained at or prior to the authorization time in accordance with relevant regulations. The purpose of use is typically registered in association with the redirect_uris.
Only necessary UserInfo data should be stored at the Client and the Client SHOULD associate the received data with the purpose of use statement.
| TOC |
The Resource Server SHOULD make End-Users' UserInfo access logs available to them so that they can monitor who accessed their data.
| TOC |
To protect the End-User from a possible correlation among Clients, the use of a Pairwise Pseudonymous Identifier (PPID) as the sub (subject) SHOULD be considered.
| TOC |
Offline access enables access to Claims when the user is not present, posing greater privacy risk than the Claims transfer when the user is present. Therefore, it is prudent to obtain explicit consent for offline access to resources. This specification mandates the use of the prompt parameter to obtain consent unless it is already known that the request complies with the conditions for processing the request in each jurisdiction.
When an Access Token is returned via the User Agent using the Implicit Flow or Hybrid Flow, there is a greater risk of it being exposed to an attacker, who could later use it to access the UserInfo endpoint. If the Access Token does not enable offline access and the server can differentiate whether the Client request has been made offline or online, the risk will be substantially reduced. Therefore, this specification mandates ignoring the offline access request when the Access Token is transmitted through the User Agent. Note that differentiating between online and offline access from the server can be difficult especially for native clients. The server may well have to rely on heuristics. Also, the risk of exposure for the Access Token delivered through the User Agent for the Response Types of code token and token is the same. Thus, the implementations should be prepared to detect whether the Access Token was issued through the User Agent or directly from the Token Endpoint and deny offline access if the token was issued through the User Agent.
Note that although these provisions require an explicit consent dialogue through the prompt parameter, the mere fact that the user pressed an "accept" button etc., might not constitute a valid consent. Developers should be aware that for the act of consent to be valid, typically, the impact of the terms have to be understood by the End-User, the consent must be freely given and not forced (i.e., other options have to be available), and the terms must fair and equitable. In general, it is advisable for the service to follow the required privacy principles in each jurisdiction and rely on other conditions for processing the request than simply explicit consent, as online self-service "explicit consent" often does not form a valid consent in some jurisdictions.
| TOC |
| TOC |
This specification registers the Claims defined in Section 5.1 (Standard Claims) and Section 2 (ID Token) in the IANA JSON Web Token Claims registry defined in [JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” July 2014.).
| TOC |
| TOC |
This specification registers the following parameters in the IANA OAuth Parameters registry defined in RFC 6749 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749].
| TOC |
| TOC |
This specification registers the following errors in the IANA OAuth Extensions Error registry defined in RFC 6749 (Hardt, D., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749].
| TOC |
| TOC |
| TOC |
| [CORS] | Opera Software ASA, “Cross-Origin Resource Sharing,” July 2010. |
| [E.164] | International Telecommunication Union, “E.164: The international public telecommunication numbering plan,” 2010. |
| [IANA.Language] | Internet Assigned Numbers Authority (IANA), “Language Subtag Registry,” 2005. |
| [ISO29115] | International Organization for Standardization, “ISO/IEC 29115:2013 -- Information technology - Security techniques - Entity authentication assurance framework,” ISO/IEC 29115, March 2013. |
| [ISO3166-1] | International Organization for Standardization, “ISO 3166-1:1997. Codes for the representation of names of countries and their subdivisions -- Part 1: Country codes,” 1997. |
| [ISO639-1] | International Organization for Standardization, “ISO 639-1:2002. Codes for the representation of names of languages -- Part 1: Alpha-2 code,” 2002. |
| [ISO8601-2004] | International Organization for Standardization, “ISO 8601:2004. Data elements and interchange formats - Information interchange - Representation of dates and times,” 2004. |
| [JWA] | Jones, M., “JSON Web Algorithms (JWA),” draft-ietf-jose-json-web-algorithms (work in progress), July 2014 (HTML). |
| [JWE] | Jones, M., Rescorla, E., and J. Hildebrand, “JSON Web Encryption (JWE),” draft-ietf-jose-json-web-encryption (work in progress), July 2014 (HTML). |
| [JWK] | Jones, M., “JSON Web Key (JWK),” draft-ietf-jose-json-web-key (work in progress), July 2014 (HTML). |
| [JWS] | Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” draft-ietf-jose-json-web-signature (work in progress), July 2014 (HTML). |
| [JWT] | Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” draft-ietf-oauth-json-web-token (work in progress), July 2014 (HTML). |
| [OAuth.Assertions] | Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” draft-ietf-oauth-assertions (work in progress), July 2014 (HTML). |
| [OAuth.JWT] | Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” draft-ietf-oauth-jwt-bearer (work in progress), July 2014 (HTML). |
| [OAuth.Responses] | de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014. |
| [OpenID.Discovery] | Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0,” November 2014. |
| [OpenID.Registration] | Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” November 2014. |
| [RFC2119] | Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” BCP 14, RFC 2119, March 1997 (TXT, HTML, XML). |
| [RFC2246] | Dierks, T. and C. Allen, “The TLS Protocol Version 1.0,” RFC 2246, January 1999 (TXT). |
| [RFC2616] | Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1,” RFC 2616, June 1999 (TXT, PS, PDF, HTML, XML). |
| [RFC3339] | Klyne, G., Ed. and C. Newman, “Date and Time on the Internet: Timestamps,” RFC 3339, July 2002 (TXT, HTML, XML). |
| [RFC3966] | Schulzrinne, H., “The tel URI for Telephone Numbers,” RFC 3966, December 2004 (TXT). |
| [RFC3986] | Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax,” STD 66, RFC 3986, January 2005 (TXT, HTML, XML). |
| [RFC4627] | Crockford, D., “The application/json Media Type for JavaScript Object Notation (JSON),” RFC 4627, July 2006 (TXT). |
| [RFC5246] | Dierks, T. and E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.2,” RFC 5246, August 2008 (TXT). |
| [RFC5322] | Resnick, P., Ed., “Internet Message Format,” RFC 5322, October 2008 (TXT, HTML, XML). |
| [RFC5646] | Phillips, A. and M. Davis, “Tags for Identifying Languages,” BCP 47, RFC 5646, September 2009 (TXT). |
| [RFC6125] | Saint-Andre, P. and J. Hodges, “Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS),” RFC 6125, March 2011 (TXT). |
| [RFC6711] | Johansson, L., “An IANA Registry for Level of Assurance (LoA) Profiles,” RFC 6711, August 2012 (TXT). |
| [RFC6749] | Hardt, D., “The OAuth 2.0 Authorization Framework,” RFC 6749, October 2012 (TXT). |
| [RFC6750] | Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” RFC 6750, October 2012 (TXT). |
| [RFC6819] | Lodderstedt, T., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” RFC 6819, January 2013 (TXT). |
| [USA15] | Davis, M., Whistler, K., and M. Dürst, “Unicode Normalization Forms,” Unicode Standard Annex 15, 09 2009. |
| [W3C.REC-html401-19991224] | Raggett, D., Hors, A., and I. Jacobs, “HTML 4.01 Specification,” World Wide Web Consortium Recommendation REC-html401-19991224, December 1999 (HTML). |
| [zoneinfo] | Public Domain, “The tz database,” June 2011. |
| TOC |
| [JWK.Thumbprint] | Jones, M., “JSON Web Key (JWK) Thumbprint,” draft-jones-jose-jwk-thumbprint (work in progress), July 2014 (HTML). |
| [OAuth.Post] | Jones, M. and B. Campbell, “OAuth 2.0 Form Post Response Mode,” February 2014. |
| [OpenID.2.0] | OpenID Foundation, “OpenID Authentication 2.0,” December 2007 (TXT, HTML). |
| [OpenID.Basic] | Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, “OpenID Connect Basic Client Implementer's Guide 1.0,” November 2014. |
| [OpenID.Implicit] | Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, “OpenID Connect Implicit Client Implementer's Guide 1.0,” November 2014. |
| [OpenID.PAPE] | Recordon, D., Jones, M., Bufu, J., Ed., Daugherty, J., Ed., and N. Sakimura, “OpenID Provider Authentication Policy Extension 1.0,” December 2008 (TXT, HTML). |
| [OpenID.Session] | Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., Mortimore, C., and E. Jay, “OpenID Connect Session Management 1.0,” November 2014. |
| [RFC4949] | Shirey, R., “Internet Security Glossary, Version 2,” RFC 4949, August 2007 (TXT). |
| [X.1252] | International Telecommunication Union, “ITU-T Recommendation X.1252 -- Cyberspace security -- Identity management -- Baseline identity management terms and definitions,” ITU-T X.1252, November 2010. |
| TOC |
The following are non-normative examples of Authorization Requests with different response_type values and their responses (with line wraps within values for display purposes only):
| TOC |
GET /authorize? response_type=code &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile%20email &nonce=n-0S6_WzA2Mj &state=af0ifjsldkj HTTP/1.1 Host: server.example.com HTTP/1.1 302 Found Location: https://client.example.org/cb? code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk &state=af0ifjsldkj
| TOC |
GET /authorize? response_type=id_token &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile%20email &nonce=n-0S6_WzA2Mj &state=af0ifjsldkj HTTP/1.1 Host: server.example.com HTTP/1.1 302 Found Location: https://client.example.org/cb# id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogImlz cyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4 Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAi bi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEz MTEyODA5NzAsCiAibmFtZSI6ICJKYW5lIERvZSIsCiAiZ2l2ZW5fbmFtZSI6 ICJKYW5lIiwKICJmYW1pbHlfbmFtZSI6ICJEb2UiLAogImdlbmRlciI6ICJm ZW1hbGUiLAogImJpcnRoZGF0ZSI6ICIwMDAwLTEwLTMxIiwKICJlbWFpbCI6 ICJqYW5lZG9lQGV4YW1wbGUuY29tIiwKICJwaWN0dXJlIjogImh0dHA6Ly9l eGFtcGxlLmNvbS9qYW5lZG9lL21lLmpwZyIKfQ.rHQjEmBqn9Jre0OLykYNn spA10Qql2rvx4FsD00jwlB0Sym4NzpgvPKsDjn_wMkHxcp6CilPcoKrWHcip R2iAjzLvDNAReF97zoJqq880ZD1bwY82JDauCXELVR9O6_B0w3K-E7yM2mac AAgNCUwtik6SjoSUZRcf-O5lygIyLENx882p6MtmwaL1hd6qn5RZOQ0TLrOY u0532g9Exxcm-ChymrB4xLykpDj3lUivJt63eEGGN6DH5K6o33TcxkIjNrCD 4XB1CKKumZvCedgHHF3IAK4dVEDSUoGlH9z4pP_eWYNXvqQOjGs-rDaQzUHl 6cQQWNiDpWOl_lxXjQEvQ &state=af0ifjsldkj
The value of the id_token parameter is the ID Token, which is a signed JWT, containing three base64url encoded segments separated by period ('.') characters. The first segment represents the JOSE Header. Base64url decoding it will result in the following set of Header Parameters:
{"kid":"1e9gdk7","alg":"RS256"}
The alg value represents the algorithm that was used to sign the JWT, in this case RS256, representing RSASSA-PKCS-v1_5 using SHA-256. The kid value is a key identifier used in identifying the key to be used to verify the signature. If the kid value is unknown to the RP, it needs to retrieve the contents of the OP's JWK Set again to obtain the OP's current set of keys.
The second segment represents the Claims in the ID Token. Verifying and decoding the ID Token will yield the following Claims:
{ "iss": "http://server.example.com", "sub": "248289761001", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp":<PHONE_NUMBER>, "iat":<PHONE_NUMBER>, "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "gender": "female", "birthdate": "0000-10-31", "email"<EMAIL_ADDRESS>"picture": "http://example.com/janedoe/me.jpg" }
The third segment represents the ID Token signature, which is verified as described in [JWS] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” July 2014.).
| TOC |
GET /authorize? response_type=id_token%20token &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile%20email &nonce=n-0S6_WzA2Mj &state=af0ifjsldkj HTTP/1.1 Host: server.example.com HTTP/1.1 302 Found Location: https://client.example.org/cb# access_token=jHkWEdUXMU1BwAsC4vtUsZwnNvTIxEl0z9K3vx5KF0Y &token_type=Bearer &id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogIml zcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ 4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiA ibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDE zMTEyODA5NzAsCiAiYXRfaGFzaCI6ICI3N1FtVVB0alBmeld0RjJBbnBLOVJ RIgp9.F9gRev0Dt2tKcrBkHy72cmRqnLdzw9FLCCSebV7mWs7o_sv2O5s6zM ky2kmhHTVx9HmdvNnx9GaZ8XMYRFeYk8L5NZ7aYlA5W56nsG1iWOou_-gji0 ibWIuuf4Owaho3YSoi7EvsTuLFz6tq-dLyz0dKABMDsiCmJ5wqkPUDTE3QTX jzbUmOzUDli-gCh5QPuZAq0cNW3pf_2n4zpvTYtbmj12cVcxGIMZby7TMWES RjQ9_o3jvhVNcCGcE0KAQXejhA1ocJhNEvQNqMFGlBb6_0RxxKjDZ-Oa329e GDidOvvp0h5hoES4a8IuGKS7NOcpp-aFwp0qVMDLI-Xnm-Pg &state=af0ifjsldkj
Verifying and decoding the ID Token will yield the following Claims:
{ "iss": "http://server.example.com", "sub": "248289761001", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp":<PHONE_NUMBER>, "iat":<PHONE_NUMBER>, "at_hash": "77QmUPtjPfzWtF2AnpK9RQ" }
| TOC |
GET /authorize? response_type=code%20id_token &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile%20email &nonce=n-0S6_WzA2Mj &state=af0ifjsldkj HTTP/1.1 Host: server.example.com HTTP/1.1 302 Found Location: https://client.example.org/cb# code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk &id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogIml zcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ 4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiA ibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDE zMTEyODA5NzAsCiAiY19oYXNoIjogIkxEa3RLZG9RYWszUGswY25YeENsdEE iCn0.XW6uhdrkBgcGx6zVIrCiROpWURs-4goO1sKA4m9jhJIImiGg5muPUcN egx6sSv43c5DSn37sxCRrDZZm4ZPBKKgtYASMcE20SDgvYJdJS0cyuFw7Ijp _7WnIjcrl6B5cmoM6ylCvsLMwkoQAxVublMwH10oAxjzD6NEFsu9nipkszWh sPePf_rM4eMpkmCbTzume-fzZIi5VjdWGGEmzTg32h3jiex-r5WTHbj-u5HL 7u_KP3rmbdYNzlzd1xWRYTUs4E8nOTgzAUwvwXkIQhOh5TPcSMBYy6X3E7-_ gr9Ue6n4ND7hTFhtjYs3cjNKIA08qm5cpVYFMFMG6PkhzLQ &state=af0ifjsldkj
Verifying and decoding the ID Token will yield the following Claims:
{ "iss": "http://server.example.com", "sub": "248289761001", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp":<PHONE_NUMBER>, "iat":<PHONE_NUMBER>, "c_hash": "LDktKdoQak3Pk0cnXxCltA" }
| TOC |
GET /authorize? response_type=code%20token &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile%20email &nonce=n-0S6_WzA2Mj &state=af0ifjsldkj HTTP/1.1 Host: server.example.com HTTP/1.1 302 Found Location: https://client.example.org/cb# code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk &access_token=jHkWEdUXMU1BwAsC4vtUsZwnNvTIxEl0z9K3vx5KF0Y &token_type=Bearer &state=af0ifjsldkj
| TOC |
GET /authorize? response_type=code%20id_token%20token &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=openid%20profile%20email &nonce=n-0S6_WzA2Mj &state=af0ifjsldkj HTTP/1.1 Host: server.example.com HTTP/1.1 302 Found Location: https://client.example.org/cb# code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk &access_token=jHkWEdUXMU1BwAsC4vtUsZwnNvTIxEl0z9K3vx5KF0Y &token_type=Bearer &id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogIml zcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ 4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiA ibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDE zMTEyODA5NzAsCiAiY19oYXNoIjogIkxEa3RLZG9RYWszUGswY25YeENsdEE iCn0.XW6uhdrkBgcGx6zVIrCiROpWURs-4goO1sKA4m9jhJIImiGg5muPUcN egx6sSv43c5DSn37sxCRrDZZm4ZPBKKgtYASMcE20SDgvYJdJS0cyuFw7Ijp _7WnIjcrl6B5cmoM6ylCvsLMwkoQAxVublMwH10oAxjzD6NEFsu9nipkszWh sPePf_rM4eMpkmCbTzume-fzZIi5VjdWGGEmzTg32h3jiex-r5WTHbj-u5HL 7u_KP3rmbdYNzlzd1xWRYTUs4E8nOTgzAUwvwXkIQhOh5TPcSMBYy6X3E7-_ gr9Ue6n4ND7hTFhtjYs3cjNKIA08qm5cpVYFMFMG6PkhzLQ &state=af0ifjsldkj
Verifying and decoding the ID Token will yield the following Claims:
{ "iss": "http://server.example.com", "sub": "248289761001", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp":<PHONE_NUMBER>, "iat":<PHONE_NUMBER>, "at_hash": "77QmUPtjPfzWtF2AnpK9RQ", "c_hash": "LDktKdoQak3Pk0cnXxCltA" }
| TOC |
The following RSA public key, represented in JWK format, can be used to validate the ID Token signatures in the above examples (with line wraps within values for display purposes only):
{ "kty":"RSA", "kid":"1e9gdk7", "n":"w7Zdfmece8iaB0kiTY8pCtiBtzbptJmP28nSWwtdjRu0f2GFpajvWE4VhfJA jEsOcwYzay7XGN0b-X84BfC8hmCTOj2b2eHT7NsZegFPKRUQzJ9wW8ipn_aD JWMGDuB1XyqT1E7DYqjUCEOD1b4FLpy_xPn6oV_TYOfQ9fZdbE5HGxJUzeku GcOKqOQ8M7wfYHhHHLxGpQVgL0apWuP2gDDOdTtpuld4D2LK1MZK99s9gaSj RHE8JDb1Z4IGhEcEyzkxswVdPndUWzfvWBBWXWxtSUvQGBRkuy1BHOa4sP6F KjWEeeF7gm7UMs2Nm2QUgNZw6xvEDGaLk4KASdIxRQ", "e":"AQAB" }
| TOC |
As a successor version of OpenID, this specification heavily relies on ideas explored in OpenID Authentication 2.0 (OpenID Foundation, “OpenID Authentication 2.0,” December 2007.) [OpenID.2.0]. Please refer to Appendix C of OpenID Authentication 2.0 for the full list of the contributors for that specification.
In addition, the OpenID Community would like to thank the following people for their contributions to this specification:
Naveen Agarwal (naa@google.com), Google
Amanda Anganes (aanganes@mitre.org), MITRE
Casper Biering (cb@peercraft.com), Peercraft
John Bradley (ve7jtb@ve7jtb.com), Ping Identity
Tim Bray (tbray@textuality.com), Google
Johnny Bufu (jbufu@janrain.com), Janrain
Brian Campbell (bcampbell@pingidentity.com), Ping Identity
Blaine Cook (romeda@gmail.com), Independent
Breno de Medeiros (breno@google.com), Google
Pamela Dingle (pdingle@pingidentity.com), Ping Identity
Vladimir Dzhuvinov (vladimir@nimbusds.com), Nimbus Directory Services
George Fletcher (george.fletcher@corp.aol.com), AOL
Roland Hedberg (roland.hedberg@adm.umu.se), University of Umea
Ryo Ito (ryo.ito@mixi.co.jp), mixi, Inc.
Edmund Jay (ejay@mgi1.com), Illumila
Michael B. Jones (mbj@microsoft.com), Microsoft
Torsten Lodderstedt (t.lodderstedt@telekom.de), Deutsche Telekom
Nov Matake (nov@matake.jp), Independent
Chuck Mortimore (cmortimore@salesforce.com), Salesforce
Anthony Nadalin (tonynad@microsoft.com), Microsoft
Hideki Nara (hdknr@ic-tact.co.jp), Tact Communications
Axel Nennker (axel.nennker@telekom.de), Deutsche Telekom
David Recordon (dr@fb.com), Facebook
Justin Richer (jricher@mitre.org), MITRE
Nat Sakimura (n-sakimura@nri.co.jp), Nomura Research Institute, Ltd.
Luke Shepard (lshepard@fb.com), Facebook
Andreas Åkre Solberg (andreas.solberg@uninett.no), UNINET
Paul Tarjan (pt@fb.com), Facebook
| TOC |
Copyright (c) 2014 The OpenID Foundation.
The OpenID Foundation (OIDF) grants to any Contributor, developer, implementer, or other interested party a non-exclusive, royalty free, worldwide copyright license to reproduce, prepare derivative works from, distribute, perform and display, this Implementers Draft or Final Specification solely for the purposes of (i) developing specifications, and (ii) implementing Implementers Drafts and Final Specifications based on such documents, provided that attribution be made to the OIDF as the source of the material, but that such attribution does not indicate an endorsement by the OIDF.
The technology described in this specification was made available from contributions from various sources, including members of the OpenID Foundation and others. Although the OpenID Foundation has taken steps to help ensure that the technology is available for distribution, it takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this specification or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any independent effort to identify any such rights. The OpenID Foundation and the contributors to this specification make no (and hereby expressly disclaim any) warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to this specification, and the entire risk as to implementing this specification is assumed by the implementer. The OpenID Intellectual Property Rights policy requires contributors to offer a patent promise not to assert certain patent claims against other contributors and against implementers. The OpenID Foundation invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology that may be required to practice this specification.
| TOC |
| Nat Sakimura | |
| Nomura Research Institute, Ltd. | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://nat.sakimura.org/ |
| John Bradley | |
| Ping Identity | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://www.thread-safe.com/ |
| Michael B. Jones | |
| Microsoft | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://self-issued.info/ |
| Breno de Medeiros | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://stackoverflow.com/users/311376/breno |
| Chuck Mortimore | |
| Salesforce | |
| Email: |<EMAIL_ADDRESS>|
| URI: | https://twitter.com/cmort |


This tutorial focuses on the boto interface to the Simple Storage Service from Amazon Web Services. This tutorial assumes that you have already downloaded and installed boto.
The first step in accessing S3 is to create a connection to the service. There are two ways to do this in boto. The first is:
>>> from boto.s3.connection import S3Connection
>>> conn = S3Connection('<aws access key>', '<aws secret key>')
At this point the variable conn will point to an S3Connection object. In this example, the AWS access key and AWS secret key are passed in to the method explicitely. Alternatively, you can set the environment variables:
and then call the constructor without any arguments, like this:
>>> conn = S3Connection()
There is also a shortcut function in the boto package, called connect_s3 that may provide a slightly easier means of creating a connection:
>>> import boto
>>> conn = boto.connect_s3()
In either case, conn will point to an S3Connection object which we will use throughout the remainder of this tutorial.
Once you have a connection established with S3, you will probably want to create a bucket. A bucket is a container used to store key/value pairs in S3. A bucket can hold an unlimited amount of data so you could potentially have just one bucket in S3 for all of your information. Or, you could create separate buckets for different types of data. You can figure all of that out later, first let’s just create a bucket. That can be accomplished like this:
>>> bucket = conn.create_bucket('mybucket')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "boto/connection.py", line 285, in create_bucket
raise S3CreateError(response.status, response.reason)
boto.exception.S3CreateError: S3Error[409]: Conflict
Whoa. What happened there? Well, the thing you have to know about buckets is that they are kind of like domain names. It’s one flat name space that everyone who uses S3 shares. So, someone has already create a bucket called “mybucket” in S3 and that means no one else can grab that bucket name. So, you have to come up with a name that hasn’t been taken yet. For example, something that uses a unique string as a prefix. Your AWS_ACCESS_KEY (NOT YOUR SECRET KEY!) could work but I’ll leave it to your imagination to come up with something. I’ll just assume that you found an acceptable name.
The create_bucket method will create the requested bucket if it does not exist or will return the existing bucket if it does exist.
The example above assumes that you want to create a bucket in the standard US region. However, it is possible to create buckets in other locations. To do so, first import the Location object from the boto.s3.connection module, like this:
>>> from boto.s3.connection import Location
>>> print '\n'.join(i for i in dir(Location) if i[0].isupper())
APNortheast
APSoutheast
APSoutheast2
DEFAULT
EU
SAEast
USWest
USWest2
As you can see, the Location object defines a number of possible locations. By default, the location is the empty string which is interpreted as the US Classic Region, the original S3 region. However, by specifying another location at the time the bucket is created, you can instruct S3 to create the bucket in that location. For example:
>>> conn.create_bucket('mybucket', location=Location.EU)
will create the bucket in the EU region (assuming the name is available).
Once you have a bucket, presumably you will want to store some data in it. S3 doesn’t care what kind of information you store in your objects or what format you use to store it. All you need is a key that is unique within your bucket.
The Key object is used in boto to keep track of data stored in S3. To store new data in S3, start by creating a new Key object:
>>> from boto.s3.key import Key
>>> k = Key(bucket)
>>> k.key = 'foobar'
>>> k.set_contents_from_string('This is a test of S3')
The net effect of these statements is to create a new object in S3 with a key of “foobar” and a value of “This is a test of S3”. To validate that this worked, quit out of the interpreter and start it up again. Then:
>>> import boto
>>> c = boto.connect_s3()
>>> b = c.get_bucket('mybucket') # substitute your bucket name here
>>> from boto.s3.key import Key
>>> k = Key(b)
>>> k.key = 'foobar'
>>> k.get_contents_as_string()
'This is a test of S3'
So, we can definitely store and retrieve strings. A more interesting example may be to store the contents of a local file in S3 and then retrieve the contents to another local file.
>>> k = Key(b)
>>> k.key = 'myfile'
>>> k.set_contents_from_filename('foo.jpg')
>>> k.get_contents_to_filename('bar.jpg')
There are a couple of things to note about this. When you send data to S3 from a file or filename, boto will attempt to determine the correct mime type for that file and send it as a Content-Type header. The boto package uses the standard mimetypes package in Python to do the mime type guessing. The other thing to note is that boto does stream the content to and from S3 so you should be able to send and receive large files without any problem.
When fetching a key that has already exists, you have two options. If you’re uncertain whether a key exists (or if you need the metadata set on it, you can call Bucket.get_key(key_name_here). However, if you’re sure a key already exists within a bucket, you can skip the check for a key on the server.
>>> import boto
>>> c = boto.connect_s3()
>>> b = c.get_bucket('mybucket') # substitute your bucket name here
# Will hit the API to check if it exists.
>>> possible_key = b.get_key('mykey') # substitute your key name here
# Won't hit the API.
>>> key_we_know_is_there = b.get_key('mykey', validate=False)
At times the data you may want to store will be hundreds of megabytes or more in size. S3 allows you to split such files into smaller components. You upload each component in turn and then S3 combines them into the final object. While this is fairly straightforward, it requires a few extra steps to be taken. The example below makes use of the FileChunkIO module, so pip install FileChunkIO if it isn’t already installed.
>>> import math, os
>>> import boto
>>> from filechunkio import FileChunkIO
# Connect to S3
>>> c = boto.connect_s3()
>>> b = c.get_bucket('mybucket')
# Get file info
>>> source_path = 'path/to/your/file.ext'
>>> source_size = os.stat(source_path).st_size
# Create a multipart upload request
>>> mp = b.initiate_multipart_upload(os.path.basename(source_path))
# Use a chunk size of 50 MiB (feel free to change this)
>>> chunk_size = 52428800
>>> chunk_count = int(math.ceil(source_size / chunk_size))
# Send the file parts, using FileChunkIO to create a file-like object
# that points to a certain byte range within the original file. We
# set bytes to never exceed the original file size.
>>> for i in range(chunk_count + 1):
>>> offset = chunk_size * i
>>> bytes = min(chunk_size, source_size - offset)
>>> with FileChunkIO(source_path, 'r', offset=offset,
bytes=bytes) as fp:
>>> mp.upload_part_from_file(fp, part_num=i + 1)
# Finish the upload
>>> mp.complete_upload()
It is also possible to upload the parts in parallel using threads. The s3put script that ships with Boto provides an example of doing so using a thread pool.
Note that if you forget to call either mp.complete_upload() or mp.cancel_upload() you will be left with an incomplete upload and charged for the storage consumed by the uploaded parts. A call to bucket.get_all_multipart_uploads() can help to show lost multipart upload parts.
Once a bucket exists, you can access it by getting the bucket. For example:
>>> mybucket = conn.get_bucket('mybucket') # Substitute in your bucket name
>>> mybucket.list()
...listing of keys in the bucket...
By default, this method tries to validate the bucket’s existence. You can override this behavior by passing validate=False.:
>>> nonexistent = conn.get_bucket('i-dont-exist-at-all', validate=False)
Changed in version 2.25.0.
Warning
If validate=False is passed, no request is made to the service (no charge/communication delay). This is only safe to do if you are sure the bucket exists.
If the default validate=True is passed, a request is made to the service to ensure the bucket exists. Prior to Boto v2.25.0, this fetched a list of keys (but with a max limit set to 0, always returning an empty list) in the bucket (& included better error messages), at an increased expense. As of Boto v2.25.0, this now performs a HEAD request (less expensive but worse error messages).
If you were relying on parsing the error message before, you should call something like:
bucket = conn.get_bucket('<bucket_name>', validate=False)
bucket.get_all_keys(maxkeys=0)
If the bucket does not exist, a S3ResponseError will commonly be thrown. If you’d rather not deal with any exceptions, you can use the lookup method.:
>>> nonexistent = conn.lookup('i-dont-exist-at-all')
>>> if nonexistent is None:
... print "No such bucket!"
...
No such bucket!
Removing a bucket can be done using the delete_bucket method. For example:
>>> conn.delete_bucket('mybucket') # Substitute in your bucket name
The bucket must be empty of keys or this call will fail & an exception will be raised.  Delete them all.
>>> for key in full_bucket.list():
... key.delete()
...
# The bucket is empty now. Delete it.
>>> conn.delete_bucket('bucket-to-delete')
Warning
This method can cause data loss! Be very careful when using it.
Additionally, be aware that using the above method for removing all keys and deleting the bucket involves a request for each key. As such, it’s not particularly fast & is very chatty.
In addition to accessing specific buckets via the create_bucket method you can also get a list of all available buckets that you have created.
>>> rs = conn.get_all_buckets()
This returns a ResultSet object (see the SQS Tutorial for more info on ResultSet objects). The ResultSet can be used as a sequence or list type object to retrieve Bucket objects.
>>> len(rs)
11
>>> for b in rs:
... print b.name
...
<listing of available buckets>
>>> b = rs[0]
The S3 service provides the ability to control access to buckets and keys within s3 via the Access Control List (ACL) associated with each object in S3. There are two ways to set the ACL for an object:
To set a canned ACL for a bucket, use the set_acl method of the Bucket object. The argument passed to this method must be one of the four permissable canned policies named in the list CannedACLStrings contained in acl.py. For example, to make a bucket readable by anyone:
>>> b.set_acl('public-read')
You can also set the ACL for Key objects, either by passing an additional argument to the above method:
>>> b.set_acl('public-read', 'foobar')
where ‘foobar’ is the key of some object within the bucket b or you can call the set_acl method of the Key object:
>>> k.set_acl('public-read')
You can also retrieve the current ACL for a Bucket or Key object using the get_acl object. This method parses the AccessControlPolicy response sent by S3 and creates a set of Python objects that represent the ACL.
>>> acp = b.get_acl()
>>> acp
<boto.acl.Policy instance at 0x2e6940>
>>> acp.acl
<boto.acl.ACL instance at 0x2e69e0>
>>> acp.acl.grants
[<boto.acl.Grant instance at 0x2e6a08>]
>>> for grant in acp.acl.grants:
... print grant.permission, grant.display_name, grant.email_address, grant.id
...
FULL_CONTROL <boto.user.User instance at 0x2e6a30>
The Python objects representing the ACL can be found in the acl.py module of boto.
Both the Bucket object and the Key object also provide shortcut methods to simplify the process of granting individuals specific access. For example, if you want to grant an individual user READ access to a particular object in S3 you could do the following:
>>> key = b.lookup('mykeytoshare')
>>> key.add_email_grant('READ'<EMAIL_ADDRESS>The email address provided should be the one associated with the users AWS account. There is a similar method called add_user_grant that accepts the canonical id of the user rather than the email address.
S3 allows arbitrary user metadata to be assigned to objects within a bucket. To take advantage of this S3 feature, you should use the set_metadata and get_metadata methods of the Key object to set and retrieve metadata associated with an S3 object. For example:
>>> k = Key(b)
>>> k.key = 'has_metadata'
>>> k.set_metadata('meta1', 'This is the first metadata value')
>>> k.set_metadata('meta2', 'This is the second metadata value')
>>> k.set_contents_from_filename('foo.txt')
This code associates two metadata key/value pairs with the Key k. To retrieve those values later:
>>> k = b.get_key('has_metadata')
>>> k.get_metadata('meta1')
'This is the first metadata value'
>>> k.get_metadata('meta2')
'This is the second metadata value'
>>>
Cross-origin resource sharing (CORS) defines a way for client web applications that are loaded in one domain to interact with resources in a different domain. With CORS support in Amazon S3, you can build rich client-side web applications with Amazon S3 and selectively allow cross-origin access to your Amazon S3 resources.
To create a CORS configuration and associate it with a bucket:
>>> from boto.s3.cors import CORSConfiguration
>>> cors_cfg = CORSConfiguration()
>>> cors_cfg.add_rule(['PUT', 'POST', 'DELETE'], 'https://www.example.com', allowed_header='*', max_age_seconds=3000, expose_header='x-amz-server-side-encryption')
>>> cors_cfg.add_rule('GET', '*')
The above code creates a CORS configuration object with two rules.
To associate this configuration with a bucket:
>>> import boto
>>> c = boto.connect_s3()
>>> bucket = c.lookup('mybucket')
>>> bucket.set_cors(cors_cfg)
To retrieve the CORS configuration associated with a bucket:
>>> cors_cfg = bucket.get_cors()
And, finally, to delete all CORS configurations from a bucket:
>>> bucket.delete_cors()
You can configure objects in S3 to transition to Glacier after a period of time. This is done using lifecycle policies. A lifecycle policy can also specify that an object should be deleted after a period of time. Lifecycle configurations are assigned to buckets and require these parameters:
For example, given a bucket s3-glacier-boto-demo, we can first retrieve the bucket:
>>> import boto
>>> c = boto.connect_s3()
>>> bucket = c.get_bucket('s3-glacier-boto-demo')
Then we can create a lifecycle object. In our example, we want all objects under logs/* to transition to Glacier 30 days after the object is created.
>>> from boto.s3.lifecycle import Lifecycle, Transition, Rule
>>> to_glacier = Transition(days=30, storage_class='GLACIER')
>>> rule = Rule('ruleid', 'logs/', 'Enabled', transition=to_glacier)
>>> lifecycle = Lifecycle()
>>> lifecycle.append(rule)
Note
For API docs for the lifecycle objects, see boto.s3.lifecycle
We can now configure the bucket with this lifecycle policy:
>>> bucket.configure_lifecycle(lifecycle)
True
You can also retrieve the current lifecycle policy for the bucket:
>>> current = bucket.get_lifecycle_config()
>>> print current[0].transition
<Transition: in: 30 days, GLACIER>
When an object transitions to Glacier, the storage class will be updated. This can be seen when you list the objects in a bucket:
>>> for key in bucket.list():
... print key, key.storage_class
...
<Key: s3-glacier-boto-demo,logs/testlog1.log> GLACIER
You can also use the prefix argument to the bucket.list method:
>>> print list(b.list(prefix='logs/testlog1.log'))[0].storage_class
u'GLACIER'
Once an object has been transitioned to Glacier, you can restore the object back to S3. To do so, you can use the boto.s3.key.Key.restore() method of the key object. The restore method takes an integer that specifies the number of days to keep the object in S3.
>>> import boto
>>> c = boto.connect_s3()
>>> bucket = c.get_bucket('s3-glacier-boto-demo')
>>> key = bucket.get_key('logs/testlog1.log')
>>> key.restore(days=5)
It takes about 4 hours for a restore operation to make a copy of the archive available for you to access. While the object is being restored, the ongoing_restore attribute will be set to True:
>>> key = bucket.get_key('logs/testlog1.log')
>>> print key.ongoing_restore
True
When the restore is finished, this value will be False and the expiry date of the object will be non None:
>>> key = bucket.get_key('logs/testlog1.log')
>>> print key.ongoing_restore
False
>>> print key.expiry_date
"Fri, 21 Dec 2012 00:00:00 GMT"
Note
If there is no restore operation either in progress or completed, the ongoing_restore attribute will be None.
Once the object is restored you can then download the contents:
>>> key.get_contents_to_filename('testlog1.log')


Tell me a little something about yourself.
As much as the next Information Tech. student, I sincerely and honestly want to
know as much as you'll tell me about yourself. To this effect, I've set up this
nice little form for you to fill out. Once you're done giving me all of your
information, click submit!
Don't worry about me using your information in malicious ways, I'll just be running a simple php script located on a different server. That's a technical way of saying that everything you enter is going to be echoed back to you.
Don't worry about me using your information in malicious ways, I'll just be running a simple php script located on a different server. That's a technical way of saying that everything you enter is going to be echoed back to you.
Form


Another employee dies
Jafar was conductor in Medak depot
by Staff ReporterA 32-year-old TSRTC employee who suffered brain stroke, died at a private hospital in Hyderabad on Wednesday.
The employee, Sheik Jafar, used to work as a conductor with the corporation at Medak depot.
His family member, Hussain, said that Jafar was worried whether he would get back the job and that anxiety led to brain stroke on November 13.
He was initially taken to the Telangana State Road Transport Corporation’s (TSRTC) Hospital in Tarnaka, from where he was referred to Sai Sajeevani Hospital in Saroornagar.
Jafar is survived by wife Majeeunnisa, a son and daughter. She is expecting their third child.
Jafar’s body was brought to Salabatpur in Kowdipally mandal for performing last rites.
Meanwhile, an office-bearer of the National Mazdoor Union (NMU), E Ashok, requested the State government to give government jobs to family members of RTC employees who died.
A total of 27 people have died since the strike was launched on October 5.
Mr. Ashok further requested the government to issue ₹1,000 crore for payment of pending salaries of employees. A few employees have retired in the past two months. Full and final settlement was requested to be processed.