diff --git a/run_app.sh b/run_app.sh index b4d203d..456500b 100755 --- a/run_app.sh +++ b/run_app.sh @@ -29,4 +29,4 @@ if [[ -z "$HYDRA_CLIENT_SECRET" ]]; then exit 1 fi -KUBECTL_UID=${UID:-1001} KUBECTL_GID=${GID:-0} docker compose up +KUBECTL_UID=${UID:-1001} KUBECTL_GID=${GID:-0} docker-compose up diff --git a/web/login/login.py b/web/login/login.py index 591acc2..3a41367 100644 --- a/web/login/login.py +++ b/web/login/login.py @@ -385,21 +385,20 @@ def get_kratos_cookie(): return cookie -@web.route("/logout", methods=["GET"]) -def logout(): - """Handles the Hydra OpenID Connect Logout flow as well as the Kratos - logout flow + +@web.route("/prelogout", methods=["GET"]) +def prelogout(): + """Handles the Hydra OpenID Connect Logout flow Steps: - 1. Hydra's /oauth2/sessions/logout endpoint is called by an application 2. Hydra calls this endpoint with a `logout_challenge` get parameter 3. We retrieve the logout request using the challenge - 4. We retrieve the Kratos cookie from the browser - 5. We generate a Kratos logout URL - 6. We accept the Hydra logout request - 7. We redirect to the Kratos logout URL + 4. We accept the Hydra logout request + 5. We redirect to Hydro to clean-up cookies. + 6. Hyrda calls back to us with a post logout handle (/logout) + Args: logout_challenge (string): Reference to a Hydra logout challenge object @@ -421,9 +420,39 @@ def logout(): challenge) abort(503) + current_app.logger.info("Logout request hydra, subject %s", logout_request.subject) + + # Accept logout request and direct to hydra to remove cookies + try: + hydra_return = logout_request.accept(subject=logout_request.subject) + if hydra_return: + return redirect(hydra_return) + + except Exception as ex: + current_app.logger.info("Error logging out hydra: %s", str(ex)) + + + current_app.logger.info("Hydra logout not completed. Redirecting to kratos logout, maybe user removed cookies manually") + return redirect("logout") + + +@web.route("/logout", methods=["GET"]) +def logout(): + """Handles the Kratos Logout flow + + Steps: + 1. We got here from hyrda + 2. We retrieve the Kratos cookie from the browser + 3. We generate a Kratos logout URL + 4. We redirect to the Kratos logout URIL + """ + kratos_cookie = get_kratos_cookie() if not kratos_cookie: - abort(404, "Kratos session invalid or not found") + # No kratos cookie, already logged out + current_app.logger.info("Expected kratos cookie but not found. Redirecting to login"); + return redirect("login") + try: # Create a Logout URL for Browsers kratos_api_response = \ @@ -434,6 +463,5 @@ def logout(): current_app.logger.error("Exception when calling" " V0alpha2Api->create_self_service_logout_flow_url_for_browsers: %s\n", ex) - hydra_return = logout_request.accept(subject=logout_request.subject) - current_app.logger.info("Hydra info: %s", hydra_return) return redirect(kratos_api_response.logout_url) +