Fixed so it works with the SP only supporting HTTP-Redirect binding.
This commit is contained in:
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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":
|
||||
|
@@ -228,6 +228,9 @@ class Entity(HTTPBase):
|
||||
sfunc = getattr(self.metadata, service)
|
||||
|
||||
if bindings is None:
|
||||
if request and request.protocol_binding:
|
||||
bindings = [request.protocol_binding]
|
||||
else:
|
||||
bindings = self.config.preferred_binding[service]
|
||||
|
||||
if not descr_type:
|
||||
@@ -236,10 +239,30 @@ 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:
|
||||
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
|
||||
|
Reference in New Issue
Block a user