FastAPI API#
FastAPI integration for py oidc auth.
The FastApiOIDCAuth class provides:
Dependencies for protected and optional routes
An
fastapi.APIRouterwith standard authentication endpoints
Install:
pip install py-oidc-auth[fastapi]
conda install -c conda-forge py-oidc-fastapi
Basic usage
from fastapi import FastAPI
from py_oidc_auth.fastapi_auth import FastApiOIDCAuth
app = FastAPI()
auth = FastApiOIDCAuth(
client_id="my client",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
client_secret="secret",
scopes="myscope profile email",
broker_mode=True,
broker_store_url="postgresql+asyncpg://user:pw@db/myapp",
)
app.include_router(auth.create_auth_router(prefix="/api"))
@app.get("/me")
async def me(token = auth.required()):
return {"sub": token.sub}
- class py_oidc_auth.fastapi_auth.FastApiOIDCAuth(client_id: str = '', discovery_url: str = '', client_secret: str | None = None, scopes: str = 'profile email', audience: str | None = None, appname: str = 'py-oidc-auth', proxy: str = '', claims: Dict[str, Any] | None = None, offline_access: bool = True, timeout_sec: int = 10, jwks_uri: str | None = None, issuer: str | None = None, broker_mode: bool = False, broker_store_url: str | None = None, broker_store_obj: BrokerStore | None = None, broker_audience: str = 'py-oidc-auth', trusted_issuers: list[str] | None = None, broker_jwks_path: str = '/auth/v2/.well-known/jwks.json')#
Reusable OpenID Connect helper for FastAPI.
The class extends
OIDCAuthand adds a FastAPI friendly surface. All broker logic is inherited from the base class and is therefore available to every framework adapter.You typically:
Create an instance once at startup
Include
create_auth_router()in your appUse
required()andoptional()as dependencies on routes
- required(claims: Dict[str, Any] | None = None, scopes: str = '') Any#
Return a dependency that enforces authentication.
The dependency validates the bearer token from the
Authorizationheader. In broker mode verifies broker JWTs. In passthrough mode verifies IDP tokens via the discovery JWKS. If validation fails, a FastAPIfastapi.HTTPExceptionis raised.- Parameters:
claims – Optional claim constraints.
scopes – Space separated scope names that the token must contain.
- Returns:
A ready to use
fastapi.Security()dependency.
Example
@app.get("/admin") async def admin(token: IDToken = auth.required(scopes="admin")): return {"sub": token.sub}
- optional(claims: Dict[str, Any] | None = None, scopes: str = '') Any#
Return a dependency that accepts anonymous requests.
When no bearer token is present, or when token validation fails, the dependency returns
None.- Parameters:
claims – Optional claim constraints.
scopes – Space separated scope names.
- Returns:
A ready to use
fastapi.Security()dependency.
Example
@app.get("/feed") async def feed(token: Optional[IDToken] = auth.optional()): if token: return {"hello": token.preferred_username} return {"hello": "guest"}
- create_auth_router(prefix: str = '', login: str | None = '/auth/v2/login', callback: str | None = '/auth/v2/callback', token: str | None = '/auth/v2/token', device_flow: str | None = '/auth/v2/device', logout: str | None = '/auth/v2/logout', userinfo: str | None = '/auth/v2/userinfo', jwks: str | None = '/auth/v2/.well-known/jwks.json', tags: List[str | Enum] | None = None) fastapi.APIRouter#
Build an
fastapi.APIRouterwith standard auth endpoints.Each route can be disabled by passing
None(or""fortoken) for the corresponding path.Broker mode rules
broker_mode=True+token=None→ValueErrorat call time. Clients need the token endpoint to receive broker JWTs.tokenset +broker_mode=False→ logged as a warning. Clients will receive raw IDP tokens without audience restriction.broker_mode=Trueautomatically adds:A broker token endpoint that accepts RFC 8693 token exchange (
grant_type=urn:ietf:params:oauth:grant-type:token-exchange), device-code, auth-code and broker refresh flows.A
GET jwksendpoint exposing the broker public key.
The
userinfoendpoint is suppressed in broker mode because the broker JWT is self-contained (preferred_username,email,rolesare baked in at mint time).
- Parameters:
prefix – URL prefix for all routes.
login – Login route path.
callback – Callback route path.
token – Token route path.
device_flow – Device flow start route path.
logout – Logout route path.
userinfo – Userinfo route path.
tags – OpenAPI tags for all routes.
- Returns:
A router that can be included via
app.include_router.
Request examples#
Login
GET /auth/v2/login?redirect_uri=https%3A%2F%2Fapp.example.org%2Fcallback HTTP/1.1 Host: app.example.org
Callback
GET /auth/v2/callback?code=abc&state=xyz HTTP/1.1 Host: app.example.org
Token exchange
POST /auth/v2/token HTTP/1.1 Host: app.example.org Content-Type: application/x-www-form-urlencoded code=abc&redirect_uri=https%3A%2F%2Fapp.example.org%2Fcallback
Userinfo
GET /auth/v2/userinfo HTTP/1.1 Host: app.example.org Authorization: Bearer <access token>