Browse Source

Merge pull request #7678 from ZaibanAli/feature/keycloak-terminate-sso-session

feat: implement OAuth logout functionality for keyclock to terminate sso session
Timothy Jaeryang Baek 4 tháng trước cách đây
mục cha
commit
8718067894

+ 30 - 2
backend/open_webui/apps/webui/routers/auths.py

@@ -3,6 +3,7 @@ import uuid
 import time
 import datetime
 import logging
+from aiohttp import ClientSession
 
 from open_webui.apps.webui.models.auths import (
     AddUserForm,
@@ -29,7 +30,11 @@ from open_webui.env import (
     SRC_LOG_LEVELS,
 )
 from fastapi import APIRouter, Depends, HTTPException, Request, status
-from fastapi.responses import Response
+from fastapi.responses import RedirectResponse, Response
+from open_webui.config import (
+    OPENID_PROVIDER_URL,
+    ENABLE_OAUTH_SIGNUP,
+)
 from pydantic import BaseModel
 from open_webui.utils.misc import parse_duration, validate_email_format
 from open_webui.utils.auth import (
@@ -498,8 +503,31 @@ async def signup(request: Request, response: Response, form_data: SignupForm):
 
 
 @router.get("/signout")
-async def signout(response: Response):
+async def signout(request: Request, response: Response):
     response.delete_cookie("token")
+
+    if ENABLE_OAUTH_SIGNUP.value:
+        oauth_id_token = request.cookies.get("oauth_id_token")
+        if oauth_id_token:
+            try:
+                async with ClientSession() as session:
+                    async with session.get(OPENID_PROVIDER_URL.value) as resp:
+                        if resp.status == 200:
+                            openid_data = await resp.json()
+                            logout_url = openid_data.get("end_session_endpoint")
+                            if logout_url:
+                                response.delete_cookie("oauth_id_token")
+                                return RedirectResponse(
+                                    url=f"{logout_url}?id_token_hint={oauth_id_token}"
+                                )
+                        else:
+                            raise HTTPException(
+                                status_code=resp.status,
+                                detail="Failed to fetch OpenID configuration",
+                            )
+            except Exception as e:
+                raise HTTPException(status_code=500, detail=str(e))
+
     return {"status": True}
 
 

+ 10 - 1
backend/open_webui/utils/oauth.py

@@ -253,9 +253,18 @@ class OAuthManager:
             secure=WEBUI_SESSION_COOKIE_SECURE,
         )
 
+        if ENABLE_OAUTH_SIGNUP.value:
+            oauth_id_token = token.get("id_token")
+            response.set_cookie(
+                key="oauth_id_token",
+                value=oauth_id_token,
+                httponly=True,
+                samesite=WEBUI_SESSION_COOKIE_SAME_SITE,
+                secure=WEBUI_SESSION_COOKIE_SECURE,
+            )
         # Redirect back to the frontend with the JWT token
         redirect_url = f"{request.base_url}auth#token={jwt_token}"
-        return RedirectResponse(url=redirect_url)
+        return RedirectResponse(url=redirect_url, headers=response.headers)
 
 
 oauth_manager = OAuthManager()