Skip to main content

casbin-fastapi-decorator-casdoor

Casdoor OAuth2 authentication and Casbin authorization for casbin-fastapi-decorator.

Installation

pip install casbin-fastapi-decorator-casdoor
# or as an optional extra:
pip install "casbin-fastapi-decorator[casdoor]"

Quick start — facade

from fastapi import FastAPI
from casbin_fastapi_decorator_casdoor import CasdoorEnforceTarget, CasdoorIntegration

casdoor = CasdoorIntegration(
    endpoint="http://localhost:8000",
    client_id="...",
    client_secret="...",
    certificate=cert,        # PEM string from Casdoor → Application → Cert
    org_name="my_org",
    application_name="my_app",
    target=CasdoorEnforceTarget(
        # enforce_id is resolved per-request from the user's JWT
        enforce_id=lambda parsed: f"{parsed['owner']}/my_enforcer",
    ),
)

app = FastAPI()
app.include_router(casdoor.router)   # GET /login, GET /callback, POST /logout
guard = casdoor.create_guard()

@app.get("/protected")
@guard.require_permission("resource", "read")
async def protected():
    return {"ok": True}

CasdoorEnforceTarget

Selects which Casdoor API identifier to use for /api/enforce. Exactly one field must be set — static string or a callable that receives the parsed JWT payload.

from casbin_fastapi_decorator_casdoor import CasdoorEnforceTarget

# By enforcer (dynamic — org taken from the user's JWT)
CasdoorEnforceTarget(
    enforce_id=lambda parsed: f"{parsed['owner']}/my_enforcer"
)

# By enforcer (static)
CasdoorEnforceTarget(enforce_id="my_org/my_enforcer")

# By permission object
CasdoorEnforceTarget(permission_id="my_org/can_edit_posts")

# By Casbin model
CasdoorEnforceTarget(model_id="my_org/rbac_model")

# By resource
CasdoorEnforceTarget(resource_id="my_org/articles_resource")

# By owner (all policies of the organisation)
CasdoorEnforceTarget(owner="my_org")

Manual composition

For advanced use cases — custom user_factory, multiple guards with different targets, or fine-grained error handling — compose the building blocks directly:

from casdoor import AsyncCasdoorSDK
from fastapi import HTTPException
from casbin_fastapi_decorator import PermissionGuard
from casbin_fastapi_decorator_casdoor import (
    CasdoorEnforceTarget,
    CasdoorEnforcerProvider,
    CasdoorUserProvider,
    make_casdoor_router,
)

sdk = AsyncCasdoorSDK(endpoint=..., client_id=..., ...)

# Custom user identity: use e-mail instead of "owner/name"
def email_factory(parsed: dict) -> str:
    return parsed["email"]

target = CasdoorEnforceTarget(enforce_id="my_org/my_enforcer")

user_provider     = CasdoorUserProvider(sdk=sdk)
enforcer_provider = CasdoorEnforcerProvider(
    sdk=sdk,
    target=target,
    user_factory=email_factory,
)
router = make_casdoor_router(sdk=sdk, redirect_after_login="/docs")

guard = PermissionGuard(
    user_provider=user_provider,
    enforcer_provider=enforcer_provider,
    error_factory=lambda user, *rv: HTTPException(403, "Forbidden"),
)

Components

CasdoorIntegration

Main facade. Accepts all Casdoor SDK parameters plus:

Parameter Default Description
target required :class:CasdoorEnforceTarget — which Casdoor API identifier to use
state_manager CookieStateManager() OAuth state issuance/verification strategy
access_token_cookie "access_token" Cookie name for the access token
refresh_token_cookie "refresh_token" Cookie name for the refresh token
redirect_after_login "/" Path or absolute URL to redirect after OAuth2 callback. Relative ("/") stays on the same host; absolute ("https://app.example.com/") redirects to another host.
cookie_secure True Set Secure flag on cookies
cookie_httponly True Set HttpOnly flag on cookies
cookie_samesite "lax" SameSite policy ("lax", "strict", "none")
cookie_domain None Domain attribute. Use ".example.com" to share cookies across subdomains (e.g. *.my-site.ru)
cookie_path "/" Path attribute of the cookie
cookie_max_age None Max-Age in seconds; None = session cookie
router_prefix "" URL prefix for /login, /callback and /logout

CasdoorUserProvider

FastAPI dependency that validates both access_token and refresh_token cookies via sdk.parse_jwt_token() and returns the raw access_token string.

Accepts optional unauthorized_error and invalid_token_error factories for custom HTTP responses.

CasdoorEnforcerProvider

FastAPI dependency that returns a shared CasdoorEnforcer.

Parameter Default Description
sdk required AsyncCasdoorSDK instance
target required :class:CasdoorEnforceTarget
user_factory "{owner}/{name}" Callable (parsed_jwt) -> str

make_casdoor_router

Factory that returns a fastapi.APIRouter with these endpoints:

  • GET {prefix}/login — issues OAuth2 state and redirects to Casdoor
  • GET {prefix}/callback — validates state, exchanges OAuth2 code for tokens, sets cookies
  • POST {prefix}/logout — calls Casdoor SSO logout (/api/sso-logout?logoutAll=true) when an access-token cookie is present, then clears authentication cookies
  • GET {prefix}/me — returns the current user's profile by parsing the JWT access token

Default state protection is provided by CookieStateManager:

  • cookie name: casdoor_oauth_state
  • HttpOnly=True, Secure=True, SameSite=lax
  • Max-Age=300

You can override state handling using CasdoorStateManager protocol implementation (e.g. Redis/session-backed storage).

Metadata

Release files for casbin-fastapi-decorator-casdoor 1.3.1

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

Source distribution (sdist)

Source distribution for casbin-fastapi-decorator-casdoor 1.3.1
File Size Uploaded
casbin_fastapi_decorator_casdoor-1.3.1.tar.gz 8.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for casbin-fastapi-decorator-casdoor 1.3.1
File Interpreter ABI Platform
casbin_fastapi_decorator_casdoor-1.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 21.4 kB

Release files / casbin_fastapi_decorator_casdoor-1.3.1.tar.gz

Download URL casbin_fastapi_decorator_casdoor-1.3.1.tar.gz
Size 8.9 kB
Tags Source
SHA-256 checksum
How to use checksums
9ad7f90ba0ac30baa440b7391531cf148dd23d7786152bc6a461468af9019978
BLAKE2b-256 checksum
How to use checksums
6cf4fd020518592d49e5157a71384b3e7eaa74294363bb26bd6f197133db78f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / casbin_fastapi_decorator_casdoor-1.3.1-py3-none-any.whl

Download URL casbin_fastapi_decorator_casdoor-1.3.1-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef1b046f5010fd2d04574a470e685957740cf19e55f6ef8c7784b0d57815677e
BLAKE2b-256 checksum
How to use checksums
74cbc37ccc378815ab684a3199c4d076906aab7b38d9c7382877c3e4f1b8038b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.3.1 This release

2 release files

1.3.0

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.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