Skip to content

Releases: waza-ari/fastapi-keycloak-middleware

Version v1.1.0

28 Jul 17:47
4bdd1f8
Compare
Choose a tag to compare

New Features

Dependency based permission checking

This release introduces a new way of handling authorisation. The library now favours a dependency based approach for permission handling instead of the previous decorator based approach.

Warning

The old decorator based approach using the @require_permission decorator is now deprecated and will be removed in version 2 of this library. For now, no breaking changes have been introduced. See the section about deprecations below for details

Migration

The most simple case is a normal permission. In this case, it can simply be rewritten by changing the @require_permission decorator to the CheckPermission dependency as follows:

# Old
@router.get("/your-endpoint")
@require_permission("your_permission")
async def your_endpoint(user = Depends(get_user)):
    pass

# New
@router.get(
    "/your-endpoint",
    dependencies=[Depends(CheckPermissions("your_permission"))],
)
async def your_endpoint():
    pass

Tip

Note that the new version doesn't include the get_user dependency anymore. Using the CheckPermission dependency automatically makes sure a user is successfully authenticated by presenting a valid token. You can of course still use the get_user dependency is you need a reference to the user:

@router.get(
    "/your-endpoint",
    dependencies=[Depends(CheckPermissions("your_permission"))],
)
async def your_endpoint(user = Depends(get_user)):
    pass

Complex permission matching

The new approach supports the same more complex patterns that the decorator based approach supported. You can provide a list of permissions and optionally a strategy that should be applied:

@router.get(
    "/your-endpoint",
    dependencies=[Depends(CheckPermissions(["your_first_permission", "your_second_permission"], match_strategy=MatchStrategy.OR))],
)
async def your_endpoint():
    pass

Accessing the authorisation result

If you need to access the result (e.g. based on which permission the user was allowed access), you can now simply use the dependency result instead of using the decorator + the legacy get_authorization_result dependency:

@router.get("/your-endpoint")
async def your_endpoint(authorization_result: AuthorizationResult = Depends(CheckPermissions(["your_first_permission", "your_second_permission"], match_strategy=MatchStrategy.OR))):
    pass

New Doc section: testing

The docs have been extended and now include a section about my perceived best practices when testing applications secured by this library. These might not be the best ideas, I'm happy to hear about better options.

Deprecations

⚠️ The require_permission decorator is deprecated and scheduled to be removed in the next major release.

The previous approach was based on the middleware injecting users and roles into the request scope, and then having the require_permission extracting them from the request to perform access validation. It then injects the authorisation result to the next function call, but only if the dependency has been added to the method.

This approach was quite inflexible and "hacky", it required manual modification of the method signature if the dependency was used. This new approach makes testing simpler, will allow us to remove fairly complicated code in the future and is more in line with FastAPI principles.

⚠️ As a consequence, also the get_authorization_result is being marked as deprecated and is scheduled to be removed in the next major release.

Important

Both methods will emit a standard Python DeprecationWarning from this release onwards.

Full Changelog

