oidcauthlib 3.0.8__tar.gz → 3.0.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. {oidcauthlib-3.0.8/oidcauthlib.egg-info → oidcauthlib-3.0.10}/PKG-INFO +1 -1
  2. oidcauthlib-3.0.10/VERSION +1 -0
  3. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/token_reader.py +24 -5
  4. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/well_known_configuration/well_known_configuration_cache.py +1 -0
  5. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/environment/oidc_environment_variables.py +20 -0
  6. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10/oidcauthlib.egg-info}/PKG-INFO +1 -1
  7. oidcauthlib-3.0.8/VERSION +0 -1
  8. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/LICENSE +0 -0
  9. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/MANIFEST.in +0 -0
  10. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/README.md +0 -0
  11. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/__init__.py +0 -0
  12. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/__init__.py +0 -0
  13. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/auth_helper.py +0 -0
  14. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/auth_manager.py +0 -0
  15. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/cache/__init__.py +0 -0
  16. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/cache/oauth_cache.py +0 -0
  17. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/cache/oauth_memory_cache.py +0 -0
  18. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/cache/oauth_mongo_cache.py +0 -0
  19. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/config/__init__.py +0 -0
  20. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/config/auth_config.py +0 -0
  21. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/config/auth_config_reader.py +0 -0
  22. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/dcr/__init__.py +0 -0
  23. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/dcr/dcr_client.py +0 -0
  24. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/dcr/dcr_manager.py +0 -0
  25. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/dcr/dcr_registration.py +0 -0
  26. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/exceptions/__init__.py +0 -0
  27. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/exceptions/authorization_bearer_token_expired_exception.py +0 -0
  28. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/exceptions/authorization_bearer_token_invalid_exception.py +0 -0
  29. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/exceptions/authorization_bearer_token_missing_exception.py +0 -0
  30. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/exceptions/authorization_needed_exception.py +0 -0
  31. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/fastapi_auth_manager.py +0 -0
  32. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/middleware/__init__.py +0 -0
  33. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/middleware/request_scope_middleware.py +0 -0
  34. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/middleware/token_reader_middleware.py +0 -0
  35. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/models/__init__.py +0 -0
  36. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/models/auth.py +0 -0
  37. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/models/base_db_model.py +0 -0
  38. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/models/cache_item.py +0 -0
  39. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/models/client_key_set.py +0 -0
  40. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/models/token.py +0 -0
  41. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/__init__.py +0 -0
  42. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/base_repository.py +0 -0
  43. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/memory/__init__.py +0 -0
  44. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/memory/memory_repository.py +0 -0
  45. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/mongo/__init__.py +0 -0
  46. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/mongo/mongo_repository.py +0 -0
  47. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/repository/repository_factory.py +0 -0
  48. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/routers/__init__.py +0 -0
  49. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/routers/auth_router.py +0 -0
  50. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/well_known_configuration/__init__.py +0 -0
  51. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/well_known_configuration/auth_server_metadata.py +0 -0
  52. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/well_known_configuration/auth_server_metadata_discovery.py +0 -0
  53. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/well_known_configuration/well_known_configuration_cache_result.py +0 -0
  54. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/auth/well_known_configuration/well_known_configuration_manager.py +0 -0
  55. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/container/__init__.py +0 -0
  56. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/container/oidc_authlib_container_factory.py +0 -0
  57. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/open_telemetry/__init__.py +0 -0
  58. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/open_telemetry/attribute_names.py +0 -0
  59. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/open_telemetry/span_names.py +0 -0
  60. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/py.typed +0 -0
  61. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/__init__.py +0 -0
  62. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/cache_to_collection_mapper.py +0 -0
  63. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/memory_storage_factory.py +0 -0
  64. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/mongo_gridfs_db.py +0 -0
  65. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/mongo_gridfs_exception.py +0 -0
  66. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/mongo_storage_factory.py +0 -0
  67. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/storage_factory.py +0 -0
  68. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/storage/storage_factory_creator.py +0 -0
  69. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/__init__.py +0 -0
  70. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/cached.py +0 -0
  71. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/environment/__init__.py +0 -0
  72. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/environment/abstract_environment_variables.py +0 -0
  73. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/logger/__init__.py +0 -0
  74. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/logger/log_levels.py +0 -0
  75. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/logger/logging_response.py +0 -0
  76. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/logger/logging_transport.py +0 -0
  77. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/mongo_url_utils.py +0 -0
  78. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib/utilities/url_validator.py +0 -0
  79. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib.egg-info/SOURCES.txt +0 -0
  80. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib.egg-info/dependency_links.txt +0 -0
  81. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib.egg-info/requires.txt +0 -0
  82. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/oidcauthlib.egg-info/top_level.txt +0 -0
  83. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/pyproject.toml +0 -0
  84. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/setup.cfg +0 -0
  85. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/tests/test_mongo_url_utils.py +0 -0
  86. {oidcauthlib-3.0.8 → oidcauthlib-3.0.10}/tests/test_simple.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oidcauthlib
3
- Version: 3.0.8
3
+ Version: 3.0.10
4
4
  Summary: oidcauthlib
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
6
  License: Apache-2.0
@@ -0,0 +1 @@
1
+ 3.0.10
@@ -7,7 +7,7 @@ from typing import Optional, Any, Dict, List, cast
7
7
  from uuid import UUID
