diff options
author | Roland Hedberg <roland.hedberg@adm.umu.se> | 2014-06-18 12:49:07 +0200 |
---|---|---|
committer | Roland Hedberg <roland.hedberg@adm.umu.se> | 2014-06-18 12:49:07 +0200 |
commit | 2ee73258f923c55783a4b8650ad7fb3394bf83c1 (patch) | |
tree | cf2e6c5a585c754f117b10313c01b816766cb85a | |
parent | ce93950ad8aaace170cbc5b41988101a8d3f5629 (diff) | |
download | pysaml2-2ee73258f923c55783a4b8650ad7fb3394bf83c1.tar.gz |
Fixed so it works with the SP only supporting HTTP-Redirect binding.
-rwxr-xr-x | example/idp2/idp.py | 13 | ||||
-rwxr-xr-x | example/sp-wsgi/sp.py | 30 | ||||
-rw-r--r-- | src/saml2/client_base.py | 2 | ||||
-rw-r--r-- | src/saml2/entity.py | 27 |
4 files changed, 49 insertions, 23 deletions
diff --git a/example/idp2/idp.py b/example/idp2/idp.py index e1adfffc..75b8fde1 100755 --- a/example/idp2/idp.py +++ b/example/idp2/idp.py @@ -156,10 +156,19 @@ class Service(object): return self.do(request, BINDING_HTTP_ARTIFACT) def response(self, binding, http_args): + resp = None if binding == BINDING_HTTP_ARTIFACT: resp = Redirect() - else: + elif http_args["data"]: resp = Response(http_args["data"], headers=http_args["headers"]) + else: + for header in http_args["headers"]: + if header[0] == "Location": + resp = Redirect(header[1]) + + if not resp: + resp = ServiceError("Don't know how to return response") + return resp(self.environ, self.start_response) def do(self, query, binding, relay_state="", encrypt_cert=None): @@ -254,7 +263,7 @@ class SSO(Service): self.binding_out, self.destination = IDP.pick_binding( "assertion_consumer_service", bindings=self.response_bindings, - entity_id=_authn_req.issuer.text) + entity_id=_authn_req.issuer.text, request=_authn_req) except Exception as err: logger.error("Couldn't find receiver endpoint: %s" % err) raise diff --git a/example/sp-wsgi/sp.py b/example/sp-wsgi/sp.py index f940f29f..5fa31da8 100755 --- a/example/sp-wsgi/sp.py +++ b/example/sp-wsgi/sp.py @@ -522,14 +522,22 @@ class SSO(object): logger.info("Chosen IdP: '%s'" % idp_entity_id) return 0, idp_entity_id - def redirect_to_auth(self, _cli, entity_id, came_from, vorg_name=""): + def redirect_to_auth(self, _cli, entity_id, came_from): try: + # Picks a binding to use for sending the Request to the IDP _binding, destination = _cli.pick_binding( "single_sign_on_service", self.bindings, "idpsso", entity_id=entity_id) logger.debug("binding: %s, destination: %s" % (_binding, destination)) - req_id, req = _cli.create_authn_request(destination, vorg=vorg_name) + # Binding here is the response binding that is which binding the + # IDP should use to return the response. + acs = _cli.config.getattr("endpoints", "sp")[ + "assertion_consumer_service"] + # just pick one + endp, return_binding = acs[0] + req_id, req = _cli.create_authn_request(destination, + binding=return_binding) _rstate = rndstr() self.cache.relay_state[_rstate] = came_from ht_args = _cli.apply_binding(_binding, "%s" % req, destination, @@ -553,14 +561,6 @@ class SSO(object): came_from = geturl(self.environ) logger.debug("[sp.challenge] RelayState >> '%s'" % came_from) - # Am I part of a virtual organization or more than one ? - try: - vorg_name = _cli.vorg._name - except AttributeError: - vorg_name = "" - - logger.debug("[sp.challenge] VO: %s" % vorg_name) - # If more than one idp and if none is selected, I have to do wayf (done, response) = self._pick_idp(came_from) # Three cases: -1 something went wrong or Discovery service used @@ -575,7 +575,7 @@ class SSO(object): else: entity_id = response # Do the AuthnRequest - resp = self.redirect_to_auth(_cli, entity_id, came_from, vorg_name) + resp = self.redirect_to_auth(_cli, entity_id, came_from) return resp(self.environ, self.start_response) @@ -598,12 +598,6 @@ def main(environ, start_response, _sp): return _sso.do() -#noinspection PyUnusedLocal -def verify_login_cookie(environ, start_response, _sp): - _sso = SSO(_sp, environ, start_response, cache=CACHE, **ARGS) - return _sso.do() - - def disco(environ, start_response, _sp): query = parse_qs(environ["QUERY_STRING"]) entity_id = query["entityID"][0] @@ -624,7 +618,6 @@ urls = [ # Hmm, place holder, NOT used ('place', ("holder", None)), (r'^$', main), - (r'^login', verify_login_cookie), (r'^disco', disco) ] @@ -655,6 +648,7 @@ def application(environ, start_response): path = environ.get('PATH_INFO', '').lstrip('/') logger.debug("<application> PATH: '%s'" % path) + logger.debug("Finding callback to run") try: for regex, spec in urls: diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py index 94d0f1a7..f4676d23 100644 --- a/src/saml2/client_base.py +++ b/src/saml2/client_base.py @@ -530,7 +530,7 @@ class Base(Entity): "allow_unsolicited": self.allow_unsolicited, "want_assertions_signed": self.want_assertions_signed, "want_response_signed": self.want_response_signed, - "return_addrs": self.service_urls(), + "return_addrs": self.service_urls(binding=binding), "entity_id": self.config.entityid, "attribute_converters": self.config.attribute_converters, "allow_unknown_attributes": diff --git a/src/saml2/entity.py b/src/saml2/entity.py index 5a1f96fb..f6f053ef 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -228,7 +228,10 @@ class Entity(HTTPBase): sfunc = getattr(self.metadata, service) if bindings is None: - bindings = self.config.preferred_binding[service] + if request and request.protocol_binding: + bindings = [request.protocol_binding] + else: + bindings = self.config.preferred_binding[service] if not descr_type: if self.entity_type == "sp": @@ -236,11 +239,31 @@ class Entity(HTTPBase): else: descr_type = "spsso" + _url = _index = None + if request: + try: + _url = getattr(request, "%s_url" % service) + except AttributeError: + _url = None + try: + _index = getattr(request, "%s_index" % service) + except AttributeError: + pass + for binding in bindings: try: srvs = sfunc(entity_id, binding, descr_type) if srvs: - return binding, destinations(srvs)[0] + if _url: + for srv in srvs: + if srv["location"] == _url: + return binding, _url + elif _index: + for srv in srvs: + if srv["index"] == _index: + return binding, srv["location"] + else: + return binding, destinations(srvs)[0] except UnsupportedBinding: pass |