@@ -958,6 +958,54 @@ async def login(
958
958
)
959
959
960
960
961
+ def get_idp_logout_url_fast (provider_type : str , request : Request ) -> str :
962
+ """Generate IdP logout URL in a provider-agnostic way (optimized for speed)."""
963
+ try :
964
+ # Quick check for Cognito without heavy AuthSettings initialization
965
+ if provider_type == "cognito" :
966
+ cognito_domain = os .environ .get ("MCP_AUTH_COGNITO_DOMAIN" )
967
+ client_id = os .environ .get ("MCP_AUTH_CLIENT_ID" )
968
+
969
+ if cognito_domain and client_id :
970
+ timestamp = int (datetime .now (timezone .utc ).timestamp ())
971
+ scheme = request .url .scheme or "http"
972
+ host = request .headers .get ('host' , 'localhost:7860' )
973
+ return_uri = f"{ scheme } ://{ host } /login?t={ timestamp } &signed_out=true&complete=true"
974
+ logout_url = f"https://{ cognito_domain } /logout?client_id={ client_id } &logout_uri={ urllib .parse .quote (return_uri )} "
975
+ return logout_url
976
+
977
+ # For other providers, fall back to the original function if needed
978
+ # but for now, just return None to avoid blocking
979
+ return None
980
+
981
+ except Exception :
982
+ # Fail silently to avoid blocking logout
983
+ return None
984
+
985
+ def get_idp_logout_url_fast (provider_type : str , request : Request ) -> str :
986
+ """Generate IdP logout URL in a provider-agnostic way (optimized for speed)."""
987
+ try :
988
+ # Quick check for Cognito without heavy AuthSettings initialization
989
+ if provider_type == "cognito" :
990
+ cognito_domain = os .environ .get ("MCP_AUTH_COGNITO_DOMAIN" )
991
+ client_id = os .environ .get ("MCP_AUTH_CLIENT_ID" )
992
+
993
+ if cognito_domain and client_id :
994
+ timestamp = int (datetime .now (timezone .utc ).timestamp ())
995
+ scheme = request .url .scheme or "http"
996
+ host = request .headers .get ('host' , 'localhost:7860' )
997
+ return_uri = f"{ scheme } ://{ host } /login?t={ timestamp } &signed_out=true&complete=true"
998
+ logout_url = f"https://{ cognito_domain } /logout?client_id={ client_id } &logout_uri={ urllib .parse .quote (return_uri )} "
999
+ return logout_url
1000
+
1001
+ # For other providers, fall back to the original function if needed
1002
+ # but for now, just return None to avoid blocking
1003
+ return None
1004
+
1005
+ except Exception :
1006
+ # Fail silently to avoid blocking logout
1007
+ return None
1008
+
961
1009
def get_idp_logout_url (provider_type : str , request : Request ) -> str :
962
1010
"""Generate IdP logout URL in a provider-agnostic way."""
963
1011
logger .info (f"Generating IdP logout URL for provider: { provider_type } " )
@@ -1005,16 +1053,11 @@ async def logout_get(request: Request):
1005
1053
Log out by clearing the session cookie and invalidating the session server-side.
1006
1054
Provides IdP logout URLs when available.
1007
1055
"""
1008
- logger .info ("Logout initiated" )
1009
-
1010
1056
session_cookie_name = "mcp_gateway_session"
1011
1057
SECRET_KEY = os .environ .get ("SECRET_KEY" , "insecure-default-key-for-testing-only" )
1012
1058
1013
1059
# Extract session cookie manually (same approach as get_current_user)
1014
1060
session = request .cookies .get (session_cookie_name )
1015
- logger .info (f"Logout - session cookie present: { session is not None } " )
1016
- if session :
1017
- logger .info (f"Session cookie value: { session [:50 ]} ..." )
1018
1061
1019
1062
# Decode session and invalidate server-side
1020
1063
provider_type = None
@@ -1032,25 +1075,28 @@ async def logout_get(request: Request):
1032
1075
fingerprint = get_session_fingerprint (session_data )
1033
1076
SESSION_LOGOUT_TIMES [fingerprint ] = time .time ()
1034
1077
session_invalidated = True
1035
- cleanup_logout_times () # Clean up if needed
1036
1078
1037
- logger .info (f"Session logout - User: { username } , Provider: { provider_type } , Fingerprint: { fingerprint } " )
1079
+ # Only cleanup if we have too many entries (avoid unnecessary work)
1080
+ if len (SESSION_LOGOUT_TIMES ) > MAX_LOGOUT_ENTRIES :
1081
+ cleanup_logout_times ()
1082
+
1038
1083
except Exception as e :
1039
1084
logger .warning (f"Error decoding session during logout: { e } " )
1040
1085
1041
1086
# Create base logout response
1042
1087
timestamp = int (datetime .now (timezone .utc ).timestamp ())
1043
1088
logout_url = f"/login?t={ timestamp } &signed_out=true"
1044
1089
1045
- # Add IdP logout URL if available
1090
+ # Add IdP logout URL if available (but don't block on it)
1046
1091
if provider_type :
1047
- idp_logout_url = get_idp_logout_url (provider_type , request )
1048
- logger .info (f"Generated IdP logout URL for { provider_type } : { idp_logout_url } " )
1049
- if idp_logout_url :
1050
- logout_url += f"&idp_logout={ urllib .parse .quote (idp_logout_url )} "
1051
- logout_url += f"&provider_type={ provider_type } "
1052
-
1053
- logger .info (f"Final logout redirect URL: { logout_url } " )
1092
+ try :
1093
+ idp_logout_url = get_idp_logout_url_fast (provider_type , request )
1094
+ if idp_logout_url :
1095
+ logout_url += f"&idp_logout={ urllib .parse .quote (idp_logout_url )} "
1096
+ logout_url += f"&provider_type={ provider_type } "
1097
+ except Exception :
1098
+ # Don't let IdP logout URL generation block the logout - fail silently
1099
+ pass
1054
1100
1055
1101
response = RedirectResponse (url = logout_url , status_code = status .HTTP_303_SEE_OTHER )
1056
1102
@@ -1059,9 +1105,12 @@ async def logout_get(request: Request):
1059
1105
response .headers ['Cache-Control' ] = 'no-cache, no-store, must-revalidate'
1060
1106
response .headers ['Pragma' ] = 'no-cache'
1061
1107
response .headers ['Expires' ] = '0'
1062
- response .headers ['Clear-Site-Data' ] = '"cookies", "storage", "cache"'
1108
+ # Removed Clear-Site-Data header to improve logout performance
1109
+
1110
+ # Log completion with minimal info
1111
+ if username :
1112
+ logger .debug (f"Logout completed for user: { username } " )
1063
1113
1064
- logger .info (f"Logout completed for user: { username } , server-side invalidation: { session_invalidated } " )
1065
1114
return response
1066
1115
1067
1116
@app .post ("/logout" )
0 commit comments