py-identity-model


Namepy-identity-model JSON
Version 0.11.2 PyPI version JSON
download
home_pagehttps://github.com/jamescrowley321/py-oidc
SummaryOAuth2.0 and OpenID Connect Client Library
upload_time2024-02-24 17:32:55
maintainer
docs_urlNone
authorJames Crowley
requires_python
licenseApache 2.0
keywords openid jwt
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # py-identity-model
![Build](https://github.com/jamescrowley321/py-identity-model/workflows/Build/badge.svg)
![License](https://img.shields.io/pypi/l/py-identity-model)

OIDC 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:

* [IdentityModel](https://github.com/IdentityModel/IdentityModel)
* [cognitojwt](https://github.com/borisrozumnuk/cognitojwt)

## Examples

### Discovery

Only a subset of fields is currently mapped.

```python
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

```python
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](https://python-jose.readthedocs.io/en/latest/jwt/api.html#jose.jwt.decode). The configuration object is mapped to the input parameters of `jose.jwt.decode`. 

```python
@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
```



```python
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:

```python
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

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/jamescrowley321/py-oidc",
    "name": "py-identity-model",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "OpenID jwt",
    "author": "James Crowley",
    "author_email": "jamescrowley151@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cd/dd/7faa930be6dca0bd83ffd540d0ac76cb7bf19a0847ea764c8e78bc371865/py_identity_model-0.11.2.tar.gz",
    "platform": "Any",
    "description": "# py-identity-model\n![Build](https://github.com/jamescrowley321/py-identity-model/workflows/Build/badge.svg)\n![License](https://img.shields.io/pypi/l/py-identity-model)\n\nOIDC 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.\n\nDoes not currently support opaque tokens.\n\nInspired By:\n\n* [IdentityModel](https://github.com/IdentityModel/IdentityModel)\n* [cognitojwt](https://github.com/borisrozumnuk/cognitojwt)\n\n## Examples\n\n### Discovery\n\nOnly a subset of fields is currently mapped.\n\n```python\nimport os\n\nfrom py_identity_model import DiscoveryDocumentRequest, get_discovery_document\n\nDISCO_ADDRESS = os.environ[\"DISCO_ADDRESS\"]\n    \ndisco_doc_request = DiscoveryDocumentRequest(address=DISCO_ADDRESS)\ndisco_doc_response = get_discovery_document(disco_doc_request)    \nprint(disco_doc_response)\n```\n\n### JWKs\n\n```python\nimport os\n\nfrom py_identity_model import (\n    DiscoveryDocumentRequest, \n    get_discovery_document,\n    JwksRequest, \n    get_jwks,\n)\n\nDISCO_ADDRESS = os.environ[\"DISCO_ADDRESS\"]\n    \ndisco_doc_request = DiscoveryDocumentRequest(address=DISCO_ADDRESS)\ndisco_doc_response = get_discovery_document(disco_doc_request)  \n\njwks_request = JwksRequest(address=disco_doc_response.jwks_uri)\njwks_response = get_jwks(jwks_request)\nprint(jwks_response)\n```\n\n### Basic Token Validation\n\nToken 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.\n\nToken validation is simply a wrapper on top of the [jose.jwt.decode](https://python-jose.readthedocs.io/en/latest/jwt/api.html#jose.jwt.decode). The configuration object is mapped to the input parameters of `jose.jwt.decode`. \n\n```python\n@dataclass\nclass TokenValidationConfig:\n    perform_disco: bool\n    key: Optional[dict] = None\n    audience: Optional[str] = None\n    algorithms: Optional[List[str]] = None\n    issuer: Optional[List[str]] = None\n    subject: Optional[str] = None\n    options: Optional[dict] = None\n```\n\n\n\n```python\nimport os\n\nfrom py_identity_model import PyIdentityModelException, validate_token\n\nDISCO_ADDRESS = os.environ[\"DISCO_ADDRESS\"]\n\ntoken = get_token() # Get the token in the manner best suited to your application\n\nvalidation_options = {\n    \"verify_signature\": True,\n     \"verify_aud\": True,\n     \"verify_iat\": True,\n     \"verify_exp\": True,\n     \"verify_nbf\": True,\n     \"verify_iss\": True,\n     \"verify_sub\": True,\n     \"verify_jti\": True,\n     \"verify_at_hash\": True,\n     \"require_aud\": False,\n     \"require_iat\": False,\n     \"require_exp\": False,\n     \"require_nbf\": False,\n     \"require_iss\": False,\n     \"require_sub\": False,\n     \"require_jti\": False,\n     \"require_at_hash\": False,\n     \"leeway\": 0,\n}\n\nvalidation_config = TokenValidationConfig(\n     perform_disco=True,\n     audience=TEST_AUDIENCE,\n     options=validation_options\n)\n\nclaims = validate_token(jwt=token, disco_doc_address=DISCO_ADDRESS)\nprint(claims)\n```\n\n### Token Generation\n\nThe 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.\n\nExample:\n\n```python\nimport os\n\nfrom py_identity_model import (\n    ClientCredentialsTokenRequest,\n    request_client_credentials_token,\n    get_discovery_document,\n    DiscoveryDocumentRequest,\n)\n\nDISCO_ADDRESS = os.environ[\"DISCO_ADDRESS\"]\nCLIENT_ID = os.environ[\"CLIENT_ID\"]\nCLIENT_SECRET = os.environ[\"CLIENT_SECRET\"]\nSCOPE = os.environ[\"SCOPE\"]\n\ndisco_doc_response = get_discovery_document(\n    DiscoveryDocumentRequest(address=DISCO_ADDRESS)\n)\n\nclient_creds_req = ClientCredentialsTokenRequest(\n\tclient_id=CLIENT_ID,\n    client_secret=CLIENT_SECRET,\n    address=disco_doc_response.token_endpoint,\n    scope=SCOPE,\n)\nclient_creds_token = request_client_credentials_token(client_creds_req)\nprint(client_creds_token)\n```\n\n## Roadmap\nThese 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.\n* Protocol abstractions and constants\n* Discovery Endpoint\n* Token Endpoint\n* Token Introspection Endpoint\n* Token Revocation Endpoint\n* UserInfo Endpoint\n* Dynamic Client Registration\n* Device Authorization Endpoint\n* Token Validation\n* Example integrations with popular providers\n* Example middleware implementations for Flask and FastApi\n* async Support\n* Setup documentation\n* Opaque tokens\n",
    "bugtrack_url": null,
    "license": "Apache 2.0",
    "summary": "OAuth2.0 and OpenID Connect Client Library",
    "version": "0.11.2",
    "project_urls": {
        "Homepage": "https://github.com/jamescrowley321/py-oidc"
    },
    "split_keywords": [
        "openid",
        "jwt"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cddd7faa930be6dca0bd83ffd540d0ac76cb7bf19a0847ea764c8e78bc371865",
                "md5": "574db73794aa586fbd46f2674a729c67",
                "sha256": "14d198826eb4692b9bd15af879042f6ffa64478365eb2f502c202bffc2df9263"
            },
            "downloads": -1,
            "filename": "py_identity_model-0.11.2.tar.gz",
            "has_sig": false,
            "md5_digest": "574db73794aa586fbd46f2674a729c67",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 10973,
            "upload_time": "2024-02-24T17:32:55",
            "upload_time_iso_8601": "2024-02-24T17:32:55.620257Z",
            "url": "https://files.pythonhosted.org/packages/cd/dd/7faa930be6dca0bd83ffd540d0ac76cb7bf19a0847ea764c8e78bc371865/py_identity_model-0.11.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-24 17:32:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "jamescrowley321",
    "github_project": "py-oidc",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "py-identity-model"
}
        
Elapsed time: 0.20408s