resource.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """
  2. oauthlib.oauth2.rfc6749
  3. ~~~~~~~~~~~~~~~~~~~~~~~
  4. This module is an implementation of various logic needed
  5. for consuming and providing OAuth 2.0 RFC6749.
  6. """
  7. import logging
  8. from oauthlib.common import Request
  9. from .base import BaseEndpoint, catch_errors_and_unavailability
  10. log = logging.getLogger(__name__)
  11. class ResourceEndpoint(BaseEndpoint):
  12. """Authorizes access to protected resources.
  13. The client accesses protected resources by presenting the access
  14. token to the resource server. The resource server MUST validate the
  15. access token and ensure that it has not expired and that its scope
  16. covers the requested resource. The methods used by the resource
  17. server to validate the access token (as well as any error responses)
  18. are beyond the scope of this specification but generally involve an
  19. interaction or coordination between the resource server and the
  20. authorization server::
  21. # For most cases, returning a 403 should suffice.
  22. The method in which the client utilizes the access token to
  23. authenticate with the resource server depends on the type of access
  24. token issued by the authorization server. Typically, it involves
  25. using the HTTP "Authorization" request header field [RFC2617] with an
  26. authentication scheme defined by the specification of the access
  27. token type used, such as [RFC6750]::
  28. # Access tokens may also be provided in query and body
  29. https://example.com/protected?access_token=kjfch2345sdf # Query
  30. access_token=sdf23409df # Body
  31. """
  32. def __init__(self, default_token, token_types):
  33. BaseEndpoint.__init__(self)
  34. self._tokens = token_types
  35. self._default_token = default_token
  36. @property
  37. def default_token(self):
  38. return self._default_token
  39. @property
  40. def default_token_type_handler(self):
  41. return self.tokens.get(self.default_token)
  42. @property
  43. def tokens(self):
  44. return self._tokens
  45. @catch_errors_and_unavailability
  46. def verify_request(self, uri, http_method='GET', body=None, headers=None,
  47. scopes=None):
  48. """Validate client, code etc, return body + headers"""
  49. request = Request(uri, http_method, body, headers)
  50. request.token_type = self.find_token_type(request)
  51. request.scopes = scopes
  52. token_type_handler = self.tokens.get(request.token_type,
  53. self.default_token_type_handler)
  54. log.debug('Dispatching token_type %s request to %r.',
  55. request.token_type, token_type_handler)
  56. return token_type_handler.validate_request(request), request
  57. def find_token_type(self, request):
  58. """Token type identification.
  59. RFC 6749 does not provide a method for easily differentiating between
  60. different token types during protected resource access. We estimate
  61. the most likely token type (if any) by asking each known token type
  62. to give an estimation based on the request.
  63. """
  64. estimates = sorted(((t.estimate_type(request), n)
  65. for n, t in self.tokens.items()), reverse=True)
  66. return estimates[0][1] if len(estimates) else None