resource.py 3.2 KB

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