|
| 1 | +[](https://www.gnu.org/licenses/gpl-3.0) |
| 2 | +[](https://pypi.org/project/asgi-claim-validator/) |
| 3 | +[](https://pypi.org/project/asgi-claim-validator/) |
| 4 | +[](https://pypi.org/project/asgi-claim-validator/) |
| 5 | +[](https://libraries.io/pypi/asgi-claim-validator) |
| 6 | +[](https://github.com/feteu/asgi-claim-validator/commits/main) |
| 7 | +[](https://github.com/feteu/asgi-claim-validator/actions/workflows/publish-testpypi.yaml) |
| 8 | +[](https://github.com/feteu/asgi-claim-validator/actions/workflows/publish-pypi.yaml) |
| 9 | +[](https://github.com/feteu/asgi-claim-validator/actions/workflows/test.yaml) |
| 10 | + |
1 | 11 | # asgi-claim-validator
|
| 12 | + |
2 | 13 | A focused ASGI middleware for validating additional claims within JWT tokens to enhance token-based workflows.
|
| 14 | + |
| 15 | +## Overview |
| 16 | + |
| 17 | +`asgi-claim-validator` is an ASGI middleware designed to validate additional claims within JWT tokens. Built in addition to the default JWT verification implementation of Connexion, it enhances token-based workflows by ensuring that specific claims are present and meet certain criteria before allowing access to protected endpoints. This middleware allows consumers to validate claims on an endpoint/method level and is compatible with popular ASGI frameworks such as Starlette, FastAPI, and Connexion. |
| 18 | + |
| 19 | +## Features |
| 20 | + |
| 21 | +- **Claim Validation**: Validate specific claims within JWT tokens, such as `sub`, `iss`, `aud`, `exp`, `iat`, and `nbf`. |
| 22 | +- **Customizable Claims**: Define essential claims, allowed values, and whether blank values are permitted. |
| 23 | +- **Path and Method Filtering**: Apply claim validation to specific paths and HTTP methods. |
| 24 | +- **Exception Handling**: Integrate with custom exception handlers to provide meaningful error responses. |
| 25 | +- **Logging**: Log validation errors for debugging and monitoring purposes. |
| 26 | + |
| 27 | +## Installation |
| 28 | + |
| 29 | +Install the package using pip: |
| 30 | + |
| 31 | +```sh |
| 32 | +pip install asgi-claim-validator |
| 33 | +``` |
| 34 | + |
| 35 | +## Usage |
| 36 | + |
| 37 | +### Basic Usage |
| 38 | + |
| 39 | +Here's an example of how to use `asgi-claim-validator` with Starlette: |
| 40 | + |
| 41 | +```python |
| 42 | +from starlette.applications import Starlette |
| 43 | +from starlette.requests import Request |
| 44 | +from starlette.responses import JSONResponse |
| 45 | +from starlette.routing import Route |
| 46 | +from asgi_claim_validator import ClaimValidatorMiddleware |
| 47 | + |
| 48 | +async def secured_endpoint(request: Request) -> JSONResponse: |
| 49 | + return JSONResponse({"message": "secured"}) |
| 50 | + |
| 51 | +app = Starlette(routes=[ |
| 52 | + Route("/secured", secured_endpoint, methods=["GET"]), |
| 53 | +]) |
| 54 | + |
| 55 | +app.add_middleware( |
| 56 | + ClaimValidatorMiddleware, |
| 57 | + claims_callable=lambda: { |
| 58 | + "sub": "admin", |
| 59 | + "iss": "https://example.com", |
| 60 | + }, |
| 61 | + secured={ |
| 62 | + "^/secured$": { |
| 63 | + "GET": { |
| 64 | + "sub": { |
| 65 | + "essential": True, |
| 66 | + "allow_blank": False, |
| 67 | + "values": ["admin"], |
| 68 | + }, |
| 69 | + "iss": { |
| 70 | + "essential": True, |
| 71 | + "allow_blank": False, |
| 72 | + "values": ["https://example.com"], |
| 73 | + }, |
| 74 | + }, |
| 75 | + } |
| 76 | + }, |
| 77 | +) |
| 78 | +``` |
| 79 | + |
| 80 | +## Advanced Usage |
| 81 | + |
| 82 | +### Custom Exception Handlers |
| 83 | + |
| 84 | +Integrate `asgi-claim-validator` with custom exception handlers to provide meaningful error responses. Below are examples for Starlette and Connexion. Refer to the specific framework examples in the [examples](examples) directory for detailed implementation. |
| 85 | + |
| 86 | +### Middleware Configuration |
| 87 | + |
| 88 | +Configure the middleware with the following options: |
| 89 | + |
| 90 | +- **claims_callable**: A callable that returns the JWT claims to be validated. |
| 91 | +- **secured**: A dictionary defining the paths and methods that require claim validation. |
| 92 | +- **skipped**: A dictionary defining the paths and methods to be excluded from claim validation. |
| 93 | +- **raise_on_unspecified_path**: Raise an exception if the path is not specified in the `secured` or `skipped` dictionaries. |
| 94 | +- **raise_on_unspecified_method**: Raise an exception if the method is not specified for a secured path. |
| 95 | + |
| 96 | +### Claim Validation Options |
| 97 | + |
| 98 | +Configure claims with the following options: |
| 99 | + |
| 100 | +- **essential**: Indicates if the claim is essential (default: `False`). |
| 101 | +- **allow_blank**: Indicates if blank values are allowed (default: `True`). |
| 102 | +- **values**: A list of allowed values for the claim. |
| 103 | + |
| 104 | +## Examples |
| 105 | + |
| 106 | +### Starlette Example |
| 107 | +Refer to the [app.py](examples/starlette/simple/app.py) file for a complete example using Starlette. |
| 108 | + |
| 109 | +### Connexion Example |
| 110 | +Refer to the [app.py](examples/connexion/simple/app.py) file for a complete example using Connexion. |
| 111 | + |
| 112 | +## Testing |
| 113 | +Run the tests using `pytest`: |
| 114 | + |
| 115 | +```sh |
| 116 | +poetry run pytest |
| 117 | +``` |
| 118 | + |
| 119 | +## Contributing |
| 120 | +Contributions are welcome! Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on how to contribute to this project. |
| 121 | + |
| 122 | +## License |
| 123 | +This project is licensed under the GNU GPLv3 License. See the [LICENSE](LICENSE) file for more details. |
0 commit comments