summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Hedberg <roland.hedberg@adm.umu.se>2014-06-18 12:49:07 +0200
committerRoland Hedberg <roland.hedberg@adm.umu.se>2014-06-18 12:49:07 +0200
commit2ee73258f923c55783a4b8650ad7fb3394bf83c1 (patch)
treecf2e6c5a585c754f117b10313c01b816766cb85a
parentce93950ad8aaace170cbc5b41988101a8d3f5629 (diff)
downloadpysaml2-2ee73258f923c55783a4b8650ad7fb3394bf83c1.tar.gz
Fixed so it works with the SP only supporting HTTP-Redirect binding.
-rwxr-xr-xexample/idp2/idp.py13
-rwxr-xr-xexample/sp-wsgi/sp.py30
-rw-r--r--src/saml2/client_base.py2
-rw-r--r--src/saml2/entity.py27
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