@@ -907,7 +907,8 @@ def oidc_login():
907907 # Register the OIDC client
908908 client_kwargs = {
909909 'scope' : 'openid profile email' ,
910- 'token_endpoint_auth_method' : 'client_secret_post' # Send credentials in POST body instead of header
910+ 'token_endpoint_auth_method' : 'client_secret_post' , # Send credentials in POST body instead of header
911+ 'token_introspection_endpoint' : None # Disable token introspection
911912 }
912913
913914 # Check if using discovery or manual endpoints
@@ -996,7 +997,8 @@ def oidc_callback():
996997 # Register the OIDC client (same as in login)
997998 client_kwargs = {
998999 'scope' : 'openid profile email' ,
999- 'token_endpoint_auth_method' : 'client_secret_post' # Send credentials in POST body instead of header
1000+ 'token_endpoint_auth_method' : 'client_secret_post' , # Send credentials in POST body instead of header
1001+ 'token_introspection_endpoint' : None # Disable token introspection
10001002 }
10011003
10021004 if not use_manual and oidc_config .discovery_endpoint and oidc_config .discovery_endpoint .strip ():
@@ -1038,37 +1040,53 @@ def oidc_callback():
10381040 # Get the token
10391041 token = oidc_client .authorize_access_token ()
10401042
1041- # Parse the ID token to get user info
1043+ # Parse the ID token to get user info - skip JWT validation for manual endpoints
10421044 user_info = token .get ('userinfo' )
10431045 if not user_info :
1044- # Try to get userinfo from the token
1045- try :
1046- user_info = oidc_client .parse_id_token (token )
1047- except Exception as parse_error :
1048- current_app .logger .error (f"Failed to parse ID token: { parse_error } " )
1049- # Try fetching userinfo from endpoint if available
1050- if oidc_config .userinfo_endpoint :
1051- try :
1052- import requests
1053- access_token = token .get ('access_token' )
1054- if access_token :
1055- response = requests .get (
1056- oidc_config .userinfo_endpoint ,
1057- headers = {'Authorization' : f'Bearer { access_token } ' },
1058- timeout = 10
1059- )
1060- if response .status_code == 200 :
1061- user_info = response .json ()
1062- else :
1063- current_app .logger .error (f"UserInfo endpoint returned { response .status_code } : { response .text } " )
1064- except Exception as userinfo_error :
1065- current_app .logger .error (f"Failed to fetch userinfo: { userinfo_error } " )
1066-
1067- if not user_info :
1068- flash ('Failed to retrieve user information from identity provider.' , 'error' )
1069- return redirect (url_for ('main.login' ))
1070-
1071- # Get mapping configuration from session
1046+ # Try to parse ID token without validation if it exists
1047+ id_token = token .get ('id_token' )
1048+ if id_token and isinstance (id_token , str ):
1049+ # Decode JWT without verification (we trust the token came from our OAuth exchange)
1050+ try :
1051+ import json
1052+ import base64
1053+ # JWT format: header.payload.signature
1054+ parts = id_token .split ('.' )
1055+ if len (parts ) >= 2 :
1056+ # Decode the payload (add padding if needed)
1057+ payload = parts [1 ]
1058+ padding = 4 - len (payload ) % 4
1059+ if padding != 4 :
1060+ payload += '=' * padding
1061+ user_info = json .loads (base64 .urlsafe_b64decode (payload ))
1062+ current_app .logger .info ("Extracted user info from ID token payload" )
1063+ except Exception as decode_error :
1064+ current_app .logger .warning (f"Failed to decode ID token: { decode_error } " )
1065+
1066+ # If still no user_info, try fetching from userinfo endpoint
1067+ if not user_info :
1068+ # If still no user_info, try fetching from userinfo endpoint
1069+ if not user_info :
1070+ try :
1071+ import requests
1072+ access_token = token .get ('access_token' )
1073+ if access_token and oidc_config .userinfo_endpoint :
1074+ response = requests .get (
1075+ oidc_config .userinfo_endpoint ,
1076+ headers = {'Authorization' : f'Bearer { access_token } ' },
1077+ timeout = 10
1078+ )
1079+ if response .status_code == 200 :
1080+ user_info = response .json ()
1081+ current_app .logger .info ("Fetched user info from userinfo endpoint" )
1082+ else :
1083+ current_app .logger .error (f"UserInfo endpoint returned { response .status_code } : { response .text } " )
1084+ except Exception as userinfo_error :
1085+ current_app .logger .error (f"Failed to fetch userinfo: { userinfo_error } " )
1086+
1087+ if not user_info :
1088+ flash ('Failed to retrieve user information from identity provider.' , 'error' )
1089+ return redirect (url_for ('main.login' )) # Get mapping configuration from session
10721090 mapping_field = session .get ('oidc_mapping_field' , 'email' )
10731091 custom_attribute = session .get ('oidc_custom_attribute' )
10741092
0 commit comments