introspect.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. """
  2. oauthlib.oauth2.rfc6749.endpoint.introspect
  3. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. An implementation of the OAuth 2.0 `Token Introspection`.
  5. .. _`Token Introspection`: https://tools.ietf.org/html/rfc7662
  6. """
  7. import json
  8. import logging
  9. from oauthlib.common import Request
  10. from ..errors import OAuth2Error
  11. from .base import BaseEndpoint, catch_errors_and_unavailability
  12. log = logging.getLogger(__name__)
  13. class IntrospectEndpoint(BaseEndpoint):
  14. """Introspect token endpoint.
  15. This endpoint defines a method to query an OAuth 2.0 authorization
  16. server to determine the active state of an OAuth 2.0 token and to
  17. determine meta-information about this token. OAuth 2.0 deployments
  18. can use this method to convey information about the authorization
  19. context of the token from the authorization server to the protected
  20. resource.
  21. To prevent the values of access tokens from leaking into
  22. server-side logs via query parameters, an authorization server
  23. offering token introspection MAY disallow the use of HTTP GET on
  24. the introspection endpoint and instead require the HTTP POST method
  25. to be used at the introspection endpoint.
  26. """
  27. valid_token_types = ('access_token', 'refresh_token')
  28. valid_request_methods = ('POST',)
  29. def __init__(self, request_validator, supported_token_types=None):
  30. BaseEndpoint.__init__(self)
  31. self.request_validator = request_validator
  32. self.supported_token_types = (
  33. supported_token_types or self.valid_token_types)
  34. @catch_errors_and_unavailability
  35. def create_introspect_response(self, uri, http_method='POST', body=None,
  36. headers=None):
  37. """Create introspect valid or invalid response
  38. If the authorization server is unable to determine the state
  39. of the token without additional information, it SHOULD return
  40. an introspection response indicating the token is not active
  41. as described in Section 2.2.
  42. """
  43. resp_headers = {
  44. 'Content-Type': 'application/json',
  45. 'Cache-Control': 'no-store',
  46. 'Pragma': 'no-cache',
  47. }
  48. request = Request(uri, http_method, body, headers)
  49. try:
  50. self.validate_introspect_request(request)
  51. log.debug('Token introspect valid for %r.', request)
  52. except OAuth2Error as e:
  53. log.debug('Client error during validation of %r. %r.', request, e)
  54. resp_headers.update(e.headers)
  55. return resp_headers, e.json, e.status_code
  56. claims = self.request_validator.introspect_token(
  57. request.token,
  58. request.token_type_hint,
  59. request
  60. )
  61. if claims is None:
  62. return resp_headers, json.dumps(dict(active=False)), 200
  63. if "active" in claims:
  64. claims.pop("active")
  65. return resp_headers, json.dumps(dict(active=True, **claims)), 200
  66. def validate_introspect_request(self, request):
  67. """Ensure the request is valid.
  68. The protected resource calls the introspection endpoint using
  69. an HTTP POST request with parameters sent as
  70. "application/x-www-form-urlencoded".
  71. * token REQUIRED. The string value of the token.
  72. * token_type_hint OPTIONAL.
  73. A hint about the type of the token submitted for
  74. introspection. The protected resource MAY pass this parameter to
  75. help the authorization server optimize the token lookup. If the
  76. server is unable to locate the token using the given hint, it MUST
  77. extend its search across all of its supported token types. An
  78. authorization server MAY ignore this parameter, particularly if it
  79. is able to detect the token type automatically.
  80. * access_token: An Access Token as defined in [`RFC6749`], `section 1.4`_
  81. * refresh_token: A Refresh Token as defined in [`RFC6749`], `section 1.5`_
  82. The introspection endpoint MAY accept other OPTIONAL
  83. parameters to provide further context to the query. For
  84. instance, an authorization server may desire to know the IP
  85. address of the client accessing the protected resource to
  86. determine if the correct client is likely to be presenting the
  87. token. The definition of this or any other parameters are
  88. outside the scope of this specification, to be defined by
  89. service documentation or extensions to this specification.
  90. .. _`section 1.4`: http://tools.ietf.org/html/rfc6749#section-1.4
  91. .. _`section 1.5`: http://tools.ietf.org/html/rfc6749#section-1.5
  92. .. _`RFC6749`: http://tools.ietf.org/html/rfc6749
  93. """
  94. self._raise_on_bad_method(request)
  95. self._raise_on_bad_post_request(request)
  96. self._raise_on_missing_token(request)
  97. self._raise_on_invalid_client(request)
  98. self._raise_on_unsupported_token(request)