Skip to content

Commit 5e817e7

Browse files
committed
Fix issue with LogoutRequest rejected by ADFS due NameID with unspecified format instead no format attribute
1 parent b396833 commit 5e817e7

4 files changed

Lines changed: 71 additions & 2 deletions

File tree

src/onelogin/saml2/logout_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def __init__(self, settings, request=None, name_id=None, session_index=None, nq=
7272
cert = idp_data['x509cert']
7373

7474
if name_id is not None:
75-
if not name_id_format:
75+
if not name_id_format and sp_data['NameIDFormat'] != OneLogin_Saml2_Constants.NAMEID_UNSPECIFIED:
7676
name_id_format = sp_data['NameIDFormat']
7777
else:
7878
name_id_format = OneLogin_Saml2_Constants.NAMEID_ENTITY

src/onelogin/saml2/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ def format_finger_print(fingerprint):
557557
return formatted_fingerprint.lower()
558558

559559
@staticmethod
560-
def generate_name_id(value, sp_nq, sp_format, cert=None, debug=False, nq=None):
560+
def generate_name_id(value, sp_nq, sp_format=None, cert=None, debug=False, nq=None):
561561
"""
562562
Generates a nameID.
563563

tests/src/OneLogin/saml2_tests/logout_request_test.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,64 @@ def testCreateDeflatedSAMLLogoutRequestURLParameter(self):
8989
inflated = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(payload))
9090
self.assertRegex(inflated, '^<samlp:LogoutRequest')
9191

92+
def testConstructorWithNameIdFormatOnSettings(self):
93+
"""
94+
Tests the OneLogin_Saml2_LogoutRequest Constructor.
95+
Case: Defines NameIDFormat from settings
96+
"""
97+
settings_info = self.loadSettingsJSON()
98+
name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
99+
name_id_format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
100+
settings_info['sp']['NameIDFormat'] = name_id_format
101+
settings = OneLogin_Saml2_Settings(settings_info)
102+
logout_request = OneLogin_Saml2_Logout_Request(settings, name_id=name_id)
103+
logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(logout_request.get_request())
104+
name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request_xml)
105+
expected_name_id_data = {
106+
'Value': name_id,
107+
'Format': name_id_format
108+
}
109+
self.assertEqual(expected_name_id_data, name_id_data)
110+
111+
def testConstructorWithoutNameIdFormat(self):
112+
"""
113+
Tests the OneLogin_Saml2_LogoutRequest Constructor.
114+
Case: Checks that NameIDFormat is not added
115+
"""
116+
settings_info = self.loadSettingsJSON()
117+
name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
118+
name_id_format = 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
119+
settings_info['sp']['NameIDFormat'] = name_id_format
120+
settings = OneLogin_Saml2_Settings(settings_info)
121+
logout_request = OneLogin_Saml2_Logout_Request(settings, name_id=name_id)
122+
logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(logout_request.get_request())
123+
name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request_xml)
124+
expected_name_id_data = {
125+
'Value': name_id
126+
}
127+
self.assertEqual(expected_name_id_data, name_id_data)
128+
129+
def testConstructorEncryptIdUsingX509certMulti(self):
130+
"""
131+
Tests the OneLogin_Saml2_LogoutRequest Constructor.
132+
Case: Able to generate encryptedID with MultiCert
133+
"""
134+
settings_info = self.loadSettingsJSON('settings8.json')
135+
settings_info['security']['nameIdEncrypted'] = True
136+
settings = OneLogin_Saml2_Settings(settings_info)
137+
138+
logout_request = OneLogin_Saml2_Logout_Request(settings)
139+
140+
parameters = {'SAMLRequest': logout_request.get_request()}
141+
logout_url = OneLogin_Saml2_Utils.redirect('http://idp.example.com/SingleLogoutService.php', parameters, True)
142+
self.assertRegexpMatches(logout_url, '^http://idp\.example\.com\/SingleLogoutService\.php\?SAMLRequest=')
143+
url_parts = urlparse(logout_url)
144+
exploded = parse_qs(url_parts.query)
145+
payload = exploded['SAMLRequest'][0]
146+
inflated = OneLogin_Saml2_Utils.decode_base64_and_inflate(payload)
147+
self.assertRegexpMatches(inflated, '^<samlp:LogoutRequest')
148+
self.assertRegexpMatches(inflated, '<saml:EncryptedID>')
149+
92150
def testGetIDFromSAMLLogoutRequest(self):
93151
"""
94152
Tests the get_id method of the OneLogin_Saml2_LogoutRequest

tests/src/OneLogin/saml2_tests/utils_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,17 @@ def testNameidGenerationDoesNotIncludeNameQualifierAttribute(self):
511511

512512
self.assertNotIn(not_expected_attribute, name_id.attrib.keys())
513513

514+
def testGenerateNameIdWithoutFormat(self):
515+
"""
516+
Tests the generateNameId method of the OneLogin_Saml2_Utils
517+
"""
518+
name_id_value = 'ONELOGIN_ce998811003f4e60f8b07a311dc641621379cfde'
519+
name_id_format = None
520+
521+
name_id = OneLogin_Saml2_Utils.generate_name_id(name_id_value, None, name_id_format)
522+
expected_name_id = '<saml:NameID>ONELOGIN_ce998811003f4e60f8b07a311dc641621379cfde</saml:NameID>'
523+
self.assertEqual(name_id, expected_name_id)
524+
514525
def testGenerateNameIdWithSPNameQualifier(self):
515526
"""
516527
Tests the generateNameId method of the OneLogin_Saml2_Utils

0 commit comments

Comments
 (0)