Skip to content

Commit 78e522a

Browse files
preciousnijel
authored andcommitted
fix: restore previous behaviour for handling RelayState in SAML (#1469)
1 parent 96535a1 commit 78e522a

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-14
lines changed

social_core/backends/saml.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,22 @@ def get_user_id(self, details, response) -> str:
398398
uid = idp.get_user_permanent_id(response["attributes"])
399399
return f"{idp.name}:{uid}"
400400

401+
def parse_relay_state(self, relay_state_str: str) -> dict:
402+
"""Parse RelayState JSON or simple string into a dict"""
403+
try:
404+
relay_state: dict = json.loads(relay_state_str)
405+
except json.JSONDecodeError:
406+
# this is for backward compatibility; also some identity providers
407+
# (like Okta) send a simple string with the IdP name in RelayState
408+
# during IdP-initiated SSO:
409+
relay_state = {"idp": relay_state_str}
410+
411+
# Validate that the data is dict
412+
if not isinstance(relay_state, dict):
413+
raise AuthInvalidParameter(self, "RelayState")
414+
415+
return relay_state
416+
401417
def auth_complete(self, *args, **kwargs):
402418
"""
403419
The user has been redirected back from the IdP and we should
@@ -409,15 +425,7 @@ def auth_complete(self, *args, **kwargs):
409425
except KeyError:
410426
idp_name = None
411427
else:
412-
# Parse RelayState JSON
413-
try:
414-
relay_state: dict = json.loads(relay_state_str)
415-
except json.JSONDecodeError as error:
416-
raise AuthInvalidParameter(self, "RelayState") from error
417-
418-
# Validate that the data is dict
419-
if not isinstance(relay_state, dict):
420-
raise AuthInvalidParameter(self, "RelayState")
428+
relay_state = self.parse_relay_state(relay_state_str)
421429

422430
# Get IdP name
423431
idp_name = relay_state.get("idp")

social_core/tests/backends/test_saml.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
except ImportError:
1717
SAML_MODULE_ENABLED = False
1818

19-
from social_core.exceptions import AuthInvalidParameter, AuthMissingParameter
19+
from social_core.exceptions import AuthMissingParameter
2020

2121
from .base import BaseBackendTest
2222

@@ -118,14 +118,13 @@ def test_login_with_legacy_relay_state(self) -> None:
118118
"""
119119
Test that we handle legacy RelayState (i.e. just the IDP name, not a JSON object).
120120
121-
This is the form that RelayState had in prior versions of this library.
122-
It is no longer supported and fails with invalid parameter.
121+
This is the form that RelayState had in prior versions of this library. It should be supported for backwards
122+
compatibility. It is also sent by some identity providers (like Okta) on IdP-initiated login.
123123
"""
124124
self.response_fixture = "saml_response_legacy.txt"
125125

126126
self.strategy.set_request_data({"idp": "testshib"}, self.backend)
127-
with self.assertRaises(AuthInvalidParameter):
128-
self.do_login()
127+
self.do_login()
129128

130129
def test_login_no_idp_in_initial_request(self) -> None:
131130
"""

0 commit comments

Comments
 (0)