sag-py-auth-brand


Namesag-py-auth-brand JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://github.com/SamhammerAG/sag_py_auth_brand
SummaryKeycloak brand/instance authentication for python projects
upload_time2024-05-07 12:45:24
maintainerNone
docs_urlNone
authorSamhammer AG
requires_python>=3.8
licenseMIT
keywords auth fastapi keycloak
VCS
bugtrack_url
requirements contextvars fastapi sag-py-auth
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # sag_py_auth_brand

[![Maintainability][codeclimate-image]][codeclimate-url]
[![Coverage Status][coveralls-image]][coveralls-url]
[![Known Vulnerabilities](https://snyk.io/test/github/SamhammerAG/sag_py_auth_brand/badge.svg)](https://snyk.io/test/github/SamhammerAG/sag_py_auth_brand)

[coveralls-image]:https://coveralls.io/repos/github/SamhammerAG/sag_py_auth_brand/badge.svg?branch=master
[coveralls-url]:https://coveralls.io/github/SamhammerAG/sag_py_auth_brand?branch=master
[codeclimate-image]:https://api.codeclimate.com/v1/badges/9731a0fe593f7e5f10b6/maintainability
[codeclimate-url]:https://codeclimate.com/github/SamhammerAG/sag_py_auth_brand/maintainability

This provides a way to secure your fastapi with keycloak jwt bearer authentication.
This library bases on sag_py_auth and adds support for instances/brands.

## What it does
* Secure your api endpoints
* Verifies auth tokens: signature, expiration, issuer, audience
* Verifies the brand/customer over a token role
* Verifies the instance over a token role
* Verifies the stage over a realm role
* Allows to set additional permissions by specifying further token roles
* Supplies brand information from context

## How to use

### Installation

pip install sag-py-auth-brand

### Secure your apis

First create the fast api dependency with the auth config:
```python
from sag_py_auth import TokenRole
from sag_py_auth_brand.models import AuthConfig
from sag_py_auth_brand.brand_jwt_auth import BrandJwtAuth
from fastapi import Depends

auth_config = BrandAuthConfig("https://authserver.com/auth/realms/projectName", "myaudience", "myinstance", "mystage")
required_roles = [TokenRole("clientname", "adminrole")]
requires_admin = Depends(BrandJwtAuth(auth_config, required_endpoint_roles))
```

Afterwards you can use it in your route like that:

```python
@app.post("/posts", dependencies=[requires_admin], tags=["posts"])
async def add_post(post: PostSchema) -> dict:
```

Or if you use sub routes, auth can also be enforced for the entire route like that:

```python
router = APIRouter()
router.include_router(sub_router, tags=["my_api_tag"], prefix="/subroute",dependencies=[requires_admin])
```

### Get brand information

See sag_py_auth to find out how to access the token and user info.

Furthermore you can get the brand by accessing it over the context:
```python
from sag_py_auth_brand.request_brand_context import get_request_brand as get_brand_from_context
brand = get_brand_from_context()
```

This works in async calls but not in sub threads (without additional changes).

See:
* https://docs.python.org/3/library/contextvars.html
* https://kobybass.medium.com/python-contextvars-and-multithreading-faa33dbe953d

### Log the brand

It is possible to log the brand by adding a filter.

```python
import logging
from sag_py_auth_brand.request_brand_logging_filter import RequestBrandLoggingFilter

console_handler = logging.StreamHandler(sys.stdout)
console_handler.addFilter(RequestBrandLoggingFilter())

```

The filter provides the field request_brand with the brand.

### How a token has to look like

```json
{

    "iss": "https://authserver.com/auth/realms/projectName",
    "aud": ["audienceOne", "audienceTwo"],
    "typ": "Bearer",
    "azp": "public-project-swagger",
    "preferred_username": "preferredUsernameValue",
    .....
    "realm_access": {
        "roles": ["myStage"]
    },
    "resource_access": {
        "role-instance": {
            "roles": ["myInstance"]
        },
        "role-brand": {
            "roles": ["myBrand"]
        },
        "role-endpoint": {
            "roles": ["permissionOne", "permissionTwo"]
        }
    }
}
```

* role-endpoint is just required for permission checks of the api endpoint

## How to start developing

### With vscode

Just install vscode with dev containers extension. All required extensions and configurations are prepared automatically.

### With pycharm

* Install latest pycharm
* Install pycharm plugin BlackConnect
* Install pycharm plugin Mypy
* Configure the python interpreter/venv
* pip install requirements-dev.txt
* pip install black[d]
* Ctl+Alt+S => Check Tools => BlackConnect => Trigger when saving changed files
* Ctl+Alt+S => Check Tools => BlackConnect => Trigger on code reformat
* Ctl+Alt+S => Click Tools => BlackConnect => "Load from pyproject.yaml" (ensure line length is 120)
* Ctl+Alt+S => Click Tools => BlackConnect => Configure path to the blackd.exe at the "local instance" config (e.g. C:\Python310\Scripts\blackd.exe)
* Ctl+Alt+S => Click Tools => Actions on save => Reformat code
* Restart pycharm

## How to publish

* Update the version in setup.py and commit your change
* Create a tag with the same version number
* Let github do the rest

## How to test

To avoid publishing to pypi unnecessarily you can do as follows

* Tag your branch however you like
* Use the chosen tag in the requirements.txt-file of the project you want to test this library in, eg. `sag_py_auth_brand==<your tag>`
* Rebuild/redeploy your project

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/SamhammerAG/sag_py_auth_brand",
    "name": "sag-py-auth-brand",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "auth, fastapi, keycloak",
    "author": "Samhammer AG",
    "author_email": "support@samhammer.de",
    "download_url": "https://files.pythonhosted.org/packages/f3/06/df9202070e4dc6bf9e7de87210234546c4c71d233948ca1a00d3dedf4bd2/sag_py_auth_brand-0.3.1.tar.gz",
    "platform": null,
    "description": "# sag_py_auth_brand\n\n[![Maintainability][codeclimate-image]][codeclimate-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n[![Known Vulnerabilities](https://snyk.io/test/github/SamhammerAG/sag_py_auth_brand/badge.svg)](https://snyk.io/test/github/SamhammerAG/sag_py_auth_brand)\n\n[coveralls-image]:https://coveralls.io/repos/github/SamhammerAG/sag_py_auth_brand/badge.svg?branch=master\n[coveralls-url]:https://coveralls.io/github/SamhammerAG/sag_py_auth_brand?branch=master\n[codeclimate-image]:https://api.codeclimate.com/v1/badges/9731a0fe593f7e5f10b6/maintainability\n[codeclimate-url]:https://codeclimate.com/github/SamhammerAG/sag_py_auth_brand/maintainability\n\nThis provides a way to secure your fastapi with keycloak jwt bearer authentication.\nThis library bases on sag_py_auth and adds support for instances/brands.\n\n## What it does\n* Secure your api endpoints\n* Verifies auth tokens: signature, expiration, issuer, audience\n* Verifies the brand/customer over a token role\n* Verifies the instance over a token role\n* Verifies the stage over a realm role\n* Allows to set additional permissions by specifying further token roles\n* Supplies brand information from context\n\n## How to use\n\n### Installation\n\npip install sag-py-auth-brand\n\n### Secure your apis\n\nFirst create the fast api dependency with the auth config:\n```python\nfrom sag_py_auth import TokenRole\nfrom sag_py_auth_brand.models import AuthConfig\nfrom sag_py_auth_brand.brand_jwt_auth import BrandJwtAuth\nfrom fastapi import Depends\n\nauth_config = BrandAuthConfig(\"https://authserver.com/auth/realms/projectName\", \"myaudience\", \"myinstance\", \"mystage\")\nrequired_roles = [TokenRole(\"clientname\", \"adminrole\")]\nrequires_admin = Depends(BrandJwtAuth(auth_config, required_endpoint_roles))\n```\n\nAfterwards you can use it in your route like that:\n\n```python\n@app.post(\"/posts\", dependencies=[requires_admin], tags=[\"posts\"])\nasync def add_post(post: PostSchema) -> dict:\n```\n\nOr if you use sub routes, auth can also be enforced for the entire route like that:\n\n```python\nrouter = APIRouter()\nrouter.include_router(sub_router, tags=[\"my_api_tag\"], prefix=\"/subroute\",dependencies=[requires_admin])\n```\n\n### Get brand information\n\nSee sag_py_auth to find out how to access the token and user info.\n\nFurthermore you can get the brand by accessing it over the context:\n```python\nfrom sag_py_auth_brand.request_brand_context import get_request_brand as get_brand_from_context\nbrand = get_brand_from_context()\n```\n\nThis works in async calls but not in sub threads (without additional changes).\n\nSee:\n* https://docs.python.org/3/library/contextvars.html\n* https://kobybass.medium.com/python-contextvars-and-multithreading-faa33dbe953d\n\n### Log the brand\n\nIt is possible to log the brand by adding a filter.\n\n```python\nimport logging\nfrom sag_py_auth_brand.request_brand_logging_filter import RequestBrandLoggingFilter\n\nconsole_handler = logging.StreamHandler(sys.stdout)\nconsole_handler.addFilter(RequestBrandLoggingFilter())\n\n```\n\nThe filter provides the field request_brand with the brand.\n\n### How a token has to look like\n\n```json\n{\n\n    \"iss\": \"https://authserver.com/auth/realms/projectName\",\n    \"aud\": [\"audienceOne\", \"audienceTwo\"],\n    \"typ\": \"Bearer\",\n    \"azp\": \"public-project-swagger\",\n    \"preferred_username\": \"preferredUsernameValue\",\n    .....\n    \"realm_access\": {\n        \"roles\": [\"myStage\"]\n    },\n    \"resource_access\": {\n        \"role-instance\": {\n            \"roles\": [\"myInstance\"]\n        },\n        \"role-brand\": {\n            \"roles\": [\"myBrand\"]\n        },\n        \"role-endpoint\": {\n            \"roles\": [\"permissionOne\", \"permissionTwo\"]\n        }\n    }\n}\n```\n\n* role-endpoint is just required for permission checks of the api endpoint\n\n## How to start developing\n\n### With vscode\n\nJust install vscode with dev containers extension. All required extensions and configurations are prepared automatically.\n\n### With pycharm\n\n* Install latest pycharm\n* Install pycharm plugin BlackConnect\n* Install pycharm plugin Mypy\n* Configure the python interpreter/venv\n* pip install requirements-dev.txt\n* pip install black[d]\n* Ctl+Alt+S => Check Tools => BlackConnect => Trigger when saving changed files\n* Ctl+Alt+S => Check Tools => BlackConnect => Trigger on code reformat\n* Ctl+Alt+S => Click Tools => BlackConnect => \"Load from pyproject.yaml\" (ensure line length is 120)\n* Ctl+Alt+S => Click Tools => BlackConnect => Configure path to the blackd.exe at the \"local instance\" config (e.g. C:\\Python310\\Scripts\\blackd.exe)\n* Ctl+Alt+S => Click Tools => Actions on save => Reformat code\n* Restart pycharm\n\n## How to publish\n\n* Update the version in setup.py and commit your change\n* Create a tag with the same version number\n* Let github do the rest\n\n## How to test\n\nTo avoid publishing to pypi unnecessarily you can do as follows\n\n* Tag your branch however you like\n* Use the chosen tag in the requirements.txt-file of the project you want to test this library in, eg. `sag_py_auth_brand==<your tag>`\n* Rebuild/redeploy your project\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Keycloak brand/instance authentication for python projects",
    "version": "0.3.1",
    "project_urls": {
        "Bug Reports": "https://github.com/SamhammerAG/sag_py_auth_brand/issues",
        "Documentation": "https://github.com/SamhammerAG/sag_py_auth_brand",
        "Homepage": "https://github.com/SamhammerAG/sag_py_auth_brand",
        "Source": "https://github.com/SamhammerAG/sag_py_auth_brand"
    },
    "split_keywords": [
        "auth",
        " fastapi",
        " keycloak"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "af10fec541f226d2e61fb1cea56bda8c9152ea457defe2006e29661829882f1f",
                "md5": "f1ecfcc44cc526b7730e5236e8b05cb0",
                "sha256": "2a12a707625acd0c965929994c95c73f101dc173148ef06fd49d2da041d0969f"
            },
            "downloads": -1,
            "filename": "sag_py_auth_brand-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f1ecfcc44cc526b7730e5236e8b05cb0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 6951,
            "upload_time": "2024-05-07T12:45:22",
            "upload_time_iso_8601": "2024-05-07T12:45:22.545181Z",
            "url": "https://files.pythonhosted.org/packages/af/10/fec541f226d2e61fb1cea56bda8c9152ea457defe2006e29661829882f1f/sag_py_auth_brand-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f306df9202070e4dc6bf9e7de87210234546c4c71d233948ca1a00d3dedf4bd2",
                "md5": "1b742f6c47488ebb60b420281b6260a0",
                "sha256": "5a23a2dc72c8264414a3897cb2d369f32962965307dcb7480e553a57df9eca18"
            },
            "downloads": -1,
            "filename": "sag_py_auth_brand-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "1b742f6c47488ebb60b420281b6260a0",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 8073,
            "upload_time": "2024-05-07T12:45:24",
            "upload_time_iso_8601": "2024-05-07T12:45:24.531219Z",
            "url": "https://files.pythonhosted.org/packages/f3/06/df9202070e4dc6bf9e7de87210234546c4c71d233948ca1a00d3dedf4bd2/sag_py_auth_brand-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-07 12:45:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "SamhammerAG",
    "github_project": "sag_py_auth_brand",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "contextvars",
            "specs": [
                [
                    ">=",
                    "2.4"
                ]
            ]
        },
        {
            "name": "fastapi",
            "specs": [
                [
                    ">=",
                    "0.110.3"
                ]
            ]
        },
        {
            "name": "sag-py-auth",
            "specs": [
                [
                    ">=",
                    "0.1.7"
                ]
            ]
        }
    ],
    "lcname": "sag-py-auth-brand"
}
        
Elapsed time: 0.27028s