Skip to main content

Handle OAuth2 authentication for REST APIs

pypi version Build status Coverage Code style: black Number of tests Number of downloads

As expected by the HTTP specification, token is extracted from Authorization header and must be prefixed with Bearer .

Token will then be validated and in case it is valid, you will be able to access the raw token (as string) and the decoded token body (as dictionary).

Starlette

Provides a Starlette authentication backend: layabauth.starlette.OAuth2IdTokenBackend.

3 arguments are required:

  • The JWKs URI as defined in .well-known.
  • Azure Active Directory: https://sts.windows.net/common/discovery/keys
  • Microsoft Identity Platform: https://sts.windows.net/common/discovery/keys

Below is a sample Starlette application with an endpoint requesting a Microsoft issued OAuth2 token.

import starlette.applications
from starlette.authentication import SimpleUser, requires
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.responses import PlainTextResponse

import layabauth.starlette

backend = layabauth.starlette.OAuth2IdTokenBackend(
    jwks_uri="https://sts.windows.net/common/discovery/keys",
    create_user=lambda token, token_body: SimpleUser(token_body["name"]),
    scopes=lambda token, token_body: token_body["scopes"]
)
app = starlette.applications.Starlette(middleware=[Middleware(AuthenticationMiddleware, backend=backend)])

@app.route("/my_endpoint")
@requires('my_scope')
async def my_endpoint(request):
    return PlainTextResponse(request.user.display_name)

Flask

Provides a decorator layabauth.flask.requires_authentication to ensure that, in a context of a Flask application, a valid OAuth2 token was received.

The JWKs URI as defined in .well-known is the only required argument.

  • Azure Active Directory: https://sts.windows.net/common/discovery/keys
  • Microsoft Identity Platform: https://sts.windows.net/common/discovery/keys

If validation fails, an werkzeug.exceptions.Unauthorized exception is raised. Otherwise token is stored in flask.g.token and decoded token body is stored in flask.g.token_body.

Decorator works fine on flask-restplus methods as well.

Below is a sample Flask application with an endpoint requesting a Microsoft issued OAuth2 token.

import flask
import layabauth.flask

app = flask.Flask(__name__)

@app.route("/my_endpoint")
@layabauth.flask.requires_authentication("https://sts.windows.net/common/discovery/keys")
def my_endpoint():
    # Optional, ensure that the appropriates scopes are provided
    layabauth.flask.requires_scopes(lambda token, token_body: token_body["scopes"], "my_scope")
    # Return the content of the name entry within the decoded token body.
    return flask.Response(flask.g.token_body["name"])

app.run()

OpenAPI

You can generate OpenAPI 2.0 security definition thanks to layabauth.authorizations.

You can generate OpenAPI 2.0 method security thanks to layabauth.method_authorizations

Testing

Authentication can be mocked using layabauth.testing.auth_mock pytest fixture.

token_body pytest fixture returning the decoded token body used in tests must be provided. jwks_uri pytest fixture returning the jwks_uri used in tests must be provided.

from layabauth.testing import *


@pytest.fixture
def jwks_uri():
    return "https://sts.windows.net/common/discovery/keys"


@pytest.fixture
def token_body():
    return {"name": "TEST@email.com", "scopes": ["my_scope"]}


def test_authentication(auth_mock, client):
    response = client.get("/my_endpoint", headers={"Authentication": "Bearer mocked_token"})
    assert response.text == "TEST@email.com"

How to install

  1. python 3.6+ must be installed
  2. Use pip to install module:
python -m pip install layabauth

Release files for layabauth 6.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for layabauth 6.0.0
File Size Uploaded
layabauth-6.0.0.tar.gz 7.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for layabauth 6.0.0
File Interpreter ABI Platform
layabauth-6.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 15.9 kB

Release files / layabauth-6.0.0.tar.gz

Download URL layabauth-6.0.0.tar.gz
Size 7.3 kB
Tags Source
SHA-256 checksum
How to use checksums
60f721caf6af5cf477c7646e1b8cac97ddc760e906f41c95b9e05a8a4e8bfa50
BLAKE2b-256 checksum
How to use checksums
bcc368099bcb2b5b5c1d3c1f786fdaea41b270ed33be67af7d96af461b1eb3be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

Release files / layabauth-6.0.0-py3-none-any.whl

Download URL layabauth-6.0.0-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
014d8e986ccb25e726b6d7fe786c79c01562d67babd70feb8c3f719c59243ae4
BLAKE2b-256 checksum
How to use checksums
1b2ba544b8827731ac2fcb9aeeb2c8f6775e4ad2dcb2d710445e2d313c2d7fa5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

Release history Release notifications | RSS feed

7.0.0

2 release files

This release

6.0.0 This release

2 release files

5.1.0

2 release files

5.0.1

2 release files

5.0.0

2 release files

4.0.1

2 release files

4.0.0

2 release files

3.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page