Skip to content

Commit

Permalink
Fix issue with LogoutRequest rejected by ADFS due NameID with unspeci…
Browse files Browse the repository at this point in the history
…fied format instead no format attribute
  • Loading branch information
pitbulk committed Oct 19, 2017
1 parent b089e78 commit 265d019
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 19 deletions.
12 changes: 5 additions & 7 deletions src/onelogin/saml2/logout_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,13 @@ def __init__(self, settings, request=None, name_id=None, session_index=None, nq=
cert = idp_data['x509cert']

if name_id is not None:
if name_id_format is not None:
nameIdFormat = name_id_format
else:
nameIdFormat = sp_data['NameIDFormat']
if not name_id_format and sp_data['NameIDFormat'] != OneLogin_Saml2_Constants.NAMEID_UNSPECIFIED:
name_id_format = sp_data['NameIDFormat']
else:
nameIdFormat = OneLogin_Saml2_Constants.NAMEID_ENTITY
name_id_format = OneLogin_Saml2_Constants.NAMEID_ENTITY

spNameQualifier = None
if nameIdFormat == OneLogin_Saml2_Constants.NAMEID_ENTITY:
if name_id_format == OneLogin_Saml2_Constants.NAMEID_ENTITY:
name_id = idp_data['entityId']
nq = None
elif nq is not None:
Expand All @@ -94,7 +92,7 @@ def __init__(self, settings, request=None, name_id=None, session_index=None, nq=
name_id_obj = OneLogin_Saml2_Utils.generate_name_id(
name_id,
spNameQualifier,
nameIdFormat,
name_id_format,
cert,
False,
nq
Expand Down
5 changes: 3 additions & 2 deletions src/onelogin/saml2/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ def format_finger_print(fingerprint):
return formated_fingerprint.lower()

@staticmethod
def generate_name_id(value, sp_nq, sp_format, cert=None, debug=False, nq=None):
def generate_name_id(value, sp_nq, sp_format=None, cert=None, debug=False, nq=None):
"""
Generates a nameID.
Expand Down Expand Up @@ -646,7 +646,8 @@ def generate_name_id(value, sp_nq, sp_format, cert=None, debug=False, nq=None):
name_id.setAttribute('SPNameQualifier', sp_nq)
if nq is not None:
name_id.setAttribute('NameQualifier', nq)
name_id.setAttribute('Format', sp_format)
if sp_format is not None:
name_id.setAttribute('Format', sp_format)
name_id.appendChild(doc.createTextNode(value))
name_id_container.appendChild(name_id)

Expand Down
57 changes: 47 additions & 10 deletions tests/src/OneLogin/saml2_tests/logout_request_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,12 @@ def testConstructor(self):
inflated = OneLogin_Saml2_Utils.decode_base64_and_inflate(payload)
self.assertRegexpMatches(inflated, '^<samlp:LogoutRequest')

def testConstructorEncryptIdUsingX509certMulti(self):
def testCreateDeflatedSAMLLogoutRequestURLParameter(self):
"""
Tests the OneLogin_Saml2_LogoutRequest Constructor.
Case: Able to generate encryptedID with MultiCert
The creation of a deflated SAML Logout Request
"""
settings_info = self.loadSettingsJSON('settings8.json')
settings_info['security']['nameIdEncrypted'] = True
settings = OneLogin_Saml2_Settings(settings_info)

settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
logout_request = OneLogin_Saml2_Logout_Request(settings)

parameters = {'SAMLRequest': logout_request.get_request()}
Expand All @@ -74,14 +71,53 @@ def testConstructorEncryptIdUsingX509certMulti(self):
payload = exploded['SAMLRequest'][0]
inflated = OneLogin_Saml2_Utils.decode_base64_and_inflate(payload)
self.assertRegexpMatches(inflated, '^<samlp:LogoutRequest')
self.assertRegexpMatches(inflated, '<saml:EncryptedID>')

def testCreateDeflatedSAMLLogoutRequestURLParameter(self):
def testConstructorWithNameIdFormatOnSettings(self):
"""
Tests the OneLogin_Saml2_LogoutRequest Constructor.
The creation of a deflated SAML Logout Request
Case: Defines NameIDFormat from settings
"""
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
settings_info = self.loadSettingsJSON()
name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
name_id_format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
settings_info['sp']['NameIDFormat'] = name_id_format
settings = OneLogin_Saml2_Settings(settings_info)
logout_request = OneLogin_Saml2_Logout_Request(settings, name_id=name_id)
logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(logout_request.get_request())
name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request_xml)
expected_name_id_data = {
'Value': name_id,
'Format': name_id_format
}
self.assertEqual(expected_name_id_data, name_id_data)

def testConstructorWithoutNameIdFormat(self):
"""
Tests the OneLogin_Saml2_LogoutRequest Constructor.
Case: Checks that NameIDFormat is not added
"""
settings_info = self.loadSettingsJSON()
name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
name_id_format = 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
settings_info['sp']['NameIDFormat'] = name_id_format
settings = OneLogin_Saml2_Settings(settings_info)
logout_request = OneLogin_Saml2_Logout_Request(settings, name_id=name_id)
logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(logout_request.get_request())
name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request_xml)
expected_name_id_data = {
'Value': name_id
}
self.assertEqual(expected_name_id_data, name_id_data)

def testConstructorEncryptIdUsingX509certMulti(self):
"""
Tests the OneLogin_Saml2_LogoutRequest Constructor.
Case: Able to generate encryptedID with MultiCert
"""
settings_info = self.loadSettingsJSON('settings8.json')
settings_info['security']['nameIdEncrypted'] = True
settings = OneLogin_Saml2_Settings(settings_info)

logout_request = OneLogin_Saml2_Logout_Request(settings)

parameters = {'SAMLRequest': logout_request.get_request()}
Expand All @@ -92,6 +128,7 @@ def testCreateDeflatedSAMLLogoutRequestURLParameter(self):
payload = exploded['SAMLRequest'][0]
inflated = OneLogin_Saml2_Utils.decode_base64_and_inflate(payload)
self.assertRegexpMatches(inflated, '^<samlp:LogoutRequest')
self.assertRegexpMatches(inflated, '<saml:EncryptedID>')

def testGetIDFromSAMLLogoutRequest(self):
"""
Expand Down
11 changes: 11 additions & 0 deletions tests/src/OneLogin/saml2_tests/utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,17 @@ def testGenerateNameIdWithSPNameQualifier(self):
expected_name_id_enc = '<saml:EncryptedID><xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/><xenc:CipherData><xenc:CipherValue>'
self.assertIn(expected_name_id_enc, name_id_enc)

def testGenerateNameIdWithoutFormat(self):
"""
Tests the generateNameId method of the OneLogin_Saml2_Utils
"""
name_id_value = 'ONELOGIN_ce998811003f4e60f8b07a311dc641621379cfde'
name_id_format = None

name_id = OneLogin_Saml2_Utils.generate_name_id(name_id_value, None, name_id_format)
expected_name_id = '<saml:NameID>ONELOGIN_ce998811003f4e60f8b07a311dc641621379cfde</saml:NameID>'
self.assertEqual(name_id, expected_name_id)

def testGenerateNameIdWithoutSPNameQualifier(self):
"""
Tests the generateNameId method of the OneLogin_Saml2_Utils
Expand Down

0 comments on commit 265d019

Please sign in to comment.