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 CasdoorGET {prefix}/callback— validates state, exchanges OAuth2 code for tokens, sets cookiesPOST {prefix}/logout— calls Casdoor SSO logout (/api/sso-logout?logoutAll=true) when an access-token cookie is present, then clears authentication cookiesGET {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=laxMax-Age=300
You can override state handling using CasdoorStateManager protocol
implementation (e.g. Redis/session-backed storage).
Release files for casbin-fastapi-decorator-casdoor 1.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| casbin_fastapi_decorator_casdoor-1.3.0.tar.gz | 8.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| casbin_fastapi_decorator_casdoor-1.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.4 kB
Release files / casbin_fastapi_decorator_casdoor-1.3.0.tar.gz
| Download URL | casbin_fastapi_decorator_casdoor-1.3.0.tar.gz |
|---|---|
| Size | 8.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f16045d0a2fc82d28b4029c009808656be20c51871472fb2df135e7fbc0fa0b9
|
|
BLAKE2b-256 checksum How to use checksums |
850080922a9fbdff7536d1d37e2fcbd5d7bb0cd9766221eb2cb1d8cc0baf97b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","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.0-py3-none-any.whl
| Download URL | casbin_fastapi_decorator_casdoor-1.3.0-py3-none-any.whl |
|---|---|
| Size | 12.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b5227f163e8ed79dad7e4813e6f4aaf18254ad3f1fbba9349c56b909311891b
|
|
BLAKE2b-256 checksum How to use checksums |
856a4d181b0af9910ba08c0151dcc74da9d6cf509a4a977dd9920f3b61679efd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","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}
|