Skip to main content

OAuth2.0 and OpenID Connect Client Library

Project description

py-identity-model

Build License

OIDC/OAuth2.0 helper library for decoding JWTs and creating JWTs utilizing the client_credentials grant. This project is very limited in functionality, but it has been used in production for years as the foundation of Flask/FastAPI middleware implementations.

The use case for the library in its current form is limited to the following

  • Discovery endpoint is utilized
  • JWKS endpoint is utilized
  • Authorization servers with multiple active keys

While you can manually construct the validation configs required to manually bypass automated discovery, the library does not currently test those scenarios.

For more information on the lower level configuration options for token validation, refer to the official PyJWT Docs

Does not currently support opaque tokens.

Inspired By:

Examples

Discovery

Only a subset of fields is currently mapped.

import os

from py_identity_model import DiscoveryDocumentRequest, get_discovery_document

DISCO_ADDRESS = os.environ["DISCO_ADDRESS"]
    
disco_doc_request = DiscoveryDocumentRequest(address=DISCO_ADDRESS)
disco_doc_response = get_discovery_document(disco_doc_request)    
print(disco_doc_response)

JWKs

import os

from py_identity_model import (
    DiscoveryDocumentRequest, 
    get_discovery_document,
    JwksRequest, 
    get_jwks,
)

DISCO_ADDRESS = os.environ["DISCO_ADDRESS"]
    
disco_doc_request = DiscoveryDocumentRequest(address=DISCO_ADDRESS)
disco_doc_response = get_discovery_document(disco_doc_request)  

jwks_request = JwksRequest(address=disco_doc_response.jwks_uri)
jwks_response = get_jwks(jwks_request)
print(jwks_response)

Basic Token Validation

Token validation validates the signature of a JWT against the values provided from an OIDC discovery document. The function will throw an exception if the token is expired or signature validation fails.

Token validation is simply a wrapper on top of the jose.jwt.decode. The configuration object is mapped to the input parameters of jose.jwt.decode.

@dataclass
class TokenValidationConfig:
    perform_disco: bool
    key: Optional[dict] = None
    audience: Optional[str] = None
    algorithms: Optional[List[str]] = None
    issuer: Optional[List[str]] = None
    subject: Optional[str] = None
    options: Optional[dict] = None
import os

from py_identity_model import PyIdentityModelException, validate_token

DISCO_ADDRESS = os.environ["DISCO_ADDRESS"]

token = get_token() # Get the token in the manner best suited to your application

validation_options = {
    "verify_signature": True,
     "verify_aud": True,
     "verify_iat": True,
     "verify_exp": True,
     "verify_nbf": True,
     "verify_iss": True,
     "verify_sub": True,
     "verify_jti": True,
     "verify_at_hash": True,
     "require_aud": False,
     "require_iat": False,
     "require_exp": False,
     "require_nbf": False,
     "require_iss": False,
     "require_sub": False,
     "require_jti": False,
     "require_at_hash": False,
     "leeway": 0,
}

validation_config = TokenValidationConfig(
     perform_disco=True,
     audience=TEST_AUDIENCE,
     options=validation_options
)

claims = validate_token(jwt=token, disco_doc_address=DISCO_ADDRESS)
print(claims)

Token Generation

The only current supported flow is the client_credentials flow. Load configuration parameters in the method your application supports. Environment variables are used here for demonstration purposes.

Example:

import os

from py_identity_model import (
    ClientCredentialsTokenRequest,
    request_client_credentials_token,
    get_discovery_document,
    DiscoveryDocumentRequest,
)

DISCO_ADDRESS = os.environ["DISCO_ADDRESS"]
CLIENT_ID = os.environ["CLIENT_ID"]
CLIENT_SECRET = os.environ["CLIENT_SECRET"]
SCOPE = os.environ["SCOPE"]

disco_doc_response = get_discovery_document(
    DiscoveryDocumentRequest(address=DISCO_ADDRESS)
)

client_creds_req = ClientCredentialsTokenRequest(
	client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    address=disco_doc_response.token_endpoint,
    scope=SCOPE,
)
client_creds_token = request_client_credentials_token(client_creds_req)
print(client_creds_token)

Roadmap

These are in no particular order of importance. I am working on this project to bring a library as capable as IdentityModel to the Python ecosystem and will most likely focus on the needful and most used features first.

  • Protocol abstractions and constants
  • Discovery Endpoint
  • Token Endpoint
  • Token Introspection Endpoint
  • Token Revocation Endpoint
  • UserInfo Endpoint
  • Dynamic Client Registration
  • Device Authorization Endpoint
  • Token Validation
  • Example integrations with popular providers
  • Example middleware implementations for Flask and FastApi
  • async Support
  • Setup documentation
  • Opaque tokens

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_identity_model-0.13.0.tar.gz (10.6 kB view details)

Uploaded Source

Built Distribution

py_identity_model-0.13.0-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file py_identity_model-0.13.0.tar.gz.

File metadata

  • Download URL: py_identity_model-0.13.0.tar.gz
  • Upload date:
  • Size: 10.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.4 Linux/6.8.0-44-generic

File hashes

Hashes for py_identity_model-0.13.0.tar.gz
Algorithm Hash digest
SHA256 59d08ca34e1098f7c1156198262d76d21705d47e7b92c9965cfbd9ba689550e1
MD5 0d5062ffdf9033c9870a0138168952c3
BLAKE2b-256 5ff7ea76ddc088ba83b6caf7a7a2a6b18a52b7ecaf0d6f8727bd7344145ec511

See more details on using hashes here.

File details

Details for the file py_identity_model-0.13.0-py3-none-any.whl.

File metadata

  • Download URL: py_identity_model-0.13.0-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.4 Linux/6.8.0-44-generic

File hashes

Hashes for py_identity_model-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 47da264fcf3b2ea2306186fa67428ca761320b8fef37ed8638213ace782b5b84
MD5 6f9c6690556f7e11dc7c4a2430577b17
BLAKE2b-256 2c43100710d0b8d53763659b90b6598ec9bc37ae1a1bd5817fd7c9750915dcf5

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page