Skip to content

Commit 2e95269

Browse files
author
Rebecka Gulliksson
committed
Support HTTP POST binding in FakeSP.make_auth_req.
1 parent 7b052a2 commit 2e95269

File tree

6 files changed

+25
-26
lines changed

6 files changed

+25
-26
lines changed

tests/flows/test_saml-oidc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def run_test(self, satosa_config_dict, sp_conf, oidc_backend_config, frontend_co
3434
fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False))
3535

3636
# create auth req
37-
req = urlparse(fakesp.make_auth_req(frontend_metadata[frontend_config["name"]][0].entity_id))
38-
auth_req = req.path + "?" + req.query
37+
destination, req_args = fakesp.make_auth_req(frontend_metadata[frontend_config["name"]][0].entity_id)
38+
auth_req = urlparse(destination).path + "?" + urlencode(req_args)
3939

4040
# make auth req to proxy
4141
proxied_auth_req = test_client.get(auth_req)

tests/flows/test_saml-saml.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ def run_test(self, satosa_config_dict, sp_conf, idp_conf, saml_backend_config, f
3131
fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False))
3232

3333
# create auth req
34-
req = urlparse(fakesp.make_auth_req(frontend_metadata[frontend_config["name"]][0].entity_id))
35-
auth_req = req.path + "?" + req.query
34+
destination, req_args = fakesp.make_auth_req(frontend_metadata[frontend_config["name"]][0].entity_id)
35+
auth_req = urlparse(destination).path + "?" + urlencode(req_args)
3636

3737
# make auth req to proxy
3838
proxied_auth_req = test_client.get(auth_req)

tests/satosa/backends/test_saml2.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,7 @@ def test_authn_response(self, context, idp_conf, sp_conf):
164164
response_binding = BINDING_HTTP_REDIRECT
165165
fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False))
166166
fakeidp = FakeIdP(USERS, config=IdPConfig().load(idp_conf, metadata_construction=False))
167-
auth_req = fakesp.make_auth_req(idp_conf["entityid"])
168-
request_params = dict(parse_qsl(urlparse(auth_req).query))
167+
destination, request_params = fakesp.make_auth_req(idp_conf["entityid"])
169168
url, auth_resp = fakeidp.handle_auth_req(request_params["SAMLRequest"], request_params["RelayState"],
170169
BINDING_HTTP_REDIRECT,
171170
"testuser1", response_binding=response_binding)

tests/satosa/frontends/test_saml2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ def setup_for_authn_req(self, context, idp_conf, sp_conf, nameid_format=None, re
7070
sp_conf["metadata"]["inline"].append(idp_metadata_str)
7171

7272
fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False))
73-
context.request = parse.parse_qs(
74-
urlparse(fakesp.make_auth_req(samlfrontend.idp_config["entityid"], nameid_format, relay_state)).query)
73+
destination, auth_req = fakesp.make_auth_req(samlfrontend.idp_config["entityid"], nameid_format, relay_state)
74+
context.request = auth_req
7575
tmp_dict = {}
7676
for val in context.request:
7777
if isinstance(context.request[val], list):

tests/test_requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pytest==2.8.5
2-
responses==0.5.0
2+
responses==0.5.0
3+
beautifulsoup4==4.5.1

tests/util.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
from urllib.parse import parse_qsl, urlparse
88

99
from Crypto.PublicKey import RSA
10+
from bs4 import BeautifulSoup
1011
from saml2 import server, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
1112
from saml2.authn_context import AuthnBroker, authn_context_class_ref, PASSWORD
1213
from saml2.cert import OpenSSLWrapper
1314
from saml2.client import Saml2Client
14-
from saml2.config import config_factory, Config
15+
from saml2.config import Config
1516
from saml2.metadata import entity_descriptor
1617
from saml2.saml import name_id_from_string, NAMEID_FORMAT_TRANSIENT, NAMEID_FORMAT_PERSISTENT
1718
from saml2.samlp import NameIDPolicy
@@ -34,7 +35,8 @@ def __init__(self, config):
3435
"""
3536
Saml2Client.__init__(self, config)
3637

37-
def make_auth_req(self, entity_id, nameid_format=None, relay_state="relay_state", binding=BINDING_HTTP_REDIRECT):
38+
def make_auth_req(self, entity_id, nameid_format=None, relay_state="relay_state",
39+
request_binding=BINDING_HTTP_REDIRECT, response_binding=BINDING_HTTP_REDIRECT):
3840
"""
3941
:type entity_id: str
4042
:rtype: str
@@ -45,26 +47,23 @@ def make_auth_req(self, entity_id, nameid_format=None, relay_state="relay_state"
4547
# Picks a binding to use for sending the Request to the IDP
4648
_binding, destination = self.pick_binding(
4749
'single_sign_on_service',
48-
[binding], 'idpsso',
50+
[request_binding], 'idpsso',
4951
entity_id=entity_id)
50-
# Binding here is the response binding that is which binding the
51-
# IDP shou ld use to return the response.
52-
acs = self.config.getattr('endpoints', 'sp')[
53-
'assertion_consumer_service']
54-
# just pick one
55-
return_binding = None
56-
for i in range(len(acs)):
57-
endp, return_binding = acs[i]
58-
if return_binding == _binding:
59-
break
6052

6153
req_id, req = self.create_authn_request(destination,
62-
binding=return_binding, nameid_format=nameid_format)
54+
binding=response_binding, nameid_format=nameid_format)
6355
ht_args = self.apply_binding(_binding, '%s' % req, destination,
6456
relay_state=relay_state)
6557

66-
url = ht_args['headers'][0][1]
67-
return url
58+
if _binding == BINDING_HTTP_POST:
59+
form_post_html = "\n".join(ht_args["data"])
60+
doctree = BeautifulSoup(form_post_html, "html.parser")
61+
saml_request = doctree.find("input", {"name": "SAMLRequest"})["value"]
62+
resp = {"SAMLRequest": saml_request, "RelayState": relay_state}
63+
elif _binding == BINDING_HTTP_REDIRECT:
64+
resp = dict(parse_qsl(urlparse(dict(ht_args["headers"])["Location"]).query))
65+
66+
return destination, resp
6867

6968

7069
class FakeIdP(server.Server):
@@ -120,7 +119,7 @@ def handle_auth_req(self, saml_request, relay_state, binding, userid,
120119

121120
if response_binding == BINDING_HTTP_POST:
122121
saml_response = base64.b64encode(str(_resp).encode("utf-8"))
123-
resp = {'SAMLResponse': saml_response, 'RelayState': relay_state}
122+
resp = {"SAMLResponse": saml_response, "RelayState": relay_state}
124123
elif response_binding == BINDING_HTTP_REDIRECT:
125124
http_args = self.apply_binding(response_binding, '%s' % _resp,
126125
destination, relay_state, response=True)

0 commit comments

Comments
 (0)