Skip to content

Commit 2ee7325

Browse files
author
Roland Hedberg
committed
Fixed so it works with the SP only supporting HTTP-Redirect binding.
1 parent ce93950 commit 2ee7325

File tree

4 files changed

+49
-23
lines changed

4 files changed

+49
-23
lines changed

example/idp2/idp.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,19 @@ def artifact_operation(self, saml_msg):
156156
return self.do(request, BINDING_HTTP_ARTIFACT)
157157

158158
def response(self, binding, http_args):
159+
resp = None
159160
if binding == BINDING_HTTP_ARTIFACT:
160161
resp = Redirect()
161-
else:
162+
elif http_args["data"]:
162163
resp = Response(http_args["data"], headers=http_args["headers"])
164+
else:
165+
for header in http_args["headers"]:
166+
if header[0] == "Location":
167+
resp = Redirect(header[1])
168+
169+
if not resp:
170+
resp = ServiceError("Don't know how to return response")
171+
163172
return resp(self.environ, self.start_response)
164173

165174
def do(self, query, binding, relay_state="", encrypt_cert=None):
@@ -254,7 +263,7 @@ def verify_request(self, query, binding):
254263
self.binding_out, self.destination = IDP.pick_binding(
255264
"assertion_consumer_service",
256265
bindings=self.response_bindings,
257-
entity_id=_authn_req.issuer.text)
266+
entity_id=_authn_req.issuer.text, request=_authn_req)
258267
except Exception as err:
259268
logger.error("Couldn't find receiver endpoint: %s" % err)
260269
raise

example/sp-wsgi/sp.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -522,14 +522,22 @@ def _pick_idp(self, came_from):
522522
logger.info("Chosen IdP: '%s'" % idp_entity_id)
523523
return 0, idp_entity_id
524524

525-
def redirect_to_auth(self, _cli, entity_id, came_from, vorg_name=""):
525+
def redirect_to_auth(self, _cli, entity_id, came_from):
526526
try:
527+
# Picks a binding to use for sending the Request to the IDP
527528
_binding, destination = _cli.pick_binding(
528529
"single_sign_on_service", self.bindings, "idpsso",
529530
entity_id=entity_id)
530531
logger.debug("binding: %s, destination: %s" % (_binding,
531532
destination))
532-
req_id, req = _cli.create_authn_request(destination, vorg=vorg_name)
533+
# Binding here is the response binding that is which binding the
534+
# IDP should use to return the response.
535+
acs = _cli.config.getattr("endpoints", "sp")[
536+
"assertion_consumer_service"]
537+
# just pick one
538+
endp, return_binding = acs[0]
539+
req_id, req = _cli.create_authn_request(destination,
540+
binding=return_binding)
533541
_rstate = rndstr()
534542
self.cache.relay_state[_rstate] = came_from
535543
ht_args = _cli.apply_binding(_binding, "%s" % req, destination,
@@ -553,14 +561,6 @@ def do(self):
553561
came_from = geturl(self.environ)
554562
logger.debug("[sp.challenge] RelayState >> '%s'" % came_from)
555563

556-
# Am I part of a virtual organization or more than one ?
557-
try:
558-
vorg_name = _cli.vorg._name
559-
except AttributeError:
560-
vorg_name = ""
561-
562-
logger.debug("[sp.challenge] VO: %s" % vorg_name)
563-
564564
# If more than one idp and if none is selected, I have to do wayf
565565
(done, response) = self._pick_idp(came_from)
566566
# Three cases: -1 something went wrong or Discovery service used
@@ -575,7 +575,7 @@ def do(self):
575575
else:
576576
entity_id = response
577577
# Do the AuthnRequest
578-
resp = self.redirect_to_auth(_cli, entity_id, came_from, vorg_name)
578+
resp = self.redirect_to_auth(_cli, entity_id, came_from)
579579
return resp(self.environ, self.start_response)
580580

581581

@@ -598,12 +598,6 @@ def main(environ, start_response, _sp):
598598
return _sso.do()
599599

600600

601-
#noinspection PyUnusedLocal
602-
def verify_login_cookie(environ, start_response, _sp):
603-
_sso = SSO(_sp, environ, start_response, cache=CACHE, **ARGS)
604-
return _sso.do()
605-
606-
607601
def disco(environ, start_response, _sp):
608602
query = parse_qs(environ["QUERY_STRING"])
609603
entity_id = query["entityID"][0]
@@ -624,7 +618,6 @@ def disco(environ, start_response, _sp):
624618
# Hmm, place holder, NOT used
625619
('place', ("holder", None)),
626620
(r'^$', main),
627-
(r'^login', verify_login_cookie),
628621
(r'^disco', disco)
629622
]
630623

@@ -655,6 +648,7 @@ def application(environ, start_response):
655648
path = environ.get('PATH_INFO', '').lstrip('/')
656649
logger.debug("<application> PATH: '%s'" % path)
657650

651+
658652
logger.debug("Finding callback to run")
659653
try:
660654
for regex, spec in urls:

src/saml2/client_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ def parse_authn_request_response(self, xmlstr, binding, outstanding=None,
530530
"allow_unsolicited": self.allow_unsolicited,
531531
"want_assertions_signed": self.want_assertions_signed,
532532
"want_response_signed": self.want_response_signed,
533-
"return_addrs": self.service_urls(),
533+
"return_addrs": self.service_urls(binding=binding),
534534
"entity_id": self.config.entityid,
535535
"attribute_converters": self.config.attribute_converters,
536536
"allow_unknown_attributes":

src/saml2/entity.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,19 +228,42 @@ def pick_binding(self, service, bindings=None, descr_type="", request=None,
228228
sfunc = getattr(self.metadata, service)
229229

230230
if bindings is None:
231-
bindings = self.config.preferred_binding[service]
231+
if request and request.protocol_binding:
232+
bindings = [request.protocol_binding]
233+
else:
234+
bindings = self.config.preferred_binding[service]
232235

233236
if not descr_type:
234237
if self.entity_type == "sp":
235238
descr_type = "idpsso"
236239
else:
237240
descr_type = "spsso"
238241

242+
_url = _index = None
243+
if request:
244+
try:
245+
_url = getattr(request, "%s_url" % service)
246+
except AttributeError:
247+
_url = None
248+
try:
249+
_index = getattr(request, "%s_index" % service)
250+
except AttributeError:
251+
pass
252+
239253
for binding in bindings:
240254
try:
241255
srvs = sfunc(entity_id, binding, descr_type)
242256
if srvs:
243-
return binding, destinations(srvs)[0]
257+
if _url:
258+
for srv in srvs:
259+
if srv["location"] == _url:
260+
return binding, _url
261+
elif _index:
262+
for srv in srvs:
263+
if srv["index"] == _index:
264+
return binding, srv["location"]
265+
else:
266+
return binding, destinations(srvs)[0]
244267
except UnsupportedBinding:
245268
pass
246269

0 commit comments

Comments
 (0)