feat: implement new way of handling authorization, switching away from the decorator approach. Currently, the decorator approach is still supported, it is marked deprecated in this release though.
[docs: adjust docs to correctly have authorization related config settings in KeycloakConfiguration. Fixes https://github.com//issues/54
build: raise version number to 1.0.2
fix: deprecation warnings after switching to Pydantic v2
fix: type hint of validation_option had wrong brackets](docs: adjust docs to correctly have authorization related config settings in KeycloakConfiguration. Fixes #54)docs: adjust docs to correctly have authorization related config settings in KeycloakConfiguration. Fixes #54
fix: remove non-required statements from init file
dev: add mypy cache files to gitignore
style: fix various typing issues

Full Changelog: v1.0.2...v1.1.0

v1.0.2

21 Jul 13:49
3747605
Compare
Choose a tag to compare

v1.0.1

19 May 09:31
Compare
Choose a tag to compare

Breaking Changes

No breaking changes have been introduced.

Full Changelog

fix: type hint of validation_option had wrong brackets

Full Changelog: v0.1.0...v1.0.1

v1.0.0

19 May 08:54
Compare
Choose a tag to compare

Breaking Changes

The underlying python-keycloak library has been updated to v4.0.0. This changes a couple of things:

  • python-jose has been replaced with JWCrypto for token validation. This means that the options that are available to customise token validation have changed
  • As a consequence, the decode_options setting of KeycloakConfiguration has been removed. In previous versions it was passed to python-keycloak which in turn passed it to python-jose
  • Two new settings have been introduced:
    • validate_token accepts a boolean value and controls whether python-keycloak will attempt to validate the token or not
    • validation_options accepts kwargs that are passed straight to the JWT constructor. Check the JWCrypto documentation for a list of supported arguments

Full Changelog

fix: use correct type for validation_options
waza-ari
chore: update python-keycloak to v4.0.0
waza-ari

Full Changelog: v0.4.2...v1.0.0

Release v0.4.2

18 May 10:10
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v0.4.1...v0.4.2

v0.4.1

30 Apr 17:23
Compare
Choose a tag to compare

Version 0.4.0

18 Apr 14:57
Compare
Choose a tag to compare

Overview

Changes

  • New setup method to add middleware to FastAPI app - enabling additional features
  • Error response code added to OpenAPI spec by default
  • JSONResponse instead of PlainTextResponse following a consistent schema

New Features

  • Swagger UI Authentication

Important Changes

New Setup Method

This version introduces a new method to configure the middleware for your FastAPI application. The old method of adding the Middleware class directly is still available and supported, therefore consider this as a new method adding new options while maintaining backwards compatibility.

Old usage

from fastapi_keycloak_middleware import KeycloakConfiguration, KeycloakMiddleware

# Set up Keycloak
 keycloak_config = KeycloakConfiguration(
   ...
 )

 app = FastAPI()

 # Add middleware with basic config
 app.add_middleware(
     KeycloakMiddleware,
     keycloak_configuration=keycloak_config,
 )

New usage

from fastapi_keycloak_middleware import KeycloakConfiguration, setup_keycloak_middleware

# Set up Keycloak
 keycloak_config = KeycloakConfiguration(
   ...
 )

 app = FastAPI()

 # Add middleware with basic config
 setup_keycloak_middleware(
     app,
     keycloak_configuration=keycloak_config,
 )

This allows us to make more sophisticated changes to the app, such as adding proper responses and add Swagger UI authentication.

Error Response codes

Error response codes are now enabled by default. See below for details.

New Feature

Swagger UI Authentication

It is now possible to properly configure the Swagger UI to authenticate against Keycloak and send requests with the correct token to the backend. Therefore it is now possible to actually test the API using Swagger UI. It requires the new setup method mentioned above and needs to be explicitly enabled.

** Example **:

 keycloak_config = KeycloakConfiguration(
     url="https://sso.your-keycloak.com/auth/",
     realm="<Realm Name>",
     client_id="<Client ID>",
     client_secret="<Client Secret>",
     swagger_client_id="<Swagger Client ID>",
     swagger_auth_scopes=["openid", "profile"], # Optional
     swagger_auth_pkce=True, # Optional
     swagger_scheme_name="keycloak" # Optional
 )

setup_keycloak_middleware(
    app,
    keycloak_configuration=keycloak_config,
    add_swagger_auth=True
)

Please refer to the documentation for additional details.

Error Response codes

The library now has the ability to automatically add 401 and 403 error responses to the OpenAPI spec. This is mainly useful when working with client generators that automatically create client SDKs based on the OpenAPI spec. This feature is enabled by default, but doesn't overwrite any existing responses you may have added to your application.

The default behaviour can be disabled by setting the add_exception_response to False when calling setup_keycloak_middleware:

setup_keycloak_middleware(
    app,
    keycloak_configuration=keycloak_config,
    add_exception_response=False
)

Full Changelog

  • fix: properly use Pydantic field defaults by @waza-ari in #36
  • Switch from PlainTextResponse to JSONResponse by @waza-ari in #37
  • fix: middleware typing was incorrectly accepting a FastAPI app, while… by @waza-ari in #38
  • Add initialisation helper by @waza-ari in #39

Full Changelog: v0.3.1...v0.4.0

Version 0.3.1

03 Mar 18:06
729cef8
Compare
Choose a tag to compare

Breaking Changes

No breaking changes are introduced.

Full Changelog

fix: pin python-keycloak to <v3.9.1 for now

This release is needed due to a change in python-keycloak. See #30 for details.

Version 0.3.0

25 Aug 19:34
Compare
Choose a tag to compare

Breaking Changes

No breaking changes are introduced.

Full Changelog

feat(jwt): Make JWT decode options configurable #14

It is now possible to configure the options passed to python-jose which is used to decode the JWT.

chore(dependencies): #15 update python-keycloak dependency

The decency on python-keycloak was unnecessarily strict. It has been relaxed to allow any version above v2.14.0 (which the library has been written and tested with) and <v4 as there is no breaking change in v3 that affects this library.

Merge pull request #12 from hokiegeek2/11_update_keycloak_configuration

The SSL verification behaviour regarding the Keyclaok SSL certificate is now configurable. Possible values are True, which validates the server certificate using the system certificate store, a string containing a path for a CA bundle file, in which case this CA bundle file is used to validate the certificate or False which disables certificate validation altogether. Thanks @hokiegeek2 for the contribution!

Version 0.2.2

08 Apr 15:49
Compare
Choose a tag to compare

Breaking Changes

No breaking changes are introduced.

Full Changelog