Skip to content

Commit

Permalink
Issue #364: Some urls come with 403 response (#366)
Browse files Browse the repository at this point in the history
* Issue #364: Some urls come with 403 response

python3-saml urllib dependency responds with 403 status
to urls with default Python user-agent
  • Loading branch information
galynazholtkevych authored Jul 21, 2023
1 parent 888c8bc commit d1bfaeb
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/onelogin/saml2/idp_metadata_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class OneLogin_Saml2_IdPMetadataParser(object):
"""

@classmethod
def get_metadata(cls, url, validate_cert=True, timeout=None):
def get_metadata(cls, url, validate_cert=True, timeout=None, headers=None):
"""
Gets the metadata XML from the provided URL
:param url: Url where the XML of the Identity Provider Metadata is published.
Expand All @@ -38,19 +38,23 @@ def get_metadata(cls, url, validate_cert=True, timeout=None):
:param timeout: Timeout in seconds to wait for metadata response
:type timeout: int
:param headers: Extra headers to send in the request
:type headers: dict
:returns: metadata XML
:rtype: string
"""
valid = False

request = urllib2.Request(url, headers=headers or {})

if validate_cert:
response = urllib2.urlopen(url, timeout=timeout)
response = urllib2.urlopen(request, timeout=timeout)
else:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
response = urllib2.urlopen(url, context=ctx, timeout=timeout)
response = urllib2.urlopen(request, context=ctx, timeout=timeout)
xml = response.read()

if xml:
Expand Down Expand Up @@ -87,7 +91,7 @@ def parse_remote(cls, url, validate_cert=True, entity_id=None, timeout=None, **k
:returns: settings dict with extracted data
:rtype: dict
"""
idp_metadata = cls.get_metadata(url, validate_cert, timeout)
idp_metadata = cls.get_metadata(url, validate_cert, timeout, headers=kwargs.pop('headers', None))
return cls.parse(idp_metadata, entity_id=entity_id, **kwargs)

@classmethod
Expand Down
15 changes: 15 additions & 0 deletions tests/src/OneLogin/saml2_tests/idp_metadata_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ def testGetMetadata(self):
except URLError:
pass

def testGetMetadataWithHeaders(self):
data = OneLogin_Saml2_IdPMetadataParser.get_metadata('https://samltest.id/saml/providers',
headers={'User-Agent': 'Mozilla/5.0'})
self.assertIsNotNone(data)
self.assertIn(b'entityID=', data)

def testParseRemote(self):
"""
Tests the parse_remote method of the OneLogin_Saml2_IdPMetadataParser
Expand Down Expand Up @@ -86,6 +92,15 @@ def testParseRemote(self):
expected_settings = json.loads(expected_settings_json)
self.assertEqual(expected_settings, data)

def testParseRemoteWithHeaders(self):
"""
Tests the parse_remote method passing headers of the OneLogin_Saml2_IdPMetadataParser
"""
data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://samltest.id/saml/providers')
self.assertEqual(data['idp']['entityId'], 'https://samltest.id/saml/idp')
self.assertIsNotNone(data['idp']['singleSignOnService']['url'])
self.assertIsNotNone(data['idp']['x509certMulti'])

def testParse(self):
"""
Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
Expand Down

0 comments on commit d1bfaeb

Please sign in to comment.