Allow for properly signed HTTP_REDIRECT logout request.
This commit is contained in:
@@ -14,6 +14,8 @@ from saml2 import BINDING_HTTP_REDIRECT
|
||||
from saml2 import BINDING_HTTP_POST
|
||||
from saml2 import BINDING_SOAP
|
||||
|
||||
import saml2.xmldsig as ds
|
||||
|
||||
from saml2.ident import decode, code
|
||||
from saml2.httpbase import HTTPError
|
||||
from saml2.s_utils import sid
|
||||
@@ -161,7 +163,7 @@ class Saml2Client(Base):
|
||||
return self.do_logout(name_id, entity_ids, reason, expire, sign)
|
||||
|
||||
def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
|
||||
expected_binding=None):
|
||||
expected_binding=None, **kwargs):
|
||||
"""
|
||||
|
||||
:param name_id: Identifier of the Subject (a NameID instance)
|
||||
@@ -172,6 +174,7 @@ class Saml2Client(Base):
|
||||
:param sign: Whether to sign the request or not
|
||||
:param expected_binding: Specify the expected binding then not try it
|
||||
all
|
||||
:param kwargs: Extra key word arguments.
|
||||
:return:
|
||||
"""
|
||||
# check time
|
||||
@@ -214,15 +217,23 @@ class Saml2Client(Base):
|
||||
if sign is None:
|
||||
sign = self.logout_requests_signed
|
||||
|
||||
sigalg = None
|
||||
key = None
|
||||
if sign:
|
||||
srequest = self.sign(request)
|
||||
if binding == BINDING_HTTP_REDIRECT:
|
||||
sigalg = kwargs.get("sigalg", ds.sig_default)
|
||||
key = kwargs.get("key", self.signkey)
|
||||
srequest = str(request)
|
||||
else:
|
||||
srequest = self.sign(request)
|
||||
else:
|
||||
srequest = "%s" % request
|
||||
srequest = str(request)
|
||||
|
||||
relay_state = self._relay_state(req_id)
|
||||
|
||||
http_info = self.apply_binding(binding, srequest, destination,
|
||||
relay_state)
|
||||
relay_state, sigalg=sigalg,
|
||||
key=key)
|
||||
|
||||
if binding == BINDING_SOAP:
|
||||
response = self.send(**http_info)
|
||||
|
||||
@@ -1179,6 +1179,48 @@ class TestClient:
|
||||
BINDING_HTTP_REDIRECT)
|
||||
print(res)
|
||||
|
||||
def test_do_logout_signed_redirect(self):
|
||||
conf = config.SPConfig()
|
||||
conf.load_file("sp_slo_redirect_conf")
|
||||
client = Saml2Client(conf)
|
||||
key = client.signkey
|
||||
|
||||
# information about the user from an IdP
|
||||
session_info = {
|
||||
"name_id": nid,
|
||||
"issuer": "urn:mace:example.com:saml:roland:idp",
|
||||
"not_on_or_after": in_a_while(minutes=15),
|
||||
"ava": {
|
||||
"givenName": "Anders",
|
||||
"surName": "Andersson",
|
||||
"mail": "anders.andersson@example.com"
|
||||
}
|
||||
}
|
||||
client.users.add_information_about_person(session_info)
|
||||
entity_ids = client.users.issuers_of_info(nid)
|
||||
assert entity_ids == ["urn:mace:example.com:saml:roland:idp"]
|
||||
|
||||
resp = client.do_logout(nid, entity_ids, "Tired", in_a_while(minutes=5),
|
||||
sign=True, expected_binding=BINDING_HTTP_REDIRECT)
|
||||
|
||||
assert list(resp.keys()) == entity_ids
|
||||
binding, info = resp[entity_ids[0]]
|
||||
assert binding == BINDING_HTTP_REDIRECT
|
||||
|
||||
loc = info["headers"][0][1]
|
||||
_, _, _, _, qs, _ = urlparse(loc)
|
||||
qs = parse_qs(qs)
|
||||
assert _leq(qs.keys(),
|
||||
['SigAlg', 'SAMLRequest', 'RelayState', 'Signature'])
|
||||
|
||||
assert verify_redirect_signature(list_values2simpletons(qs),
|
||||
sigkey=key)
|
||||
|
||||
res = self.server.parse_logout_request(qs["SAMLRequest"][0],
|
||||
BINDING_HTTP_REDIRECT)
|
||||
print(res)
|
||||
|
||||
|
||||
# Below can only be done with dummy Server
|
||||
IDP = "urn:mace:example.com:saml:roland:idp"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user