Skip to content

Commit 9fd184c

Browse files
author
Serge Domkowski
committed
Allow for properly signed HTTP_REDIRECT logout request.
1 parent ae9d27e commit 9fd184c

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

src/saml2/client.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from saml2 import BINDING_HTTP_POST
1515
from saml2 import BINDING_SOAP
1616

17+
import saml2.xmldsig as ds
18+
1719
from saml2.ident import decode, code
1820
from saml2.httpbase import HTTPError
1921
from saml2.s_utils import sid
@@ -161,7 +163,7 @@ def global_logout(self, name_id, reason="", expire=None, sign=None):
161163
return self.do_logout(name_id, entity_ids, reason, expire, sign)
162164

163165
def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
164-
expected_binding=None):
166+
expected_binding=None, **kwargs):
165167
"""
166168
167169
:param name_id: Identifier of the Subject (a NameID instance)
@@ -172,6 +174,7 @@ def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
172174
:param sign: Whether to sign the request or not
173175
:param expected_binding: Specify the expected binding then not try it
174176
all
177+
:param kwargs: Extra key word arguments.
175178
:return:
176179
"""
177180
# check time
@@ -214,15 +217,23 @@ def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
214217
if sign is None:
215218
sign = self.logout_requests_signed
216219

220+
sigalg = None
221+
key = None
217222
if sign:
218-
srequest = self.sign(request)
223+
if binding == BINDING_HTTP_REDIRECT:
224+
sigalg = kwargs.get("sigalg", ds.sig_default)
225+
key = kwargs.get("key", self.signkey)
226+
srequest = str(request)
227+
else:
228+
srequest = self.sign(request)
219229
else:
220-
srequest = "%s" % request
230+
srequest = str(request)
221231

222232
relay_state = self._relay_state(req_id)
223233

224234
http_info = self.apply_binding(binding, srequest, destination,
225-
relay_state)
235+
relay_state, sigalg=sigalg,
236+
key=key)
226237

227238
if binding == BINDING_SOAP:
228239
response = self.send(**http_info)

tests/test_51_client.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,48 @@ def test_signed_redirect(self):
11791179
BINDING_HTTP_REDIRECT)
11801180
print(res)
11811181

1182+
def test_do_logout_signed_redirect(self):
1183+
conf = config.SPConfig()
1184+
conf.load_file("sp_slo_redirect_conf")
1185+
client = Saml2Client(conf)
1186+
key = client.signkey
1187+
1188+
# information about the user from an IdP
1189+
session_info = {
1190+
"name_id": nid,
1191+
"issuer": "urn:mace:example.com:saml:roland:idp",
1192+
"not_on_or_after": in_a_while(minutes=15),
1193+
"ava": {
1194+
"givenName": "Anders",
1195+
"surName": "Andersson",
1196+
1197+
}
1198+
}
1199+
client.users.add_information_about_person(session_info)
1200+
entity_ids = client.users.issuers_of_info(nid)
1201+
assert entity_ids == ["urn:mace:example.com:saml:roland:idp"]
1202+
1203+
resp = client.do_logout(nid, entity_ids, "Tired", in_a_while(minutes=5),
1204+
sign=True, expected_binding=BINDING_HTTP_REDIRECT)
1205+
1206+
assert list(resp.keys()) == entity_ids
1207+
binding, info = resp[entity_ids[0]]
1208+
assert binding == BINDING_HTTP_REDIRECT
1209+
1210+
loc = info["headers"][0][1]
1211+
_, _, _, _, qs, _ = urlparse(loc)
1212+
qs = parse_qs(qs)
1213+
assert _leq(qs.keys(),
1214+
['SigAlg', 'SAMLRequest', 'RelayState', 'Signature'])
1215+
1216+
assert verify_redirect_signature(list_values2simpletons(qs),
1217+
sigkey=key)
1218+
1219+
res = self.server.parse_logout_request(qs["SAMLRequest"][0],
1220+
BINDING_HTTP_REDIRECT)
1221+
print(res)
1222+
1223+
11821224
# Below can only be done with dummy Server
11831225
IDP = "urn:mace:example.com:saml:roland:idp"
11841226

0 commit comments

Comments
 (0)