8
8
 
9
9
  from joserfc import jwt, jws
10
- from joserfc.errors import ExpiredTokenError
10
+ from joserfc.errors import ExpiredTokenError, InvalidKeyIdError
11
11
  from joserfc.jwk import KeySet
12
12
 
13
13
  from zoneinfo import ZoneInfo
@@ -147,7 +147,13 @@ class TokenReader:
147
147
  if not jwks:
148
148
  raise RuntimeError("JWKS must be fetched before verifying tokens")
149
149
  try:
150
- decoded = jwt.decode(token, jwks, algorithms=self.algorithms)
150
+ try:
151
+ decoded = jwt.decode(token, jwks, algorithms=self.algorithms)
152
+ except InvalidKeyIdError:
153
+ logger.info("Unknown kid in token during decode; refreshing JWKS and retrying.")
154
+ await self._well_known_config_manager.refresh_async()
155
+ jwks = await self._well_known_config_manager.get_jwks_async()
156
+ decoded = jwt.decode(token, jwks, algorithms=self.algorithms)
151
157
  return decoded.claims
152
158
  except Exception as e:
153
159
  logger.exception(f"Failed to decode token: {e}")
@@ -197,8 +203,15 @@ class TokenReader:
197
203
  issuer: Optional[str] = None
198
204
  audience: Optional[str] = None
199
205
  try:
200
- # Validate the token
201
- verified = jwt.decode(token, jwks, algorithms=self.algorithms)
206
+ # Validate the token; on unknown kid, refresh JWKS once and retry
207
+ try:
208
+ verified = jwt.decode(token, jwks, algorithms=self.algorithms)
209
+ except InvalidKeyIdError:
210
+ logger.info("Unknown kid in token; refreshing JWKS from identity providers and retrying.")
211
+ await self._well_known_config_manager.refresh_async()
212
+ jwks = await self._well_known_config_manager.get_jwks_async()
213
+ jwks_kids = [key.get("kid") for key in jwks.keys]
214
+ verified = jwt.decode(token, jwks, algorithms=self.algorithms)
202
215
  issuer = verified.claims.get("iss")
203
216
  audience = verified.claims.get("aud") or verified.claims.get(
204
217
  "client_id"
@@ -322,7 +335,13 @@ class TokenReader:
322
335
  assert access_token, "Access token must not be empty"
323
336
  jwks: KeySet = await self._well_known_config_manager.get_jwks_async()
324
337
  try:
325
- verified = jwt.decode(access_token, jwks, algorithms=self.algorithms)
338
+ try:
339
+ verified = jwt.decode(access_token, jwks, algorithms=self.algorithms)
340
+ except InvalidKeyIdError:
341
+ logger.info("Unknown kid in token during validity check; refreshing JWKS and retrying.")
342
+ await self._well_known_config_manager.refresh_async()
343
+ jwks = await self._well_known_config_manager.get_jwks_async()
344
+ verified = jwt.decode(access_token, jwks, algorithms=self.algorithms)
326
345
  exp = verified.claims.get("exp")
327
346
  now = time.time()
328
347
  if exp and exp < now:
@@ -247,6 +247,7 @@ class WellKnownConfigurationCache:
247
247
  await self.well_known_store.put(
248
248
  key=well_known_uri,
249
249
  value=well_known_configuration_cache_result.model_dump(),
250
+ ttl=self.environment_variables.well_known_cache_ttl_seconds,
250
251
  )
251
252
  logger.info(f"Cached OIDC discovery document for {well_known_uri}")
252
253
  return well_known_configuration_cache_result
@@ -196,6 +196,26 @@ class OidcEnvironmentVariables(AbstractEnvironmentVariables):
196
196
  except ValueError:
197
197
  raise ValueError("MAX_MONGO_INLINE_SIZE_KB must be a positive integer representing bytes")
198
198
 
199
+ @property
200
+ def well_known_cache_ttl_seconds(self) -> int:
201
+ """TTL in seconds for well-known configuration entries in the persistent store.
202
+
203
+ Controls how long OIDC discovery documents (including JWKS keys) are
204
+ cached in MongoDB before expiring. This ensures key rotations by
205
+ identity providers are picked up within a bounded window.
206
+
207
+ Set via WELL_KNOWN_CACHE_TTL_SECONDS environment variable.
208
+ Defaults to 3600 seconds (1 hour).
209
+
210
+ Returns:
211
+ TTL in seconds
212
+ """
213
+ try:
214
+ ttl = int(os.environ.get("WELL_KNOWN_CACHE_TTL_SECONDS", "3600"))
215
+ return ttl
216
+ except ValueError:
217
+ raise ValueError("WELL_KNOWN_CACHE_TTL_SECONDS must be a positive integer representing seconds")
218
+
199
219
  @property
200
220
  def well_known_config_http_timeout_seconds(self) -> int:
201
221
  """HTTP timeout in seconds for fetching well-known configurations.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oidcauthlib
3
- Version: 3.0.8
3
+ Version: 3.0.10
4
4
  Summary: oidcauthlib
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
6
  License: Apache-2.0
oidcauthlib-3.0.8/VERSION DELETED
@@ -1 +0,0 @@
1
- 3.0.8
File without changes
File without changes
File without changes
File without changes
File without changes