1 # -*- coding: utf-8 -*-
3 oauthlib.oauth1.rfc5849.endpoints.signature_only
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 This module is an implementation of the signing logic of OAuth 1.0 RFC 5849.
9 from __future__ import absolute_import, unicode_literals
13 from .base import BaseEndpoint
16 log = logging.getLogger(__name__)
19 class SignatureOnlyEndpoint(BaseEndpoint):
21 """An endpoint only responsible for verifying an oauth signature."""
23 def validate_request(self, uri, http_method='GET',
24 body=None, headers=None):
25 """Validate a signed OAuth request.
27 :param uri: The full URI of the token request.
28 :param http_method: A valid HTTP verb, i.e. GET, POST, PUT, HEAD, etc.
29 :param body: The request body as a string.
30 :param headers: The request headers as a dict.
31 :returns: A tuple of 2 elements.
32 1. True if valid, False otherwise.
33 2. An oauthlib.common.Request object.
36 request = self._create_request(uri, http_method, body, headers)
37 except errors.OAuth1Error:
41 self._check_transport_security(request)
42 self._check_mandatory_parameters(request)
43 except errors.OAuth1Error:
46 if not self.request_validator.validate_timestamp_and_nonce(
47 request.client_key, request.timestamp, request.nonce, request):
50 # The server SHOULD return a 401 (Unauthorized) status code when
51 # receiving a request with invalid client credentials.
52 # Note: This is postponed in order to avoid timing attacks, instead
53 # a dummy client is assigned and used to maintain near constant
54 # time request verification.
56 # Note that early exit would enable client enumeration
57 valid_client = self.request_validator.validate_client_key(
58 request.client_key, request)
60 request.client_key = self.request_validator.dummy_client
62 valid_signature = self._check_signature(request)
64 # We delay checking validity until the very end, using dummy values for
65 # calculations and fetching secrets/keys to ensure the flow of every
66 # request remains almost identical regardless of whether valid values
67 # have been supplied. This ensures near constant time execution and
68 # prevents malicious users from guessing sensitive information
69 v = all((valid_client, valid_signature))
71 log.info("[Failure] request verification failed.")
72 log.info("Valid client: %s", valid_client)
73 log.info("Valid signature: %s", valid_signature)