Python authlib: Umgang mit mehreren WebservernPython

Python-Programme
Anonymous
 Python authlib: Umgang mit mehreren Webservern

Post by Anonymous »

Ich entwickle einen auf FastAPI basierenden Webserver, der in einen Container integriert werden soll, der auf Kubernetes mit Replikaten bereitgestellt werden soll. Die Authentifizierung wird durch authlib und Keycloak durchgeführt.
Der Server, der den Benutzer (über /login) zum Identitätsanbieter umleitet, ist möglicherweise nicht derselbe, der die /auth-Route ausführt.
Ich kann möglicherweise die Umleitungs-URL mithilfe der IP-Adresse des Servers erstellen, der die /login-Anfrage ausführt, aber das klingt für mich nicht richtig, insbesondere für die von Keycloak zugelassenen Umleitungs-URLs, die wären statische IPs.
Hier ist ein Codeausschnitt, den ich geschrieben habe:

Code: Select all

oauth = OAuth()
oauth.register(
name="keycloak",
client_id=settings.keycloak.client_id,
client_secret=settings.keycloak.client_secret.get_secret_value(),
server_metadata_url=settings.keycloak.server_metadata_url,
# The group scope does not exist by default. This must be added.
client_kwargs={"scope": "openid email profile group"},
# The state is a value which is used as a kind of CSRF check.
# When the /login redirects to keycloak, it includes this value.
# Later, when keycloak redirects to /auth, it also includes the state value.
# If the values mismatche, a CSRF error is raised.
# Configuring it is required to perform replication.
state="toto",
)
oauth_client: StarletteOAuth2App = oauth.keycloak

def get_user_name(userinfo: dict):
"""Get the user name from user information dict."""
return userinfo.get("name", None) or userinfo.get("preferred_username")

@router.get("/login", tags=["user"])
async def login(request: Request):
"""Redirect the user to keycloak login page."""
redirect_uri = request.url_for("auth")
return await oauth_client.authorize_redirect(request, redirect_uri, state="toto")

@router.get("/auth", tags=["user"])
async def auth(request: Request):
"""Authenticate the user by creating a session cookie."""
token = await oauth_client.authorize_access_token(request)
userinfo = token["userinfo"]

# Needs json.dumps otherwise this is not correctly saved in session
request.session["user"] = json.dumps(userinfo)

_LOGGER.info("User %s got connected", get_user_name(userinfo))

# Get the URL the user requested before login, if any.
target_url = request.session.pop("target-url", "/")
return RedirectResponse(target_url)

Ich habe einen kleinen Kommentar geschrieben, um zu erklären, was ich über den Status-Wert verstanden habe.
Die Schlüsselfrage könnte der Wert des Status-Parameters sein, der auf allen Servern gleich sein sollte. Allerdings ist in der Dokumentation nicht klar, wie man es benutzt. Außerdem weist diese Antwort darauf hin, dass der Wert zufällig sein sollte, um Angriffe zu verhindern. Also, wie könnte ich das tun?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post