Skip to content

Commit dde0613

Browse files
Merge pull request #230 from skoranda/dynamic_saml_disovery_service
Dynamic saml discovery service
2 parents 49da5d4 + fd41bf0 commit dde0613

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

src/satosa/backends/saml2.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class SAMLBackend(BackendModule, SAMLBaseModule):
4040
A saml2 backend module (acting as a SP).
4141
"""
4242
KEY_DISCO_SRV = 'disco_srv'
43+
KEY_SAML_DISCOVERY_SERVICE_URL = 'saml_discovery_service_url'
44+
KEY_SAML_DISCOVERY_SERVICE_POLICY = 'saml_discovery_service_policy'
4345
KEY_SP_CONFIG = 'sp_config'
4446
VALUE_ACR_COMPARISON_DEFAULT = 'exact'
4547

@@ -102,9 +104,9 @@ def start_auth(self, context, internal_req):
102104
entity_id = idps[0]
103105
return self.authn_request(context, entity_id)
104106

105-
return self.disco_query()
107+
return self.disco_query(context)
106108

107-
def disco_query(self):
109+
def disco_query(self, context):
108110
"""
109111
Makes a request to the discovery server
110112
@@ -116,8 +118,21 @@ def disco_query(self):
116118
:param internal_req: The request
117119
:return: Response
118120
"""
119-
return_url = self.sp.config.getattr("endpoints", "sp")["discovery_response"][0][0]
120-
loc = self.sp.create_discovery_service_request(self.discosrv, self.sp.config.entityid, **{"return": return_url})
121+
endpoints = self.sp.config.getattr("endpoints", "sp")
122+
return_url = endpoints["discovery_response"][0][0]
123+
124+
disco_url = (
125+
context.get_decoration(self.KEY_SAML_DISCOVERY_SERVICE_URL) or self.discosrv
126+
)
127+
disco_policy = context.get_decoration(self.KEY_SAML_DISCOVERY_SERVICE_POLICY)
128+
129+
args = {"return": return_url}
130+
if disco_policy:
131+
args["policy"] = disco_policy
132+
133+
loc = self.sp.create_discovery_service_request(
134+
disco_url, self.sp.config.entityid, **args
135+
)
121136
return SeeOther(loc)
122137

123138
def construct_requested_authn_context(self, entity_id):

tests/satosa/backends/test_saml2.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ def assert_redirect_to_idp(self, redirect_response, idp_conf):
4747
assert redirect_location == idp_conf["service"]["idp"]["endpoints"]["single_sign_on_service"][0][0]
4848
assert "SAMLRequest" in parse_qs(parsed.query)
4949

50-
def assert_redirect_to_discovery_server(self, redirect_response, sp_conf):
50+
def assert_redirect_to_discovery_server(
51+
self, redirect_response, sp_conf, expected_discosrv_url
52+
):
5153
assert redirect_response.status == "303 See Other"
5254
parsed = urlparse(redirect_response.message)
5355
redirect_location = "{parsed.scheme}://{parsed.netloc}{parsed.path}".format(parsed=parsed)
54-
assert redirect_location == DISCOSRV_URL
56+
assert redirect_location == expected_discosrv_url
5557

5658
request_params = dict(parse_qsl(parsed.query))
5759
assert request_params["return"] == sp_conf["service"]["sp"]["endpoints"]["discovery_response"][0][0]
@@ -99,7 +101,15 @@ def get_path_from_url(url):
99101

100102
def test_start_auth_defaults_to_redirecting_to_discovery_server(self, context, sp_conf):
101103
resp = self.samlbackend.start_auth(context, InternalData())
102-
self.assert_redirect_to_discovery_server(resp, sp_conf)
104+
self.assert_redirect_to_discovery_server(resp, sp_conf, DISCOSRV_URL)
105+
106+
def test_discovery_server_set_in_context(self, context, sp_conf):
107+
discosrv_url = 'https://my.org/saml_discovery_service'
108+
context.decorate(
109+
SAMLBackend.KEY_SAML_DISCOVERY_SERVICE_URL, discosrv_url
110+
)
111+
resp = self.samlbackend.start_auth(context, InternalData())
112+
self.assert_redirect_to_discovery_server(resp, sp_conf, discosrv_url)
103113

104114
def test_full_flow(self, context, idp_conf, sp_conf):
105115
test_state_key = "test_state_key_456afgrh"
@@ -110,7 +120,7 @@ def test_full_flow(self, context, idp_conf, sp_conf):
110120

111121
# start auth flow (redirecting to discovery server)
112122
resp = self.samlbackend.start_auth(context, InternalData())
113-
self.assert_redirect_to_discovery_server(resp, sp_conf)
123+
self.assert_redirect_to_discovery_server(resp, sp_conf, DISCOSRV_URL)
114124

115125
# fake response from discovery server
116126
disco_resp = parse_qs(urlparse(resp.message).query)
@@ -166,7 +176,7 @@ def test_always_redirect_to_discovery_service_if_using_mdq(self, context, sp_con
166176
samlbackend = SAMLBackend(None, INTERNAL_ATTRIBUTES, {"sp_config": sp_conf, "disco_srv": DISCOSRV_URL,},
167177
"base_url", "saml_backend")
168178
resp = samlbackend.start_auth(context, InternalData())
169-
self.assert_redirect_to_discovery_server(resp, sp_conf)
179+
self.assert_redirect_to_discovery_server(resp, sp_conf, DISCOSRV_URL)
170180

171181
def test_authn_request(self, context, idp_conf):
172182
resp = self.samlbackend.authn_request(context, idp_conf["entityid"])

0 commit comments

Comments
 (0)