diff options
Diffstat (limited to 'oauthlib')
-rw-r--r-- | oauthlib/oauth1/rfc5849/request_validator.py | 4 | ||||
-rw-r--r-- | oauthlib/oauth2/rfc6749/clients/base.py | 155 | ||||
-rw-r--r-- | oauthlib/oauth2/rfc6749/endpoints/introspect.py | 10 | ||||
-rw-r--r-- | oauthlib/oauth2/rfc6749/request_validator.py | 5 | ||||
-rw-r--r-- | oauthlib/oauth2/rfc8628/clients/device.py | 4 | ||||
-rw-r--r-- | oauthlib/openid/connect/core/endpoints/userinfo.py | 21 |
6 files changed, 92 insertions, 107 deletions
diff --git a/oauthlib/oauth1/rfc5849/request_validator.py b/oauthlib/oauth1/rfc5849/request_validator.py index dc5bf0e..d8e4ee4 100644 --- a/oauthlib/oauth1/rfc5849/request_validator.py +++ b/oauthlib/oauth1/rfc5849/request_validator.py @@ -443,7 +443,7 @@ class RequestValidator: :type request: oauthlib.common.Request :returns: None - Per `Section 2.3`__ of the spec: + Per `Section 2.3`_ of the spec: "The server MUST (...) ensure that the temporary credentials have not expired or been used before." @@ -831,7 +831,7 @@ class RequestValidator: """Associate an authorization verifier with a request token. :param token: A request token string. - :param verifier A dictionary containing the oauth_verifier and + :param verifier: A dictionary containing the oauth_verifier and oauth_token :param request: OAuthlib request. :type request: oauthlib.common.Request diff --git a/oauthlib/oauth2/rfc6749/clients/base.py b/oauthlib/oauth2/rfc6749/clients/base.py index bb4c133..6a5d0dc 100644 --- a/oauthlib/oauth2/rfc6749/clients/base.py +++ b/oauthlib/oauth2/rfc6749/clients/base.py @@ -228,26 +228,21 @@ class Client: required parameters to the authorization URL. :param authorization_url: Provider authorization endpoint URL. - :param state: CSRF protection string. Will be automatically created if - not provided. The generated state is available via the ``state`` - attribute. Clients should verify that the state is unchanged and - present in the authorization response. This verification is done - automatically if using the ``authorization_response`` parameter - with ``prepare_token_request``. - + not provided. The generated state is available via the ``state`` + attribute. Clients should verify that the state is unchanged and + present in the authorization response. This verification is done + automatically if using the ``authorization_response`` parameter + with ``prepare_token_request``. :param redirect_url: Redirect URL to which the user will be returned - after authorization. Must be provided unless previously setup with - the provider. If provided then it must also be provided in the - token request. - + after authorization. Must be provided unless previously setup with + the provider. If provided then it must also be provided in the + token request. :param scope: List of scopes to request. Must be equal to - or a subset of the scopes granted when obtaining the refresh - token. If none is provided, the ones provided in the constructor are - used. - + or a subset of the scopes granted when obtaining the refresh + token. If none is provided, the ones provided in the constructor are + used. :param kwargs: Additional parameters to included in the request. - :returns: The prepared request tuple with (url, headers, body). """ if not is_secure_transport(authorization_url): @@ -271,22 +266,16 @@ class Client: credentials. :param token_url: Provider token creation endpoint URL. - :param authorization_response: The full redirection URL string, i.e. - the location to which the user was redirected after successfull - authorization. Used to mine credentials needed to obtain a token - in this step, such as authorization code. - + the location to which the user was redirected after successfull + authorization. Used to mine credentials needed to obtain a token + in this step, such as authorization code. :param redirect_url: The redirect_url supplied with the authorization - request (if there was one). - + request (if there was one). :param state: - :param body: Existing request body (URL encoded string) to embed parameters into. This may contain extra paramters. Default ''. - :param kwargs: Additional parameters to included in the request. - :returns: The prepared request tuple with (url, headers, body). """ if not is_secure_transport(token_url): @@ -312,19 +301,14 @@ class Client: obtain a new access token, and possibly a new refresh token. :param token_url: Provider token refresh endpoint URL. - :param refresh_token: Refresh token string. - :param body: Existing request body (URL encoded string) to embed parameters - into. This may contain extra paramters. Default ''. - + into. This may contain extra paramters. Default ''. :param scope: List of scopes to request. Must be equal to - or a subset of the scopes granted when obtaining the refresh - token. If none is provided, the ones provided in the constructor are - used. - + or a subset of the scopes granted when obtaining the refresh + token. If none is provided, the ones provided in the constructor are + used. :param kwargs: Additional parameters to included in the request. - :returns: The prepared request tuple with (url, headers, body). """ if not is_secure_transport(token_url): @@ -341,20 +325,14 @@ class Client: """Prepare a token revocation request. :param revocation_url: Provider token revocation endpoint URL. - :param token: The access or refresh token to be revoked (string). - :param token_type_hint: ``"access_token"`` (default) or - ``"refresh_token"``. This is optional and if you wish to not pass it you - must provide ``token_type_hint=None``. - + ``"refresh_token"``. This is optional and if you wish to not pass it you + must provide ``token_type_hint=None``. :param body: - :param callback: A jsonp callback such as ``package.callback`` to be invoked - upon receiving the response. Not that it should not include a () suffix. - + upon receiving the response. Not that it should not include a () suffix. :param kwargs: Additional parameters to included in the request. - :returns: The prepared request tuple with (url, headers, body). Note that JSONP request may use GET requests as the parameters will @@ -362,7 +340,7 @@ class Client: An example of a revocation request - .. code-block: http + .. code-block:: http POST /revoke HTTP/1.1 Host: server.example.com @@ -373,7 +351,7 @@ class Client: An example of a jsonp revocation request - .. code-block: http + .. code-block:: http GET /revoke?token=agabcdefddddafdd&callback=package.myCallback HTTP/1.1 Host: server.example.com @@ -382,9 +360,9 @@ class Client: and an error response - .. code-block: http + .. code-block:: javascript - package.myCallback({"error":"unsupported_token_type"}); + package.myCallback({"error":"unsupported_token_type"}); Note that these requests usually require client credentials, client_id in the case for public clients and provider specific authentication @@ -408,9 +386,10 @@ class Client: :param body: The response body from the token request. :param scope: Scopes originally requested. If none is provided, the ones - provided in the constructor are used. + provided in the constructor are used. :return: Dictionary of token parameters. - :raises: Warning if scope has changed. OAuth2Error if response is invalid. + :raises: Warning if scope has changed. :py:class:`oauthlib.oauth2.errors.OAuth2Error` + if response is invalid. These response are json encoded and could easily be parsed without the assistance of OAuthLib. However, there are a few subtle issues @@ -436,7 +415,7 @@ class Client: If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value. - **scope** + **scope** Providers may supply this in all responses but are required to only if it has changed since the authorization request. @@ -454,20 +433,16 @@ class Client: If the authorization server issued a refresh token to the client, the client makes a refresh request to the token endpoint by adding the - following parameters using the "application/x-www-form-urlencoded" + following parameters using the `application/x-www-form-urlencoded` format in the HTTP request entity-body: - grant_type - REQUIRED. Value MUST be set to "refresh_token". - refresh_token - REQUIRED. The refresh token issued to the client. - scope - OPTIONAL. The scope of the access request as described by - Section 3.3. The requested scope MUST NOT include any scope - not originally granted by the resource owner, and if omitted is - treated as equal to the scope originally granted by the - resource owner. Note that if none is provided, the ones provided - in the constructor are used if any. + :param refresh_token: REQUIRED. The refresh token issued to the client. + :param scope: OPTIONAL. The scope of the access request as described by + Section 3.3. The requested scope MUST NOT include any scope + not originally granted by the resource owner, and if omitted is + treated as equal to the scope originally granted by the + resource owner. Note that if none is provided, the ones provided + in the constructor are used if any. """ refresh_token = refresh_token or self.refresh_token scope = self.scope if scope is None else scope @@ -492,18 +467,21 @@ class Client: def create_code_verifier(self, length): """Create PKCE **code_verifier** used in computing **code_challenge**. + See `RFC7636 Section 4.1`_ + + :param length: REQUIRED. The length of the code_verifier. - :param length: REQUIRED. The length of the code_verifier. + The client first creates a code verifier, "code_verifier", for each + OAuth 2.0 [RFC6749] Authorization Request, in the following manner: - The client first creates a code verifier, "code_verifier", for each - OAuth 2.0 [RFC6749] Authorization Request, in the following manner: + .. code-block:: text - code_verifier = high-entropy cryptographic random STRING using the - unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" - from Section 2.3 of [RFC3986], with a minimum length of 43 characters - and a maximum length of 128 characters. - - .. _`Section 4.1`: https://tools.ietf.org/html/rfc7636#section-4.1 + code_verifier = high-entropy cryptographic random STRING using the + unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" + from Section 2.3 of [RFC3986], with a minimum length of 43 characters + and a maximum length of 128 characters. + + .. _`RFC7636 Section 4.1`: https://tools.ietf.org/html/rfc7636#section-4.1 """ code_verifier = None @@ -525,33 +503,30 @@ class Client: def create_code_challenge(self, code_verifier, code_challenge_method=None): """Create PKCE **code_challenge** derived from the **code_verifier**. + See `RFC7636 Section 4.2`_ - :param code_verifier: REQUIRED. The **code_verifier** generated from create_code_verifier(). - :param code_challenge_method: OPTIONAL. The method used to derive the **code_challenge**. Acceptable - values include "S256". DEFAULT is "plain". - + :param code_verifier: REQUIRED. The **code_verifier** generated from `create_code_verifier()`. + :param code_challenge_method: OPTIONAL. The method used to derive the **code_challenge**. Acceptable values include `S256`. DEFAULT is `plain`. - The client then creates a code challenge derived from the code + The client then creates a code challenge derived from the code verifier by using one of the following transformations on the code - verifier: - - plain - code_challenge = code_verifier + verifier:: - S256 - code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) + plain + code_challenge = code_verifier + S256 + code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) - If the client is capable of using "S256", it MUST use "S256", as - "S256" is Mandatory To Implement (MTI) on the server. Clients are - permitted to use "plain" only if they cannot support "S256" for some + If the client is capable of using `S256`, it MUST use `S256`, as + `S256` is Mandatory To Implement (MTI) on the server. Clients are + permitted to use `plain` only if they cannot support `S256` for some technical reason and know via out-of-band configuration that the - server supports "plain". + server supports `plain`. The plain transformation is for compatibility with existing - deployments and for constrained environments that can't use the S256 - transformation. + deployments and for constrained environments that can't use the S256 transformation. - .. _`Section 4.2`: https://tools.ietf.org/html/rfc7636#section-4.2 + .. _`RFC7636 Section 4.2`: https://tools.ietf.org/html/rfc7636#section-4.2 """ code_challenge = None diff --git a/oauthlib/oauth2/rfc6749/endpoints/introspect.py b/oauthlib/oauth2/rfc6749/endpoints/introspect.py index 63570d9..3cc61e6 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/introspect.py +++ b/oauthlib/oauth2/rfc6749/endpoints/introspect.py @@ -86,9 +86,9 @@ class IntrospectEndpoint(BaseEndpoint): an HTTP POST request with parameters sent as "application/x-www-form-urlencoded". - token REQUIRED. The string value of the token. + * token REQUIRED. The string value of the token. + * token_type_hint OPTIONAL. - token_type_hint OPTIONAL. A hint about the type of the token submitted for introspection. The protected resource MAY pass this parameter to help the authorization server optimize the token lookup. If the @@ -96,11 +96,9 @@ class IntrospectEndpoint(BaseEndpoint): extend its search across all of its supported token types. An authorization server MAY ignore this parameter, particularly if it is able to detect the token type automatically. - * access_token: An Access Token as defined in [`RFC6749`], - `section 1.4`_ - * refresh_token: A Refresh Token as defined in [`RFC6749`], - `section 1.5`_ + * access_token: An Access Token as defined in [`RFC6749`], `section 1.4`_ + * refresh_token: A Refresh Token as defined in [`RFC6749`], `section 1.5`_ The introspection endpoint MAY accept other OPTIONAL parameters to provide further context to the query. For diff --git a/oauthlib/oauth2/rfc6749/request_validator.py b/oauthlib/oauth2/rfc6749/request_validator.py index 02a13fa..c047445 100644 --- a/oauthlib/oauth2/rfc6749/request_validator.py +++ b/oauthlib/oauth2/rfc6749/request_validator.py @@ -191,6 +191,7 @@ class RequestValidator: claims associated, or `None` in case the token is unknown. Below the list of registered claims you should be interested in: + - scope : space-separated list of scopes - client_id : client identifier - username : human-readable identifier for the resource owner @@ -204,7 +205,7 @@ class RequestValidator: - jti : string identifier for the token Note that most of them are coming directly from JWT RFC. More details - can be found in `Introspect Claims`_ or `_JWT Claims`_. + can be found in `Introspect Claims`_ or `JWT Claims`_. The implementation can use *token_type_hint* to improve lookup efficency, but must fallback to other types to be compliant with RFC. @@ -443,6 +444,7 @@ class RequestValidator: - request.user - request.scopes - request.claims (if given) + OBS! The request.user attribute should be set to the resource owner associated with this authorization code. Similarly request.scopes must also be set. @@ -451,6 +453,7 @@ class RequestValidator: If PKCE is enabled (see 'is_pkce_required' and 'save_authorization_code') you MUST set the following based on the information stored: + - request.code_challenge - request.code_challenge_method diff --git a/oauthlib/oauth2/rfc8628/clients/device.py b/oauthlib/oauth2/rfc8628/clients/device.py index 95c4f5a..4707cc5 100644 --- a/oauthlib/oauth2/rfc8628/clients/device.py +++ b/oauthlib/oauth2/rfc8628/clients/device.py @@ -62,7 +62,7 @@ class DeviceClient(Client): body. :param body: Existing request body (URL encoded string) to embed parameters - into. This may contain extra paramters. Default ''. + into. This may contain extra parameters. Default ''. :param scope: The scope of the access request as described by `Section 3.3`_. @@ -84,6 +84,8 @@ class DeviceClient(Client): >>> client.prepare_request_body(scope=['hello', 'world']) 'grant_type=urn:ietf:params:oauth:grant-type:device_code&scope=hello+world' + .. _`Section 3.2.1`: https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1 + .. _`Section 3.3`: https://datatracker.ietf.org/doc/html/rfc6749#section-3.3 .. _`Section 3.4`: https://datatracker.ietf.org/doc/html/rfc8628#section-3.4 """ diff --git a/oauthlib/openid/connect/core/endpoints/userinfo.py b/oauthlib/openid/connect/core/endpoints/userinfo.py index 1c29cc5..7aa2bbe 100644 --- a/oauthlib/openid/connect/core/endpoints/userinfo.py +++ b/oauthlib/openid/connect/core/endpoints/userinfo.py @@ -69,7 +69,7 @@ class UserInfoEndpoint(BaseEndpoint): 5.3.1. UserInfo Request The Client sends the UserInfo Request using either HTTP GET or HTTP POST. The Access Token obtained from an OpenID Connect Authentication - Request MUST be sent as a Bearer Token, per Section 2 of OAuth 2.0 + Request MUST be sent as a Bearer Token, per `Section 2`_ of OAuth 2.0 Bearer Token Usage [RFC6750]. It is RECOMMENDED that the request use the HTTP GET method and the @@ -77,21 +77,28 @@ class UserInfoEndpoint(BaseEndpoint): The following is a non-normative example of a UserInfo Request: - GET /userinfo HTTP/1.1 - Host: server.example.com - Authorization: Bearer SlAV32hkKG + .. code-block:: http + + GET /userinfo HTTP/1.1 + Host: server.example.com + Authorization: Bearer SlAV32hkKG 5.3.3. UserInfo Error Response When an error condition occurs, the UserInfo Endpoint returns an Error - Response as defined in Section 3 of OAuth 2.0 Bearer Token Usage + Response as defined in `Section 3`_ of OAuth 2.0 Bearer Token Usage [RFC6750]. (HTTP errors unrelated to RFC 6750 are returned to the User Agent using the appropriate HTTP status code.) The following is a non-normative example of a UserInfo Error Response: - HTTP/1.1 401 Unauthorized - WWW-Authenticate: Bearer error="invalid_token", + .. code-block:: http + + HTTP/1.1 401 Unauthorized + WWW-Authenticate: Bearer error="invalid_token", error_description="The Access Token expired" + + .. _`Section 2`: https://datatracker.ietf.org/doc/html/rfc6750#section-2 + .. _`Section 3`: https://datatracker.ietf.org/doc/html/rfc6750#section-3 """ if not self.bearer.validate_request(request): raise errors.InvalidTokenError() |