Authlib 1.7.2__tar.gz → 1.9.0__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.
- {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/PKG-INFO +3 -3
- {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/SOURCES.txt +4 -0
- authlib-1.9.0/Authlib.egg-info/requires.txt +2 -0
- {authlib-1.7.2 → authlib-1.9.0}/PKG-INFO +3 -3
- authlib-1.9.0/authlib/common/security.py +48 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/common/urls.py +11 -2
- {authlib-1.7.2 → authlib-1.9.0}/authlib/consts.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/async_openid.py +6 -5
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/sync_openid.py +8 -7
- authlib-1.9.0/authlib/integrations/httpx_client/_compat.py +16 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/assertion_client.py +12 -13
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/oauth1_client.py +10 -15
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/oauth2_client.py +15 -16
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/utils.py +7 -2
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/assertion_session.py +3 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/client_mixin.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/_jwe_enc_cryptodome.py +2 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/_jwe_enc_cryptography.py +2 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7515/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7515/jws.py +9 -8
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7516/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_encs.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jws_algs.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/oct_key.py +8 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7519/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7519/claims.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/client_auth.py +10 -5
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/errors.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/parameters.py +6 -18
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/signature.py +9 -25
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/base.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/client.py +25 -10
- authlib-1.9.0/authlib/oauth2/drafts/__init__.py +11 -0
- authlib-1.9.0/authlib/oauth2/drafts/id_jag.py +314 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/authenticate_client.py +2 -5
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/errors.py +8 -10
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/__init__.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/authorization_code.py +4 -12
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/base.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/client_credentials.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/implicit.py +2 -6
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/refresh_token.py +2 -6
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/models.py +2 -6
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/parameters.py +6 -13
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/resource_protector.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/errors.py +4 -4
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7009/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7009/parameters.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7009/revocation.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7521/client.py +8 -10
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/assertion.py +6 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/client.py +19 -4
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/jwt_bearer.py +35 -19
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/token.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/validator.py +7 -2
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/errors.py +4 -4
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7592/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7636/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/introspection.py +2 -6
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8414/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8414/models.py +1 -4
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8414/well_known.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/endpoint.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8693/__init__.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/revocation.py +1 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/token.py +1 -1
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/token_validator.py +2 -5
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/authorization_server.py +76 -18
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/__init__.py +2 -0
- authlib-1.9.0/authlib/oidc/core/authorization_request.py +39 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/_legacy.py +12 -8
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/code.py +6 -4
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/hybrid.py +3 -3
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/implicit.py +2 -2
- {authlib-1.7.2 → authlib-1.9.0}/pyproject.toml +22 -22
- authlib-1.7.2/Authlib.egg-info/requires.txt +0 -2
- authlib-1.7.2/authlib/common/security.py +0 -21
- {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/dependency_links.txt +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/top_level.txt +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/LICENSE +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/MANIFEST.in +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/README.md +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/_joserfc_helpers.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/common/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/common/encoding.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/common/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/common/language.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/deprecate.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/async_app.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/framework_integration.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/registry.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/sync_app.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_client/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_client/apps.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_client/integration.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/authorization_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/nonce.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/resource_protector.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/authorization_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/endpoints.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/requests.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/resource_protector.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/signals.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_client/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_client/apps.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_client/integration.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/authorization_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/cache.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/resource_protector.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/authorization_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/requests.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/resource_protector.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/signals.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/oauth1_session.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/oauth2_session.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/utils.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/functions.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/tokens_mixins.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/starlette_client/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/starlette_client/apps.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/starlette_client/integration.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/_jwe_algorithms.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/jwk.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7515/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7516/jwe.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7516/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/_cryptography_key.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/asymmetric_key.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/base_key.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/jwk.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/key_set.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/ec_key.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_algs.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_zips.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/rsa_key.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/util.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7519/jwt.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc8037/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc8037/jws_eddsa.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc8037/okp_key.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/util.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/client.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/authorization_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/base_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/resource_protector.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/rsa.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/util.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/wrapper.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/auth.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/claims.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/authorization_server.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/endpoint.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/hooks.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/requests.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/token_endpoint.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/util.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/wrappers.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/parameters.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/token.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/validator.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7521/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/auth.py +2 -2
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/claims.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/endpoint.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7592/endpoint.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7636/challenge.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/token_validator.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/device_code.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/claims.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/introspection.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/discovery.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/registration.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9207/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9207/discovery.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9207/parameter.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/claims.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/errors.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/util.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/userinfo.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/util.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/discovery/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/discovery/models.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/discovery/well_known.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/registration/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/registration/claims.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/__init__.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/discovery.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/end_session.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/registration.py +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/setup.cfg +0 -0
- {authlib-1.7.2 → authlib-1.9.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Authlib
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9.0
|
|
4
4
|
Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
|
|
5
5
|
Author-email: Hsiaoming Yang <me@lepture.com>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -32,8 +32,8 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
|
32
32
|
Requires-Python: >=3.10
|
|
33
33
|
Description-Content-Type: text/markdown
|
|
34
34
|
License-File: LICENSE
|
|
35
|
-
Requires-Dist: cryptography
|
|
36
|
-
Requires-Dist: joserfc>=1.6.
|
|
35
|
+
Requires-Dist: cryptography>=45.0.1
|
|
36
|
+
Requires-Dist: joserfc>=1.6.1
|
|
37
37
|
Dynamic: license-file
|
|
38
38
|
|
|
39
39
|
<div align="center">
|
|
@@ -54,6 +54,7 @@ authlib/integrations/flask_oauth2/requests.py
|
|
|
54
54
|
authlib/integrations/flask_oauth2/resource_protector.py
|
|
55
55
|
authlib/integrations/flask_oauth2/signals.py
|
|
56
56
|
authlib/integrations/httpx_client/__init__.py
|
|
57
|
+
authlib/integrations/httpx_client/_compat.py
|
|
57
58
|
authlib/integrations/httpx_client/assertion_client.py
|
|
58
59
|
authlib/integrations/httpx_client/oauth1_client.py
|
|
59
60
|
authlib/integrations/httpx_client/oauth2_client.py
|
|
@@ -125,6 +126,8 @@ authlib/oauth2/auth.py
|
|
|
125
126
|
authlib/oauth2/base.py
|
|
126
127
|
authlib/oauth2/claims.py
|
|
127
128
|
authlib/oauth2/client.py
|
|
129
|
+
authlib/oauth2/drafts/__init__.py
|
|
130
|
+
authlib/oauth2/drafts/id_jag.py
|
|
128
131
|
authlib/oauth2/rfc6749/__init__.py
|
|
129
132
|
authlib/oauth2/rfc6749/authenticate_client.py
|
|
130
133
|
authlib/oauth2/rfc6749/authorization_server.py
|
|
@@ -199,6 +202,7 @@ authlib/oauth2/rfc9207/discovery.py
|
|
|
199
202
|
authlib/oauth2/rfc9207/parameter.py
|
|
200
203
|
authlib/oidc/__init__.py
|
|
201
204
|
authlib/oidc/core/__init__.py
|
|
205
|
+
authlib/oidc/core/authorization_request.py
|
|
202
206
|
authlib/oidc/core/claims.py
|
|
203
207
|
authlib/oidc/core/errors.py
|
|
204
208
|
authlib/oidc/core/models.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Authlib
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9.0
|
|
4
4
|
Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
|
|
5
5
|
Author-email: Hsiaoming Yang <me@lepture.com>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -32,8 +32,8 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
|
32
32
|
Requires-Python: >=3.10
|
|
33
33
|
Description-Content-Type: text/markdown
|
|
34
34
|
License-File: LICENSE
|
|
35
|
-
Requires-Dist: cryptography
|
|
36
|
-
Requires-Dist: joserfc>=1.6.
|
|
35
|
+
Requires-Dist: cryptography>=45.0.1
|
|
36
|
+
Requires-Dist: joserfc>=1.6.1
|
|
37
37
|
Dynamic: license-file
|
|
38
38
|
|
|
39
39
|
<div align="center">
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import ipaddress
|
|
2
|
+
import os
|
|
3
|
+
import random
|
|
4
|
+
import string
|
|
5
|
+
from urllib.parse import urlsplit
|
|
6
|
+
|
|
7
|
+
UNICODE_ASCII_CHARACTER_SET = string.ascii_letters + string.digits
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def generate_token(length=30, chars=UNICODE_ASCII_CHARACTER_SET):
|
|
11
|
+
rand = random.SystemRandom()
|
|
12
|
+
return "".join(rand.choice(chars) for _ in range(length))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def is_secure_transport(uri):
|
|
16
|
+
"""Check if the uri is over ssl."""
|
|
17
|
+
if os.getenv("AUTHLIB_INSECURE_TRANSPORT"):
|
|
18
|
+
return True
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
parts = urlsplit(uri)
|
|
22
|
+
except ValueError:
|
|
23
|
+
return False
|
|
24
|
+
|
|
25
|
+
if not parts.hostname:
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
if parts.scheme == "https":
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
if parts.scheme != "http":
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
# rfc8252 §7.3: native apps may use http for loopback redirection URIs.
|
|
35
|
+
if parts.hostname == "localhost":
|
|
36
|
+
return True
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
address = ipaddress.ip_address(parts.hostname)
|
|
40
|
+
except ValueError:
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
# IPv6Address.is_loopback only accounts for the mapped IPv4 address since
|
|
44
|
+
# CPython 3.10.16, 3.11.11 and 3.12.4.
|
|
45
|
+
if isinstance(address, ipaddress.IPv6Address) and address.ipv4_mapped:
|
|
46
|
+
address = address.ipv4_mapped
|
|
47
|
+
|
|
48
|
+
return address.is_loopback
|
|
@@ -140,7 +140,16 @@ def extract_params(raw):
|
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
def is_valid_url(url: str, fragments_allowed=True):
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
try:
|
|
144
|
+
parsed = urlparse.urlparse(url)
|
|
145
|
+
except ValueError:
|
|
146
|
+
return False
|
|
147
|
+
|
|
148
|
+
# The userinfo component can disguise the actual host,
|
|
149
|
+
# as in "https://provider.test@attacker.test/".
|
|
150
|
+
if "@" in parsed.netloc:
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
return bool(
|
|
145
154
|
parsed.scheme and parsed.hostname and (fragments_allowed or not parsed.fragment)
|
|
146
155
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from joserfc import jwt
|
|
2
2
|
from joserfc.errors import InvalidKeyIdError
|
|
3
3
|
from joserfc.jwk import KeySet
|
|
4
|
+
from joserfc.jws import JWSRegistry
|
|
4
5
|
|
|
5
6
|
from authlib.common.security import generate_token
|
|
6
7
|
from authlib.common.urls import add_params_to_uri
|
|
@@ -42,6 +43,9 @@ class AsyncOpenIDMixin:
|
|
|
42
43
|
self, token, nonce, claims_options=None, claims_cls=None, leeway=120
|
|
43
44
|
):
|
|
44
45
|
"""Return an instance of UserInfo from token's ``id_token``."""
|
|
46
|
+
if "id_token" not in token:
|
|
47
|
+
return None
|
|
48
|
+
|
|
45
49
|
claims_params = dict(
|
|
46
50
|
nonce=nonce,
|
|
47
51
|
client_id=self.client_id,
|
|
@@ -67,7 +71,7 @@ class AsyncOpenIDMixin:
|
|
|
67
71
|
token = jwt.decode(
|
|
68
72
|
token["id_token"],
|
|
69
73
|
key=key_set,
|
|
70
|
-
algorithms=alg_values,
|
|
74
|
+
registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
|
|
71
75
|
)
|
|
72
76
|
except InvalidKeyIdError:
|
|
73
77
|
jwks = await self.fetch_jwk_set(force=True)
|
|
@@ -75,13 +79,10 @@ class AsyncOpenIDMixin:
|
|
|
75
79
|
token = jwt.decode(
|
|
76
80
|
token["id_token"],
|
|
77
81
|
key=key_set,
|
|
78
|
-
algorithms=alg_values,
|
|
82
|
+
registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
|
|
79
83
|
)
|
|
80
84
|
|
|
81
85
|
claims = claims_cls(token.claims, token.header, claims_options, claims_params)
|
|
82
|
-
# https://github.com/authlib/authlib/issues/259
|
|
83
|
-
if claims.get("nonce_supported") is False:
|
|
84
|
-
claims.params["nonce"] = None
|
|
85
86
|
claims.validate(leeway=leeway)
|
|
86
87
|
return UserInfo(claims)
|
|
87
88
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from joserfc import jwt
|
|
2
2
|
from joserfc.errors import InvalidKeyIdError
|
|
3
3
|
from joserfc.jwk import KeySet
|
|
4
|
+
from joserfc.jws import JWSRegistry
|
|
4
5
|
|
|
5
6
|
from authlib.common.security import generate_token
|
|
6
7
|
from authlib.common.urls import add_params_to_uri
|
|
@@ -39,7 +40,11 @@ class OpenIDMixin:
|
|
|
39
40
|
def parse_id_token(
|
|
40
41
|
self, token, nonce, claims_options=None, claims_cls=None, leeway=120
|
|
41
42
|
):
|
|
42
|
-
"""Return
|
|
43
|
+
"""Return UserInfo after validating the token's ``id_token``.
|
|
44
|
+
|
|
45
|
+
The expected ``nonce`` is controlled by the application. Token claims
|
|
46
|
+
such as ``nonce_supported`` cannot disable its validation.
|
|
47
|
+
"""
|
|
43
48
|
if "id_token" not in token:
|
|
44
49
|
return None
|
|
45
50
|
|
|
@@ -66,21 +71,17 @@ class OpenIDMixin:
|
|
|
66
71
|
token = jwt.decode(
|
|
67
72
|
token["id_token"],
|
|
68
73
|
key=key_set,
|
|
69
|
-
algorithms=alg_values,
|
|
74
|
+
registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
|
|
70
75
|
)
|
|
71
76
|
except InvalidKeyIdError:
|
|
72
77
|
key_set = KeySet.import_key_set(self.fetch_jwk_set(force=True))
|
|
73
78
|
token = jwt.decode(
|
|
74
79
|
token["id_token"],
|
|
75
80
|
key=key_set,
|
|
76
|
-
algorithms=alg_values,
|
|
81
|
+
registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
|
|
77
82
|
)
|
|
78
83
|
|
|
79
84
|
claims = claims_cls(token.claims, token.header, claims_options, claims_params)
|
|
80
|
-
# https://github.com/authlib/authlib/issues/259
|
|
81
|
-
if claims.get("nonce_supported") is False:
|
|
82
|
-
claims.params["nonce"] = None
|
|
83
|
-
|
|
84
85
|
claims.validate(leeway=leeway)
|
|
85
86
|
return UserInfo(claims)
|
|
86
87
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Compatibility shim for httpx2 with legacy httpx fallback.
|
|
2
|
+
|
|
3
|
+
Falls back to httpx when httpx2 is unavailable. The fallback is deprecated
|
|
4
|
+
and will be removed in a future release.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from authlib.deprecate import deprecate
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import httpx2
|
|
11
|
+
except ImportError:
|
|
12
|
+
import httpx as httpx2
|
|
13
|
+
|
|
14
|
+
deprecate("The httpx module is deprecated; please use httpx2 instead.")
|
|
15
|
+
|
|
16
|
+
__all__ = ["httpx2"]
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import httpx
|
|
2
|
-
from httpx import USE_CLIENT_DEFAULT
|
|
3
|
-
from httpx import Response
|
|
4
|
-
|
|
5
1
|
from authlib.oauth2.rfc7521 import AssertionClient as _AssertionClient
|
|
6
2
|
from authlib.oauth2.rfc7523 import JWTBearerGrant
|
|
7
3
|
|
|
8
4
|
from ..base_client import OAuthError
|
|
5
|
+
from ._compat import httpx2
|
|
9
6
|
from .oauth2_client import OAuth2Auth
|
|
10
7
|
from .utils import extract_client_kwargs
|
|
11
8
|
|
|
9
|
+
USE_CLIENT_DEFAULT = httpx2.USE_CLIENT_DEFAULT
|
|
10
|
+
Response = httpx2.Response
|
|
11
|
+
|
|
12
12
|
__all__ = ["AsyncAssertionClient"]
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
class AsyncAssertionClient(_AssertionClient,
|
|
15
|
+
class AsyncAssertionClient(_AssertionClient, httpx2.AsyncClient):
|
|
16
16
|
token_auth_class = OAuth2Auth
|
|
17
17
|
oauth_error_class = OAuthError
|
|
18
18
|
JWT_BEARER_GRANT_TYPE = JWTBearerGrant.GRANT_TYPE
|
|
@@ -31,10 +31,11 @@ class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
|
|
|
31
31
|
claims=None,
|
|
32
32
|
token_placement="header",
|
|
33
33
|
scope=None,
|
|
34
|
+
client_id=None,
|
|
34
35
|
**kwargs,
|
|
35
36
|
):
|
|
36
37
|
client_kwargs = extract_client_kwargs(kwargs)
|
|
37
|
-
|
|
38
|
+
httpx2.AsyncClient.__init__(self, **client_kwargs)
|
|
38
39
|
|
|
39
40
|
_AssertionClient.__init__(
|
|
40
41
|
self,
|
|
@@ -47,6 +48,7 @@ class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
|
|
|
47
48
|
claims=claims,
|
|
48
49
|
token_placement=token_placement,
|
|
49
50
|
scope=scope,
|
|
51
|
+
client_id=client_id,
|
|
50
52
|
**kwargs,
|
|
51
53
|
)
|
|
52
54
|
|
|
@@ -69,7 +71,7 @@ class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
|
|
|
69
71
|
return self.parse_response_token(resp)
|
|
70
72
|
|
|
71
73
|
|
|
72
|
-
class AssertionClient(_AssertionClient,
|
|
74
|
+
class AssertionClient(_AssertionClient, httpx2.Client):
|
|
73
75
|
token_auth_class = OAuth2Auth
|
|
74
76
|
oauth_error_class = OAuthError
|
|
75
77
|
JWT_BEARER_GRANT_TYPE = JWTBearerGrant.GRANT_TYPE
|
|
@@ -88,15 +90,11 @@ class AssertionClient(_AssertionClient, httpx.Client):
|
|
|
88
90
|
claims=None,
|
|
89
91
|
token_placement="header",
|
|
90
92
|
scope=None,
|
|
93
|
+
client_id=None,
|
|
91
94
|
**kwargs,
|
|
92
95
|
):
|
|
93
96
|
client_kwargs = extract_client_kwargs(kwargs)
|
|
94
|
-
|
|
95
|
-
app_value = client_kwargs.pop("app", None)
|
|
96
|
-
if app_value is not None:
|
|
97
|
-
client_kwargs["transport"] = httpx.WSGITransport(app=app_value)
|
|
98
|
-
|
|
99
|
-
httpx.Client.__init__(self, **client_kwargs)
|
|
97
|
+
httpx2.Client.__init__(self, **client_kwargs)
|
|
100
98
|
|
|
101
99
|
_AssertionClient.__init__(
|
|
102
100
|
self,
|
|
@@ -109,6 +107,7 @@ class AssertionClient(_AssertionClient, httpx.Client):
|
|
|
109
107
|
claims=claims,
|
|
110
108
|
token_placement=token_placement,
|
|
111
109
|
scope=scope,
|
|
110
|
+
client_id=client_id,
|
|
112
111
|
**kwargs,
|
|
113
112
|
)
|
|
114
113
|
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
-
import httpx
|
|
4
|
-
from httpx import Auth
|
|
5
|
-
from httpx import Request
|
|
6
|
-
from httpx import Response
|
|
7
|
-
|
|
8
3
|
from authlib.common.encoding import to_unicode
|
|
9
4
|
from authlib.oauth1 import SIGNATURE_HMAC_SHA1
|
|
10
5
|
from authlib.oauth1 import SIGNATURE_TYPE_HEADER
|
|
@@ -12,12 +7,17 @@ from authlib.oauth1 import ClientAuth
|
|
|
12
7
|
from authlib.oauth1.client import OAuth1Client as _OAuth1Client
|
|
13
8
|
|
|
14
9
|
from ..base_client import OAuthError
|
|
10
|
+
from ._compat import httpx2
|
|
15
11
|
from .utils import build_request
|
|
16
12
|
from .utils import extract_client_kwargs
|
|
17
13
|
|
|
14
|
+
Auth = httpx2.Auth
|
|
15
|
+
Request = httpx2.Request
|
|
16
|
+
Response = httpx2.Response
|
|
17
|
+
|
|
18
18
|
|
|
19
19
|
class OAuth1Auth(Auth, ClientAuth):
|
|
20
|
-
"""Signs the
|
|
20
|
+
"""Signs the httpx2 request using OAuth 1 (RFC5849)."""
|
|
21
21
|
|
|
22
22
|
requires_request_body = True
|
|
23
23
|
|
|
@@ -31,7 +31,7 @@ class OAuth1Auth(Auth, ClientAuth):
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
class AsyncOAuth1Client(_OAuth1Client,
|
|
34
|
+
class AsyncOAuth1Client(_OAuth1Client, httpx2.AsyncClient):
|
|
35
35
|
auth_class = OAuth1Auth
|
|
36
36
|
|
|
37
37
|
def __init__(
|
|
@@ -49,7 +49,7 @@ class AsyncOAuth1Client(_OAuth1Client, httpx.AsyncClient):
|
|
|
49
49
|
**kwargs,
|
|
50
50
|
):
|
|
51
51
|
_client_kwargs = extract_client_kwargs(kwargs)
|
|
52
|
-
|
|
52
|
+
httpx2.AsyncClient.__init__(self, **_client_kwargs)
|
|
53
53
|
|
|
54
54
|
_OAuth1Client.__init__(
|
|
55
55
|
self,
|
|
@@ -99,7 +99,7 @@ class AsyncOAuth1Client(_OAuth1Client, httpx.AsyncClient):
|
|
|
99
99
|
raise OAuthError(error_type, error_description)
|
|
100
100
|
|
|
101
101
|
|
|
102
|
-
class OAuth1Client(_OAuth1Client,
|
|
102
|
+
class OAuth1Client(_OAuth1Client, httpx2.Client):
|
|
103
103
|
auth_class = OAuth1Auth
|
|
104
104
|
|
|
105
105
|
def __init__(
|
|
@@ -117,12 +117,7 @@ class OAuth1Client(_OAuth1Client, httpx.Client):
|
|
|
117
117
|
**kwargs,
|
|
118
118
|
):
|
|
119
119
|
_client_kwargs = extract_client_kwargs(kwargs)
|
|
120
|
-
|
|
121
|
-
app_value = _client_kwargs.pop("app", None)
|
|
122
|
-
if app_value is not None:
|
|
123
|
-
_client_kwargs["transport"] = httpx.WSGITransport(app=app_value)
|
|
124
|
-
|
|
125
|
-
httpx.Client.__init__(self, **_client_kwargs)
|
|
120
|
+
httpx2.Client.__init__(self, **_client_kwargs)
|
|
126
121
|
|
|
127
122
|
_OAuth1Client.__init__(
|
|
128
123
|
self,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
# ruff: noqa: I001
|
|
2
|
+
# The import order below is intentional: httpx compatibility must be loaded
|
|
3
|
+
# before anyio so import errors refer to httpx.
|
|
1
4
|
import typing
|
|
2
5
|
from contextlib import asynccontextmanager
|
|
3
6
|
|
|
4
|
-
import
|
|
7
|
+
from ._compat import httpx2
|
|
5
8
|
from anyio import Lock # Import after httpx so import errors refer to httpx
|
|
6
|
-
from httpx import USE_CLIENT_DEFAULT
|
|
7
|
-
from httpx import Auth
|
|
8
|
-
from httpx import Request
|
|
9
|
-
from httpx import Response
|
|
10
9
|
|
|
11
10
|
from authlib.common.urls import url_decode
|
|
12
11
|
from authlib.oauth2.auth import ClientAuth
|
|
@@ -20,6 +19,11 @@ from ..base_client import UnsupportedTokenTypeError
|
|
|
20
19
|
from .utils import HTTPX_CLIENT_KWARGS
|
|
21
20
|
from .utils import build_request
|
|
22
21
|
|
|
22
|
+
USE_CLIENT_DEFAULT = httpx2.USE_CLIENT_DEFAULT
|
|
23
|
+
Auth = httpx2.Auth
|
|
24
|
+
Request = httpx2.Request
|
|
25
|
+
Response = httpx2.Response
|
|
26
|
+
|
|
23
27
|
__all__ = [
|
|
24
28
|
"OAuth2Auth",
|
|
25
29
|
"OAuth2ClientAuth",
|
|
@@ -60,7 +64,7 @@ class OAuth2ClientAuth(Auth, ClientAuth):
|
|
|
60
64
|
)
|
|
61
65
|
|
|
62
66
|
|
|
63
|
-
class AsyncOAuth2Client(_OAuth2Client,
|
|
67
|
+
class AsyncOAuth2Client(_OAuth2Client, httpx2.AsyncClient):
|
|
64
68
|
SESSION_REQUEST_PARAMS = HTTPX_CLIENT_KWARGS
|
|
65
69
|
|
|
66
70
|
client_auth_class = OAuth2ClientAuth
|
|
@@ -81,9 +85,9 @@ class AsyncOAuth2Client(_OAuth2Client, httpx.AsyncClient):
|
|
|
81
85
|
leeway=60,
|
|
82
86
|
**kwargs,
|
|
83
87
|
):
|
|
84
|
-
# extract
|
|
88
|
+
# extract httpx2.Client kwargs
|
|
85
89
|
client_kwargs = self._extract_session_request_params(kwargs)
|
|
86
|
-
|
|
90
|
+
httpx2.AsyncClient.__init__(self, **client_kwargs)
|
|
87
91
|
|
|
88
92
|
# We use a Lock to synchronize coroutines to prevent
|
|
89
93
|
# multiple concurrent attempts to refresh the same token
|
|
@@ -208,7 +212,7 @@ class AsyncOAuth2Client(_OAuth2Client, httpx.AsyncClient):
|
|
|
208
212
|
)
|
|
209
213
|
|
|
210
214
|
|
|
211
|
-
class OAuth2Client(_OAuth2Client,
|
|
215
|
+
class OAuth2Client(_OAuth2Client, httpx2.Client):
|
|
212
216
|
SESSION_REQUEST_PARAMS = HTTPX_CLIENT_KWARGS
|
|
213
217
|
|
|
214
218
|
client_auth_class = OAuth2ClientAuth
|
|
@@ -228,14 +232,9 @@ class OAuth2Client(_OAuth2Client, httpx.Client):
|
|
|
228
232
|
update_token=None,
|
|
229
233
|
**kwargs,
|
|
230
234
|
):
|
|
231
|
-
# extract
|
|
235
|
+
# extract httpx2.Client kwargs
|
|
232
236
|
client_kwargs = self._extract_session_request_params(kwargs)
|
|
233
|
-
|
|
234
|
-
app_value = client_kwargs.pop("app", None)
|
|
235
|
-
if app_value is not None:
|
|
236
|
-
client_kwargs["transport"] = httpx.WSGITransport(app=app_value)
|
|
237
|
-
|
|
238
|
-
httpx.Client.__init__(self, **client_kwargs)
|
|
237
|
+
httpx2.Client.__init__(self, **client_kwargs)
|
|
239
238
|
|
|
240
239
|
_OAuth2Client.__init__(
|
|
241
240
|
self,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
from
|
|
1
|
+
from ._compat import httpx2
|
|
2
|
+
|
|
3
|
+
Request = httpx2.Request
|
|
2
4
|
|
|
3
5
|
HTTPX_CLIENT_KWARGS = [
|
|
4
6
|
"headers",
|
|
@@ -32,7 +34,10 @@ def extract_client_kwargs(kwargs):
|
|
|
32
34
|
def build_request(url, headers, body, initial_request: Request) -> Request:
|
|
33
35
|
"""Make sure that all the data from initial request is passed to the updated object."""
|
|
34
36
|
updated_request = Request(
|
|
35
|
-
method=initial_request.method,
|
|
37
|
+
method=initial_request.method,
|
|
38
|
+
url=url,
|
|
39
|
+
headers=headers,
|
|
40
|
+
content=body,
|
|
36
41
|
)
|
|
37
42
|
|
|
38
43
|
if hasattr(initial_request, "extensions"):
|
|
@@ -17,9 +17,7 @@ class AssertionAuth(OAuth2Auth):
|
|
|
17
17
|
|
|
18
18
|
class AssertionSession(AssertionClient, Session):
|
|
19
19
|
"""Constructs a new Assertion Framework for OAuth 2.0 Authorization Grants
|
|
20
|
-
per
|
|
21
|
-
|
|
22
|
-
.. _RFC7521: https://tools.ietf.org/html/rfc7521
|
|
20
|
+
per :rfc:`7521`.
|
|
23
21
|
"""
|
|
24
22
|
|
|
25
23
|
token_auth_class = AssertionAuth
|
|
@@ -39,6 +37,7 @@ class AssertionSession(AssertionClient, Session):
|
|
|
39
37
|
claims=None,
|
|
40
38
|
token_placement="header",
|
|
41
39
|
scope=None,
|
|
40
|
+
client_id=None,
|
|
42
41
|
default_timeout=None,
|
|
43
42
|
leeway=60,
|
|
44
43
|
**kwargs,
|
|
@@ -57,6 +56,7 @@ class AssertionSession(AssertionClient, Session):
|
|
|
57
56
|
claims=claims,
|
|
58
57
|
token_placement=token_placement,
|
|
59
58
|
scope=scope,
|
|
59
|
+
client_id=client_id,
|
|
60
60
|
leeway=leeway,
|
|
61
61
|
**kwargs,
|
|
62
62
|
)
|
|
@@ -22,9 +22,7 @@ class OAuth2ClientMixin(ClientMixin):
|
|
|
22
22
|
@property
|
|
23
23
|
def client_info(self):
|
|
24
24
|
"""Implementation for Client Info in OAuth 2.0 Dynamic Client
|
|
25
|
-
Registration Protocol via
|
|
26
|
-
|
|
27
|
-
.. _`Section 3.2.1`: https://tools.ietf.org/html/rfc7591#section-3.2.1
|
|
25
|
+
Registration Protocol via :rfc:`7591#section-3.2.1`.
|
|
28
26
|
"""
|
|
29
27
|
return dict(
|
|
30
28
|
client_id=self.client_id,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"""authlib.jose.draft.
|
|
2
2
|
~~~~~~~~~~~~~~~~~~~~
|
|
3
3
|
|
|
4
|
-
Content Encryption per
|
|
5
|
-
|
|
6
|
-
.. _`Section 4`: https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02#section-4
|
|
4
|
+
Content Encryption per
|
|
5
|
+
:draft:`draft-amringer-jose-chacha-02 Section 4 <draft-amringer-jose-chacha-02#section-4>`.
|
|
7
6
|
"""
|
|
8
7
|
|
|
9
8
|
from Cryptodome.Cipher import ChaCha20_Poly1305 as Cryptodome_ChaCha20_Poly1305
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"""authlib.jose.draft.
|
|
2
2
|
~~~~~~~~~~~~~~~~~~~~
|
|
3
3
|
|
|
4
|
-
Content Encryption per
|
|
5
|
-
|
|
6
|
-
.. _`Section 4`: https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02#section-4
|
|
4
|
+
Content Encryption per
|
|
5
|
+
:draft:`draft-amringer-jose-chacha-02 Section 4 <draft-amringer-jose-chacha-02#section-4>`.
|
|
7
6
|
"""
|
|
8
7
|
|
|
9
8
|
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
|
|
@@ -52,7 +52,7 @@ class JsonWebSignature:
|
|
|
52
52
|
def serialize_compact(self, protected, payload, key):
|
|
53
53
|
"""Generate a JWS Compact Serialization. The JWS Compact Serialization
|
|
54
54
|
represents digitally signed or MACed content as a compact, URL-safe
|
|
55
|
-
string, per
|
|
55
|
+
string, per :rfc:`7515#section-7.1`.
|
|
56
56
|
|
|
57
57
|
.. code-block:: text
|
|
58
58
|
|
|
@@ -81,15 +81,13 @@ class JsonWebSignature:
|
|
|
81
81
|
def deserialize_compact(self, s, key, decode=None):
|
|
82
82
|
"""Exact JWS Compact Serialization, and validate with the given key.
|
|
83
83
|
If key is not provided, the returned dict will contain the signature,
|
|
84
|
-
and signing input values. Via
|
|
84
|
+
and signing input values. Via :rfc:`7515#section-7.1`.
|
|
85
85
|
|
|
86
86
|
:param s: text of JWS Compact Serialization
|
|
87
87
|
:param key: key used to verify the signature
|
|
88
88
|
:param decode: a function to decode payload data
|
|
89
89
|
:return: JWSObject
|
|
90
90
|
:raise: BadSignatureError
|
|
91
|
-
|
|
92
|
-
.. _`Section 7.1`: https://tools.ietf.org/html/rfc7515#section-7.1
|
|
93
91
|
"""
|
|
94
92
|
if len(s) > self.MAX_CONTENT_LENGTH:
|
|
95
93
|
raise ValueError("Serialization is too long.")
|
|
@@ -119,7 +117,7 @@ class JsonWebSignature:
|
|
|
119
117
|
def serialize_json(self, header_obj, payload, key):
|
|
120
118
|
"""Generate a JWS JSON Serialization. The JWS JSON Serialization
|
|
121
119
|
represents digitally signed or MACed content as a JSON object,
|
|
122
|
-
per
|
|
120
|
+
per :rfc:`7515#section-7.2`.
|
|
123
121
|
|
|
124
122
|
:param header_obj: A dict/list of header
|
|
125
123
|
:param payload: A string/dict of payload
|
|
@@ -170,15 +168,13 @@ class JsonWebSignature:
|
|
|
170
168
|
def deserialize_json(self, obj, key, decode=None):
|
|
171
169
|
"""Exact JWS JSON Serialization, and validate with the given key.
|
|
172
170
|
If key is not provided, it will return a dict without signature
|
|
173
|
-
verification. Header will still be validated. Via
|
|
171
|
+
verification. Header will still be validated. Via :rfc:`7515#section-7.2`.
|
|
174
172
|
|
|
175
173
|
:param obj: text of JWS JSON Serialization
|
|
176
174
|
:param key: key used to verify the signature
|
|
177
175
|
:param decode: a function to decode payload data
|
|
178
176
|
:return: JWSObject
|
|
179
177
|
:raise: BadSignatureError
|
|
180
|
-
|
|
181
|
-
.. _`Section 7.2`: https://tools.ietf.org/html/rfc7515#section-7.2
|
|
182
178
|
"""
|
|
183
179
|
obj = ensure_dict(obj, "JWS")
|
|
184
180
|
|
|
@@ -204,6 +200,11 @@ class JsonWebSignature:
|
|
|
204
200
|
|
|
205
201
|
headers = []
|
|
206
202
|
is_valid = True
|
|
203
|
+
|
|
204
|
+
# invalidates cases like obj["signatures"] = None or obj["signatures"] = []
|
|
205
|
+
if not obj["signatures"]:
|
|
206
|
+
is_valid = False
|
|
207
|
+
|
|
207
208
|
for header_obj in obj["signatures"]:
|
|
208
209
|
jws_header, valid = self._validate_json_jws(
|
|
209
210
|
payload_segment, payload, header_obj, key
|