token.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 oauthlib.oauth2.rfc6749 import utils
  12. from .base import BaseEndpoint, catch_errors_and_unavailability
  13. log = logging.getLogger(__name__)
  14. class TokenEndpoint(BaseEndpoint):
  15. """Token issuing endpoint.
  16. The token endpoint is used by the client to obtain an access token by
  17. presenting its authorization grant or refresh token. The token
  18. endpoint is used with every authorization grant except for the
  19. implicit grant type (since an access token is issued directly).
  20. The means through which the client obtains the location of the token
  21. endpoint are beyond the scope of this specification, but the location
  22. is typically provided in the service documentation.
  23. The endpoint URI MAY include an "application/x-www-form-urlencoded"
  24. formatted (per `Appendix B`_) query component,
  25. which MUST be retained when adding additional query parameters. The
  26. endpoint URI MUST NOT include a fragment component::
  27. https://example.com/path?query=component # OK
  28. https://example.com/path?query=component#fragment # Not OK
  29. Since requests to the authorization endpoint result in user
  30. Since requests to the token endpoint result in the transmission of
  31. clear-text credentials (in the HTTP request and response), the
  32. authorization server MUST require the use of TLS as described in
  33. Section 1.6 when sending requests to the token endpoint::
  34. # We will deny any request which URI schema is not with https
  35. The client MUST use the HTTP "POST" method when making access token
  36. requests::
  37. # HTTP method is currently not enforced
  38. Parameters sent without a value MUST be treated as if they were
  39. omitted from the request. The authorization server MUST ignore
  40. unrecognized request parameters. Request and response parameters
  41. MUST NOT be included more than once::
  42. # Delegated to each grant type.
  43. .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
  44. """
  45. def __init__(self, default_grant_type, default_token_type, grant_types):
  46. BaseEndpoint.__init__(self)
  47. self._grant_types = grant_types
  48. self._default_token_type = default_token_type
  49. self._default_grant_type = default_grant_type
  50. @property
  51. def grant_types(self):
  52. return self._grant_types
  53. @property
  54. def default_grant_type(self):
  55. return self._default_grant_type
  56. @property
  57. def default_grant_type_handler(self):
  58. return self.grant_types.get(self.default_grant_type)
  59. @property
  60. def default_token_type(self):
  61. return self._default_token_type
  62. @catch_errors_and_unavailability
  63. def create_token_response(self, uri, http_method='GET', body=None,
  64. headers=None, credentials=None, grant_type_for_scope=None,
  65. claims=None):
  66. """Extract grant_type and route to the designated handler."""
  67. request = Request(
  68. uri, http_method=http_method, body=body, headers=headers)
  69. # 'scope' is an allowed Token Request param in both the "Resource Owner Password Credentials Grant"
  70. # and "Client Credentials Grant" flows
  71. # https://tools.ietf.org/html/rfc6749#section-4.3.2
  72. # https://tools.ietf.org/html/rfc6749#section-4.4.2
  73. request.scopes = utils.scope_to_list(request.scope)
  74. request.extra_credentials = credentials
  75. if grant_type_for_scope:
  76. request.grant_type = grant_type_for_scope
  77. # OpenID Connect claims, if provided. The server using oauthlib might choose
  78. # to implement the claims parameter of the Authorization Request. In this case
  79. # it should retrieve those claims and pass them via the claims argument here,
  80. # as a dict.
  81. if claims:
  82. request.claims = claims
  83. grant_type_handler = self.grant_types.get(request.grant_type,
  84. self.default_grant_type_handler)
  85. log.debug('Dispatching grant_type %s request to %r.',
  86. request.grant_type, grant_type_handler)
  87. return grant_type_handler.create_token_response(
  88. request, self.default_token_type)