Package: py-identity-model
py-identity-modelOIDC helper library. This project is very limited in functionality, but it has been used in production for years as the foundation of Flask/FastAPI middleware implementations.Does not currently support opaque tokens.Inspired By:IdentityModelcognitojwtExamplesDiscoveryOnly a subset of fields is currently mapped.importosfrompy_identity_modelimportDiscoveryDocumentRequest,get_discovery_documentDISCO_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)JWKsimportosfrompy_identity_modelimport(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 ValidationToken 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 thejose.jwt.decode. The configuration object is mapped to the input parameters ofjose.jwt.decode.@dataclassclassTokenValidationConfig:perform_disco:boolkey:Optional[dict]=Noneaudience:Optional[str]=Nonealgorithms:Optional[List[str]]=Noneissuer:Optional[List[str]]=Nonesubject:Optional[str]=Noneoptions:Optional[dict]=Noneimportosfrompy_identity_modelimportPyIdentityModelException,validate_tokenDISCO_ADDRESS=os.environ["DISCO_ADDRESS"]token=get_token()# Get the token in the manner best suited to your applicationvalidation_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 GenerationThe only current supported flow is theclient_credentialsflow. Load configuration parameters in the method your application supports. Environment variables are used here for demonstration purposes.Example:importosfrompy_identity_modelimport(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)RoadmapThese 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 constantsDiscovery EndpointToken EndpointToken Introspection EndpointToken Revocation EndpointUserInfo EndpointDynamic Client RegistrationDevice Authorization EndpointToken ValidationExample integrations with popular providersExample middleware implementations for Flask and FastApiasync SupportSetup documentationOpaque tokens