_jwt_async.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. # Copyright 2020 Google LLC
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """JSON Web Tokens
  15. Provides support for creating (encoding) and verifying (decoding) JWTs,
  16. especially JWTs generated and consumed by Google infrastructure.
  17. See `rfc7519`_ for more details on JWTs.
  18. To encode a JWT use :func:`encode`::
  19. from google.auth import crypt
  20. from google.auth import jwt_async
  21. signer = crypt.Signer(private_key)
  22. payload = {'some': 'payload'}
  23. encoded = jwt_async.encode(signer, payload)
  24. To decode a JWT and verify claims use :func:`decode`::
  25. claims = jwt_async.decode(encoded, certs=public_certs)
  26. You can also skip verification::
  27. claims = jwt_async.decode(encoded, verify=False)
  28. .. _rfc7519: https://tools.ietf.org/html/rfc7519
  29. NOTE: This async support is experimental and marked internal. This surface may
  30. change in minor releases.
  31. """
  32. from google.auth import _credentials_async
  33. from google.auth import jwt
  34. def encode(signer, payload, header=None, key_id=None):
  35. """Make a signed JWT.
  36. Args:
  37. signer (google.auth.crypt.Signer): The signer used to sign the JWT.
  38. payload (Mapping[str, str]): The JWT payload.
  39. header (Mapping[str, str]): Additional JWT header payload.
  40. key_id (str): The key id to add to the JWT header. If the
  41. signer has a key id it will be used as the default. If this is
  42. specified it will override the signer's key id.
  43. Returns:
  44. bytes: The encoded JWT.
  45. """
  46. return jwt.encode(signer, payload, header, key_id)
  47. def decode(token, certs=None, verify=True, audience=None):
  48. """Decode and verify a JWT.
  49. Args:
  50. token (str): The encoded JWT.
  51. certs (Union[str, bytes, Mapping[str, Union[str, bytes]]]): The
  52. certificate used to validate the JWT signature. If bytes or string,
  53. it must the the public key certificate in PEM format. If a mapping,
  54. it must be a mapping of key IDs to public key certificates in PEM
  55. format. The mapping must contain the same key ID that's specified
  56. in the token's header.
  57. verify (bool): Whether to perform signature and claim validation.
  58. Verification is done by default.
  59. audience (str): The audience claim, 'aud', that this JWT should
  60. contain. If None then the JWT's 'aud' parameter is not verified.
  61. Returns:
  62. Mapping[str, str]: The deserialized JSON payload in the JWT.
  63. Raises:
  64. ValueError: if any verification checks failed.
  65. """
  66. return jwt.decode(token, certs, verify, audience)
  67. class Credentials(
  68. jwt.Credentials, _credentials_async.Signing, _credentials_async.Credentials
  69. ):
  70. """Credentials that use a JWT as the bearer token.
  71. These credentials require an "audience" claim. This claim identifies the
  72. intended recipient of the bearer token.
  73. The constructor arguments determine the claims for the JWT that is
  74. sent with requests. Usually, you'll construct these credentials with
  75. one of the helper constructors as shown in the next section.
  76. To create JWT credentials using a Google service account private key
  77. JSON file::
  78. audience = 'https://pubsub.googleapis.com/google.pubsub.v1.Publisher'
  79. credentials = jwt_async.Credentials.from_service_account_file(
  80. 'service-account.json',
  81. audience=audience)
  82. If you already have the service account file loaded and parsed::
  83. service_account_info = json.load(open('service_account.json'))
  84. credentials = jwt_async.Credentials.from_service_account_info(
  85. service_account_info,
  86. audience=audience)
  87. Both helper methods pass on arguments to the constructor, so you can
  88. specify the JWT claims::
  89. credentials = jwt_async.Credentials.from_service_account_file(
  90. 'service-account.json',
  91. audience=audience,
  92. additional_claims={'meta': 'data'})
  93. You can also construct the credentials directly if you have a
  94. :class:`~google.auth.crypt.Signer` instance::
  95. credentials = jwt_async.Credentials(
  96. signer,
  97. issuer='your-issuer',
  98. subject='your-subject',
  99. audience=audience)
  100. The claims are considered immutable. If you want to modify the claims,
  101. you can easily create another instance using :meth:`with_claims`::
  102. new_audience = (
  103. 'https://pubsub.googleapis.com/google.pubsub.v1.Subscriber')
  104. new_credentials = credentials.with_claims(audience=new_audience)
  105. """
  106. class OnDemandCredentials(
  107. jwt.OnDemandCredentials, _credentials_async.Signing, _credentials_async.Credentials
  108. ):
  109. """On-demand JWT credentials.
  110. Like :class:`Credentials`, this class uses a JWT as the bearer token for
  111. authentication. However, this class does not require the audience at
  112. construction time. Instead, it will generate a new token on-demand for
  113. each request using the request URI as the audience. It caches tokens
  114. so that multiple requests to the same URI do not incur the overhead
  115. of generating a new token every time.
  116. This behavior is especially useful for `gRPC`_ clients. A gRPC service may
  117. have multiple audience and gRPC clients may not know all of the audiences
  118. required for accessing a particular service. With these credentials,
  119. no knowledge of the audiences is required ahead of time.
  120. .. _grpc: http://www.grpc.io/
  121. """