Skip to content

Commit 201ea4b

Browse files
authored
Merge pull request #256 from eltoder/feature/validate-signature-query-string
Add an option to use query string for validation
2 parents ffa5456 + 293bcde commit 201ea4b

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,10 @@ req = {
568568

569569
# Advanced request options
570570
"https": "",
571-
"lowercase_urlencoding": "",
572571
"request_uri": "",
573-
"query_string": ""
572+
"query_string": "",
573+
"validate_signature_from_qs": False,
574+
"lowercase_urlencoding": False
574575
}
575576
```
576577

@@ -602,12 +603,12 @@ An explanation of some advanced request parameters:
602603

603604
* `https` - Defaults to ``off``. Set this to ``on`` if you receive responses over HTTPS.
604605

605-
* `lowercase_urlencoding` - Defaults to `false`. ADFS users should set this to `true`.
606-
607-
* `request_uri` - The path where your SAML server recieves requests. Set this if requests are not recieved at the server's root.
606+
* `request_uri` - The path where your SAML server receives requests. Set this if requests are not received at the server's root.
608607

609608
* `query_string` - Set this with additional query parameters that should be passed to the request endpoint.
610609

610+
* `validate_signature_from_qs` - If `True`, use `query_string` to validate request and response signatures. Otherwise, use `get_data`. Defaults to `False`. Note that when using `get_data`, query parameters need to be url-encoded for validation. By default we use upper-case url-encoding. Some IdPs, notably Microsoft AD, use lower-case url-encoding, which makes signature validation to fail. To fix this issue, either pass `query_string` and set `validate_signature_from_qs` to `True`, which works for all IdPs, or set `lowercase_urlencoding` to `True`, which only works for AD.
611+
611612

612613
#### Initiate SSO ####
613614

src/onelogin/saml2/auth.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,22 @@ def add_response_signature(self, response_data, sign_algorithm=OneLogin_Saml2_Co
528528
"""
529529
return self.__build_signature(response_data, 'SAMLResponse', sign_algorithm)
530530

531+
@staticmethod
532+
def __build_sign_query_from_qs(query_string, saml_type):
533+
"""
534+
Build sign query from query string
535+
536+
:param query_string: The query string
537+
:type query_string: str
538+
539+
:param saml_type: The target URL the user should be redirected to
540+
:type saml_type: string SAMLRequest | SAMLResponse
541+
"""
542+
args = ('%s=' % saml_type, 'RelayState=', 'SigAlg=')
543+
parts = query_string.split('&')
544+
# Join in the order of arguments rather than the original order of parts.
545+
return '&'.join(part for arg in args for part in parts if part.startswith(arg))
546+
531547
@staticmethod
532548
def __build_sign_query(saml_data, relay_state, algorithm, saml_type, lowercase_urlencoding=False):
533549
"""
@@ -660,16 +676,16 @@ def __validate_signature(self, data, saml_type, raise_exceptions=False):
660676
if isinstance(sign_alg, bytes):
661677
sign_alg = sign_alg.decode('utf8')
662678

663-
lowercase_urlencoding = False
664-
if 'lowercase_urlencoding' in self.__request_data.keys():
665-
lowercase_urlencoding = self.__request_data['lowercase_urlencoding']
666-
667-
signed_query = self.__build_sign_query(data[saml_type],
668-
data.get('RelayState', None),
669-
sign_alg,
670-
saml_type,
671-
lowercase_urlencoding
672-
)
679+
query_string = self.__request_data.get('query_string')
680+
if query_string and self.__request_data.get('validate_signature_from_qs'):
681+
signed_query = self.__build_sign_query_from_qs(query_string, saml_type)
682+
else:
683+
lowercase_urlencoding = self.__request_data.get('lowercase_urlencoding', False)
684+
signed_query = self.__build_sign_query(data[saml_type],
685+
data.get('RelayState'),
686+
sign_alg,
687+
saml_type,
688+
lowercase_urlencoding)
673689

674690
if exists_multix509sign:
675691
for cert in idp_data['x509certMulti']['signing']:

0 commit comments

Comments
 (0)