https://github.com/dyakovri/fastapi-auth-oidc
Check credentials with ease using OpenID Connect
https://github.com/dyakovri/fastapi-auth-oidc
authentication fastapi jwt openid-connect
Last synced: 3 months ago
JSON representation
Check credentials with ease using OpenID Connect
- Host: GitHub
- URL: https://github.com/dyakovri/fastapi-auth-oidc
- Owner: dyakovri
- License: bsd-3-clause
- Created: 2025-04-27T20:30:46.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-08-02T20:35:41.000Z (11 months ago)
- Last Synced: 2025-08-02T22:18:34.485Z (11 months ago)
- Topics: authentication, fastapi, jwt, openid-connect
- Language: Python
- Homepage: https://pypi.org/p/fastapi-auth-oidc/
- Size: 56.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# FastAPI OIDC Security
This library allows your server-side application to check credentials with ease using OpenID Connect
token flows. Use it with Firebase, Keycloak, Authentik or other OIDC providers.
## Simple usage
You can just add `auth_user` dependency to take token data into your FastAPI routes.
```python
from fastapi import FastAPI
from fastapi_auth_oidc import OIDCProvider, IDToken
from fastapi_auth_oidc.exceptions import AuthenticationException
app = FastAPI()
auth_user = OIDCProvider(
configuration_uri="https://example.domain/issuer/.well-known/openid-configuration",
client_id="my-client",
)
@app.exception_handler(AuthenticationException)
def invalid_credentials(request: Request, exc: InvalidCredentialsException):
return JSONResponse(
status_code=403,
content={"detail": "Invalid token"},
)
@app.get("/me")
def get_me(
user: Annotated[IDToken | None, Depends(auth_user)],
):
return user.model_dump() if user else {}
```
## Advanced authorization
For authorization with this package you shoud create security guards. Example below provides
`NamedTuple` with 2 authorization methods: authenticated and is_admin. They uses FastAPI dependency
injection to ensure user and validate token. Now you shoud alse use them as dependencies.
```python
from typing import Annotated, NamedTuple
from fastapi import Depends
from fastapi_auth_oidc import IDToken, OIDCProvider
from fastapi_auth_oidc import IDToken, OIDCProvider
from fastapi_auth_oidc.exceptions import UnauthenticatedException
# Taking a new property mapping from JWT
class MyIDToken(IDToken):
my_app_permissions: str | None = None
# Setting up provider
auth_user = OIDCProvider(
configuration_uri=str(settings.oidc_configuration_uri),
client_id=settings.oidc_client_id,
token_type=MyIDToken,
)
TokenData = Annotated[MyIDToken | None, Depends(auth_user)]
# Check if user token set and valid
def get_authenticated(user: TokenData):
if not user:
raise UnauthenticatedException()
return user
# Check if user has `my_app_permissions` field in JWT token and it equals to `admin`.
def get_is_admin(user: Annotated[MyIDToken, Depends(get_authenticated)]):
if not user.my_app_permissions == "admin":
raise Exception()
return user
# This utilities in pretty form
class User(NamedTuple):
authenticated = Annotated[IDToken, Depends(get_authenticated)]
is_admin = Annotated[IDToken, Depends(get_is_admin)]
# Usage
app = FastAPI()
@app.get("/everybody")
def get_me(user: TokenData):
"""Everybody can open `"/everybody` =)"""
return user.model_dump() if user else {}
@app.get("/authenticated")
def get_me(user: User.authenticated):
"""Only users with valid JWT token will get their data"""
return user.model_dump()
@app.get("/admin")
def get_me(user: User.is_admin):
"""Only users with `my_app_permissions == "admin"` can get their data"""
return user.model_dump()
```