This commit is contained in:
phil 2025-01-20 01:16:17 +01:00
parent 5f2901d558
commit 572d2a7b0d
5 changed files with 18 additions and 10 deletions

2
TODO
View file

@ -1,3 +1,5 @@
https://docs.authlib.org/en/latest/oauth/2/intro.html#intro-oauth2 https://docs.authlib.org/en/latest/oauth/2/intro.html#intro-oauth2
https://www.keycloak.org/docs/latest/authorization_services/index.html https://www.keycloak.org/docs/latest/authorization_services/index.html
https://thinhdanggroup.github.io/oauth2-python/

View file

@ -1,6 +1,5 @@
from typing import Union from typing import Union
from functools import wraps from functools import wraps
from datetime import datetime
import logging import logging
from fastapi import HTTPException, Request, status from fastapi import HTTPException, Request, status
@ -54,7 +53,7 @@ async def get_current_user(request: Request) -> User:
logger.info(f"Token expired for user {user.name}") logger.info(f"Token expired for user {user.name}")
try: try:
userinfo = await oidc_provider.fetch_access_token( userinfo = await oidc_provider.fetch_access_token(
refresh_token=token.refresh_token refresh_token=token.get("refresh_token")
) )
except OAuthError as err: except OAuthError as err:
logger.exception(err) logger.exception(err)

View file

@ -66,7 +66,7 @@ for provider in settings.oidc.providers:
name=provider.id, name=provider.id,
server_metadata_url=provider.openid_configuration, server_metadata_url=provider.openid_configuration,
client_kwargs={ client_kwargs={
"scope": "openid email", # offline_access profile", "scope": "openid email offline_access profile",
}, },
client_id=provider.client_id, client_id=provider.client_id,
client_secret=provider.client_secret, client_secret=provider.client_secret,
@ -170,7 +170,7 @@ async def auth(request: Request, oidc_provider_id: str) -> RedirectResponse:
except OAuthError as error: except OAuthError as error:
raise HTTPException(status.HTTP_401_UNAUTHORIZED, detail=error.error) raise HTTPException(status.HTTP_401_UNAUTHORIZED, detail=error.error)
# Remember the oidc_provider in the session # Remember the oidc_provider in the session
# logger.debug(f"Scope: {token['scope']}") # logger.info(f"Scope: {token['scope']}")
request.session["oidc_provider_id"] = oidc_provider_id request.session["oidc_provider_id"] = oidc_provider_id
# #
# One could process the full decoded token which contains extra information # One could process the full decoded token which contains extra information
@ -351,9 +351,14 @@ async def get_introspect(
token: Annotated[OAuth2Token, Depends(get_token)], token: Annotated[OAuth2Token, Depends(get_token)],
) -> JSONResponse: ) -> JSONResponse:
assert request is not None # Just to keep QA checks happy assert request is not None # Just to keep QA checks happy
if (url := oidc_provider.server_metadata.get("introspection_endpoint")) is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="No intrispection endpoint found for the OIDC provider",
)
if ( if (
response := await oidc_provider.post( response := await oidc_provider.post(
oidc_provider.server_metadata["introspection_endpoint"], url,
token=token, token=token,
data={"token": token["access_token"]}, data={"token": token["access_token"]},
) )

View file

@ -6,11 +6,8 @@ from pydantic import (
AnyHttpUrl, AnyHttpUrl,
EmailStr, EmailStr,
ConfigDict, ConfigDict,
GetCoreSchemaHandler,
) )
from pydantic_core import CoreSchema, core_schema
from authlib.integrations.starlette_client.apps import StarletteOAuth2App from authlib.integrations.starlette_client.apps import StarletteOAuth2App
from authlib.oauth2.rfc6749 import OAuth2Token as OAuth2Token_authlib
from sqlmodel import SQLModel, Field from sqlmodel import SQLModel, Field
@ -19,10 +16,9 @@ class Role(SQLModel, extra="ignore"):
class UserBase(SQLModel, extra="ignore"): class UserBase(SQLModel, extra="ignore"):
id: str | None = None id: str | None = None
sid: str | None = None sid: str | None = None
name: str name: str | None = None
email: EmailStr | None = None email: EmailStr | None = None
picture: AnyHttpUrl | None = None picture: AnyHttpUrl | None = None
roles: list[Role] = [] roles: list[Role] = []

View file

@ -45,6 +45,12 @@ class OIDCProvider(BaseModel):
return "auth/" + self.id return "auth/" + self.id
class ResourceProvider(BaseModel):
id: str
name: str
resources: list[Resource] = []
class OIDCSettings(BaseModel): class OIDCSettings(BaseModel):
show_session_details: bool = False show_session_details: bool = False
providers: list[OIDCProvider] = [] providers: list[OIDCProvider] = []