Skip to content

Commit 0791176

Browse files
committed
Merge branch 'feature/bugfix-adfs' of https://github.com/m6a-UdS/python-saml into m6a-UdS-feature/bugfix-adfs
2 parents 957b587 + 86aaca4 commit 0791176

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

src/onelogin/saml2/logout_request.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ def is_valid(self, request_data):
272272
else:
273273
get_data = {}
274274

275+
if 'lowercase_urlencoding' in request_data.keys():
276+
lowercase_urlencoding = request_data['lowercase_urlencoding']
277+
else:
278+
lowercase_urlencoding = False
279+
275280
if self.__settings.is_strict():
276281
res = OneLogin_Saml2_Utils.validate_xml(dom, 'saml-schema-protocol-2.0.xsd', self.__settings.is_debug_active())
277282
if not isinstance(res, Document):
@@ -316,10 +321,10 @@ def is_valid(self, request_data):
316321
else:
317322
sign_alg = get_data['SigAlg']
318323

319-
signed_query = 'SAMLRequest=%s' % OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SAMLRequest')
324+
signed_query = 'SAMLRequest=%s' % OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SAMLRequest', lowercase_urlencoding=lowercase_urlencoding)
320325
if 'RelayState' in get_data:
321-
signed_query = '%s&RelayState=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'RelayState'))
322-
signed_query = '%s&SigAlg=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SigAlg', OneLogin_Saml2_Constants.RSA_SHA1))
326+
signed_query = '%s&RelayState=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'RelayState', lowercase_urlencoding=lowercase_urlencoding))
327+
signed_query = '%s&SigAlg=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SigAlg', OneLogin_Saml2_Constants.RSA_SHA1, lowercase_urlencoding=lowercase_urlencoding))
323328

324329
if 'x509cert' not in idp_data or idp_data['x509cert'] is None:
325330
raise Exception('In order to validate the sign on the Logout Request, the x509cert of the IdP is required')

src/onelogin/saml2/logout_response.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ def is_valid(self, request_data, request_id=None):
8282
idp_entity_id = idp_data['entityId']
8383
get_data = request_data['get_data']
8484

85+
if 'lowercase_urlencoding' in request_data.keys():
86+
lowercase_urlencoding = request_data['lowercase_urlencoding']
87+
else:
88+
lowercase_urlencoding = False
89+
8590
if self.__settings.is_strict():
8691
res = OneLogin_Saml2_Utils.validate_xml(self.document, 'saml-schema-protocol-2.0.xsd', self.__settings.is_debug_active())
8792
if not isinstance(res, Document):
@@ -119,10 +124,10 @@ def is_valid(self, request_data, request_id=None):
119124
else:
120125
sign_alg = get_data['SigAlg']
121126

122-
signed_query = 'SAMLResponse=%s' % OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SAMLResponse')
127+
signed_query = 'SAMLResponse=%s' % OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SAMLResponse', lowercase_urlencoding=lowercase_urlencoding)
123128
if 'RelayState' in get_data:
124-
signed_query = '%s&RelayState=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'RelayState'))
125-
signed_query = '%s&SigAlg=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SigAlg', OneLogin_Saml2_Constants.RSA_SHA1))
129+
signed_query = '%s&RelayState=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'RelayState', lowercase_urlencoding=lowercase_urlencoding))
130+
signed_query = '%s&SigAlg=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SigAlg', OneLogin_Saml2_Constants.RSA_SHA1, lowercase_urlencoding=lowercase_urlencoding))
126131

127132
if 'x509cert' not in idp_data or idp_data['x509cert'] is None:
128133
raise Exception('In order to validate the sign on the Logout Response, the x509cert of the IdP is required')

src/onelogin/saml2/utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,18 +1127,19 @@ def validate_binary_sign(signed_query, signature, cert=None, algorithm=OneLogin_
11271127
return False
11281128

11291129
@staticmethod
1130-
def get_encoded_parameter(get_data, name, default=None):
1130+
def get_encoded_parameter(get_data, name, default=None, lowercase_urlencoding=False):
11311131
"""Return an url encoded get parameter value
11321132
Prefer to extract the original encoded value directly from query_string since url
11331133
encoding is not canonical. The encoding used by ADFS 3.0 is not compatible with
11341134
python's quote_plus (ADFS produces lower case hex numbers and quote_plus produces
11351135
upper case hex numbers)
11361136
"""
1137+
11371138
if name not in get_data:
1138-
return quote_plus(default)
1139+
return OneLogin_Saml2_Utils.case_sensitive_urlencode(default, lowercase_urlencoding)
11391140
if 'query_string' in get_data:
11401141
return OneLogin_Saml2_Utils.extract_raw_query_parameter(get_data['query_string'], name)
1141-
return quote_plus(get_data[name])
1142+
return OneLogin_Saml2_Utils.case_sensitive_urlencode(get_data[name], lowercase_urlencoding)
11421143

11431144
@staticmethod
11441145
def extract_raw_query_parameter(query_string, parameter, default=''):
@@ -1147,3 +1148,8 @@ def extract_raw_query_parameter(query_string, parameter, default=''):
11471148
return m.group(1)
11481149
else:
11491150
return default
1151+
1152+
@staticmethod
1153+
def case_sensitive_urlencode(to_encode, lowercase=False):
1154+
encoded = quote_plus(to_encode)
1155+
return re.sub(r"%[A-F0-9]{2}", lambda m: m.group(0).lower(), encoded) if lowercase else encoded

0 commit comments

Comments
 (0)