Example #1
0
 def store_state(self, authn_req, relay_state, req_args):
     # Which page was accessed to get here
     came_from = geturl(self.environ)
     key = hash(came_from + self.environ["REMOTE_ADDR"] + str(time.time()))
     logger.debug("[sp.challenge] RelayState >> '%s'" % came_from)
     self.cache[key] = (authn_req, relay_state, req_args)
     return key
Example #2
0
 def store_state(self, authn_req, relay_state, req_args):
     # Which page was accessed to get here.
     came_from = geturl(self.environ)
     key = str(hash(came_from + self.environ["REMOTE_ADDR"] + str(time.time())))
     logger.debug("[sp.challenge] RelayState >> '%s'" % came_from)
     self.cache[key] = (authn_req, relay_state, req_args)
     return key
Example #3
0
File: sp.py Project: rohe/actester
    def do(self):
        _cli = self.sp

        # Which page was accessed to get here
        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.info("[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
        #               0 I've got an IdP to send a request to
        #               >0 ECP in progress
        logger.debug("_idp_pick returned: %s" % done)
        if done == -1:
            return response
        elif done > 0:
            self.cache.outstanding_queries[done] = came_from
            return ECP_response(response)
        else:
            entity_id = response
            # Do the AuthnRequest
            return self._redirect_to_auth(_cli,
                                          entity_id,
                                          came_from,
                                          vorg_name="")
Example #4
0
 def not_authn(self, key, requested_authn_context):
     ruri = geturl(self.environ, query=False)
     return do_authentication(self.environ,
                              self.start_response,
                              authn_context=requested_authn_context,
                              key=key,
                              redirect_uri=ruri)
Example #5
0
    def do(self):
        _cli = self.sp

        # Which page was accessed to get here
        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
        # 0 I've got an IdP to send a request to
        # >0 ECP in progress
        logger.debug("_idp_pick returned: %s" % done)
        if done == -1:
            return response(self.environ, self.start_response)
        elif done > 0:
            self.cache.outstanding_queries[done] = came_from
            return ECP_response(response)
        else:
            entity_id = response
            # Do the AuthnRequest
            resp = self._redirect_to_auth(_cli, entity_id, came_from, vorg_name)
            return resp(self.environ, self.start_response)
Example #6
0
    def not_authn(self, key, requested_authn_context):
        ruri = geturl(self.environ, query=False)

        kwargs = dict(authn_context=requested_authn_context, key=key, redirect_uri=ruri)
        # Clear cookie, if it already exists
        kaka = delete_cookie(self.environ, "idpauthn")
        if kaka:
            kwargs["headers"] = [kaka]
        return do_authentication(self.environ, self.start_response, **kwargs)
Example #7
0
    def not_authn(self, key, requested_authn_context):
        ruri = geturl(self.environ, query=False)

        kwargs = dict(authn_context=requested_authn_context, key=key, redirect_uri=ruri)
        # Clear cookie, if it already exists
        kaka = delete_cookie(self.environ, "idpauthn")
        if kaka:
            kwargs["headers"] = [kaka]
        return do_authentication(self.environ, self.start_response, **kwargs)
Example #8
0
    def do(self):
        _cli = self.sp

        # Which page was accessed to get here
        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.info("[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
        #               0 I've got an IdP to send a request to
        #               >0 ECP in progress
        logger.debug("_idp_pick returned: %s" % done)
        if done == -1:
            return response
        elif done > 0:
            self.cache.outstanding_queries[done] = came_from
            return ECP_response(response)
        else:
            entity_id = response
            # Do the AuthnRequest
            try:
                _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 = _cli.create_authn_request(destination, vorg=vorg_name)
                _rstate = rndstr()
                self.cache.relay_state[_rstate] = came_from
                ht_args = _cli.apply_binding(_binding,
                                             "%s" % req,
                                             destination,
                                             relay_state=_rstate)
                _sid = req.id
                logger.debug("ht_args: %s" % ht_args)
            except Exception, exc:
                logger.exception(exc)
                resp = ServiceError(
                    "Failed to construct the AuthnRequest: %s" % exc)
                return resp(self.environ, self.start_response)

            # remember the request
            self.cache.outstanding_queries[_sid] = came_from
            return self.response(_binding, ht_args)
Example #9
0
 def not_authn(self, key, requested_authn_context, cert_str=None, cert_key_str=None):
     redirect_uri = geturl(self.environ, query=False)
     self.logger.debug("Do authentication")
     auth_info = self.idphandler.authn_broker.pick(requested_authn_context)
     if len(auth_info):
         method, reference = auth_info[0]
         logger.debug("Authn chosen: %s (ref=%s)" % (method, reference))
         return method.authenticate(self.environ, self.start_response, reference, key, redirect_uri,
                                    certificate_str=cert_str, certificate_key_str=cert_key_str)
     else:
         resp = Unauthorized("No usable authentication method")
         return resp(self.environ, self.start_response)
Example #10
0
    def do(self):
        _cli = self.sp

        # Which page was accessed to get here
        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.info("[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
        #               0 I've got an IdP to send a request to
        #               >0 ECP in progress
        logger.debug("_idp_pick returned: %s" % done)
        if done == -1:
            return response
        elif done > 0:
            self.cache.outstanding_queries[done] = came_from
            return ECP_response(response)
        else:
            entity_id = response
            # Do the AuthnRequest
            try:
                _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 = _cli.create_authn_request(destination, vorg=vorg_name)
                _rstate = rndstr()
                self.cache.relay_state[_rstate] = came_from
                ht_args = _cli.apply_binding(_binding, "%s" % req, destination,
                                             relay_state=_rstate)
                _sid = req.id
                logger.debug("ht_args: %s" % ht_args)
            except Exception, exc:
                logger.exception(exc)
                resp = ServiceError(
                    "Failed to construct the AuthnRequest: %s" % exc)
                return resp(self.environ, self.start_response)

            # remember the request
            self.cache.outstanding_queries[_sid] = came_from
            return self.response(_binding, ht_args)
Example #11
0
 def not_authn(self,
               key,
               requested_authn_context,
               cert_str=None,
               cert_key_str=None):
     redirect_uri = geturl(self.environ, query=False)
     self.logger.debug("Do authentication")
     auth_info = self.idphandler.authn_broker.pick(requested_authn_context)
     if len(auth_info):
         method, reference = auth_info[0]
         logger.debug("Authn chosen: %s (ref=%s)" % (method, reference))
         return method.authenticate(self.environ,
                                    self.start_response,
                                    reference,
                                    key,
                                    redirect_uri,
                                    certificate_str=cert_str,
                                    certificate_key_str=cert_key_str)
     else:
         resp = Unauthorized("No usable authentication method")
         return resp(self.environ, self.start_response)
Example #12
0
File: sp.py Project: Goggin/pysaml2
    def do(self):
        _cli = self.sp

        # Which page was accessed to get here
        came_from = geturl(self.environ)
        logger.debug("[sp.challenge] RelayState >> '%s'", came_from)

        # 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
        #               0 I've got an IdP to send a request to
        #               >0 ECP in progress
        logger.debug("_idp_pick returned: %s", done)
        if done == -1:
            return response(self.environ, self.start_response)
        elif done > 0:
            self.cache.outstanding_queries[done] = came_from
            return ECPResponse(response)
        else:
            entity_id = response
            # Do the AuthnRequest
            resp = self.redirect_to_auth(_cli, entity_id, came_from)
            return resp(self.environ, self.start_response)
Example #13
0
    def do(self):
        _cli = self.sp

        # Which page was accessed to get here
        came_from = geturl(self.environ)
        logger.debug("[sp.challenge] RelayState >> '%s'", came_from)

        # 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
        #               0 I've got an IdP to send a request to
        #               >0 ECP in progress
        logger.debug("_idp_pick returned: %s", done)
        if done == -1:
            return response(self.environ, self.start_response)
        elif done > 0:
            self.cache.outstanding_queries[done] = came_from
            return ECPResponse(response)
        else:
            entity_id = response
            # Do the AuthnRequest
            resp = self.redirect_to_auth(_cli, entity_id, came_from)
            return resp(self.environ, self.start_response)
Example #14
0
 def not_authn(self, key, requested_authn_context):
     ruri = geturl(self.environ, query=False)
     return do_authentication(self.environ, self.start_response,
                              authn_context=requested_authn_context,
                              key=key, redirect_uri=ruri)
Example #15
0
File: sp.py Project: rohe/actester
    def _pick_idp(self, came_from):
        """
        If more than one idp and if none is selected, I have to do wayf or
        disco
        """

        _cli = self.sp

        logger.info("[_pick_idp] %s" % self.environ)
        if "HTTP_PAOS" in self.environ:
            if self.environ["HTTP_PAOS"] == PAOS_HEADER_INFO:
                if 'application/vnd.paos+xml' in self.environ["HTTP_ACCEPT"]:
                    # Where should I redirect the user to
                    # entityid -> the IdP to use
                    # relay_state -> when back from authentication

                    logger.info("- ECP client detected -")

                    _rstate = rndstr()
                    self.cache.relay_state[_rstate] = geturl(self.environ)
                    _entityid = _cli.config.ecp_endpoint(
                        self.environ["REMOTE_ADDR"])

                    if not _entityid:
                        return -1, ServiceError("No IdP to talk to")
                    logger.info("IdP to talk to: %s" % _entityid)
                    return ecp.ecp_auth_request(_cli, _entityid, _rstate)
                else:
                    return -1, ServiceError('Faulty Accept header')
            else:
                return -1, ServiceError('unknown ECP version')

        # Find all IdPs
        idps = self.sp.metadata.with_descriptor("idpsso")

        idp_entity_id = None

        # Any specific IdP specified in a query part
        query = self.environ.get("QUERY_STRING")
        if query:
            qdict = dict(parse_qs(query))
            try:
                _idp_entity_id = qdict[self.idp_query_param][0]
                if _idp_entity_id in idps:
                    idp_entity_id = _idp_entity_id
            except KeyError:
                logger.debug("No IdP entity ID in query: %s" % query)
                pass

        if idp_entity_id is None:
            if len(idps) == 1:
                # idps is a dictionary
                idp_entity_id = idps.keys()[0]
            elif not len(idps):
                return -1, ServiceError('Misconfiguration')
            else:
                logger.info("ENVIRON: %s" % self.environ)

                if self.wayf:
                    if query:
                        try:
                            wayf_selected = dict(
                                parse_qs(query))["wayf_selected"][0]
                        except KeyError:
                            return self._wayf_redirect(came_from)
                        idp_entity_id = wayf_selected
                    else:
                        return self._wayf_redirect(came_from)
                elif self.discosrv:
                    if query and "foo" in qdict:
                        idp_entity_id = _cli.parse_discovery_service_response(
                            query=query)
                    else:
                        sid_ = sid()
                        SESSIONDB[sid_] = self.kwargs
                        self.cache.outstanding_queries[sid_] = came_from
                        logger.info("Redirect to Discovery Service function")
                        eid = _cli.config.entityid
                        ret = _cli.config.getattr(
                            "endpoints", "sp")["discovery_response"][0][0]
                        ret += "?sid=%s" % sid_
                        loc = _cli.create_discovery_service_request(
                            self.discosrv, eid, **{"return": ret})
                        return -1, SeeOther(headers=[('Location', loc)])
                else:
                    return -1, NotImplemented("No WAYF or DS present!")

        logger.info("Chosen IdP: '%s'" % idp_entity_id)
        return 0, idp_entity_id
Example #16
0
File: sp.py Project: Goggin/pysaml2
    def _pick_idp(self, came_from):
        """
        If more than one idp and if none is selected, I have to do wayf or
        disco
        """

        _cli = self.sp

        logger.debug("[_pick_idp] %s", self.environ)
        if "HTTP_PAOS" in self.environ:
            if self.environ["HTTP_PAOS"] == PAOS_HEADER_INFO:
                if 'application/vnd.paos+xml' in self.environ["HTTP_ACCEPT"]:
                    # Where should I redirect the user to
                    # entityid -> the IdP to use
                    # relay_state -> when back from authentication

                    logger.debug("- ECP client detected -")

                    _rstate = rndstr()
                    self.cache.relay_state[_rstate] = geturl(self.environ)
                    _entityid = _cli.config.ecp_endpoint(
                        self.environ["REMOTE_ADDR"])

                    if not _entityid:
                        return -1, ServiceError("No IdP to talk to")
                    logger.debug("IdP to talk to: %s", _entityid)
                    return ecp.ecp_auth_request(_cli, _entityid, _rstate)
                else:
                    return -1, ServiceError('Faulty Accept header')
            else:
                return -1, ServiceError('unknown ECP version')

        # Find all IdPs
        idps = self.sp.metadata.with_descriptor("idpsso")

        idp_entity_id = None

        kaka = self.environ.get("HTTP_COOKIE", '')
        if kaka:
            try:
                (idp_entity_id, _) = parse_cookie("ve_disco", "SEED_SAW", kaka)
            except ValueError:
                pass
            except TypeError:
                pass

        # Any specific IdP specified in a query part
        query = self.environ.get("QUERY_STRING")
        if not idp_entity_id and query:
            try:
                _idp_entity_id = dict(parse_qs(query))[
                    self.idp_query_param][0]
                if _idp_entity_id in idps:
                    idp_entity_id = _idp_entity_id
            except KeyError:
                logger.debug("No IdP entity ID in query: %s", query)
                pass

        if not idp_entity_id:

            if self.wayf:
                if query:
                    try:
                        wayf_selected = dict(parse_qs(query))[
                            "wayf_selected"][0]
                    except KeyError:
                        return self._wayf_redirect(came_from)
                    idp_entity_id = wayf_selected
                else:
                    return self._wayf_redirect(came_from)
            elif self.discosrv:
                if query:
                    idp_entity_id = _cli.parse_discovery_service_response(
                        query=self.environ.get("QUERY_STRING"))
                if not idp_entity_id:
                    sid_ = sid()
                    self.cache.outstanding_queries[sid_] = came_from
                    logger.debug("Redirect to Discovery Service function")
                    eid = _cli.config.entityid
                    ret = _cli.config.getattr("endpoints",
                                              "sp")["discovery_response"][0][0]
                    ret += "?sid=%s" % sid_
                    loc = _cli.create_discovery_service_request(
                        self.discosrv, eid, **{"return": ret})
                    return -1, SeeOther(loc)
            elif len(idps) == 1:
                # idps is a dictionary
                idp_entity_id = idps.keys()[0]
            elif not len(idps):
                return -1, ServiceError('Misconfiguration')
            else:
                return -1, NotImplemented("No WAYF or DS present!")

        logger.info("Chosen IdP: '%s'", idp_entity_id)
        return 0, idp_entity_id
Example #17
0
    def _pick_idp(self, came_from):
        """
        If more than one idp and if none is selected, I have to do wayf or
        disco
        """

        _cli = self.sp

        logger.debug("[_pick_idp] %s", self.environ)
        if "HTTP_PAOS" in self.environ:
            if self.environ["HTTP_PAOS"] == PAOS_HEADER_INFO:
                if MIME_PAOS in self.environ["HTTP_ACCEPT"]:
                    # Where should I redirect the user to
                    # entityid -> the IdP to use
                    # relay_state -> when back from authentication

                    logger.debug("- ECP client detected -")

                    _rstate = rndstr()
                    self.cache.relay_state[_rstate] = geturl(self.environ)
                    _entityid = _cli.config.ecp_endpoint(
                        self.environ["REMOTE_ADDR"])

                    if not _entityid:
                        return -1, ServiceError("No IdP to talk to")
                    logger.debug("IdP to talk to: %s", _entityid)
                    return ecp.ecp_auth_request(_cli, _entityid, _rstate)
                else:
                    return -1, ServiceError("Faulty Accept header")
            else:
                return -1, ServiceError("unknown ECP version")

        # Find all IdPs
        idps = self.sp.metadata.with_descriptor("idpsso")

        idp_entity_id = None

        kaka = self.environ.get("HTTP_COOKIE", "")
        if kaka:
            try:
                (idp_entity_id, _) = parse_cookie("ve_disco", "SEED_SAW", kaka)
            except ValueError:
                pass
            except TypeError:
                pass

        # Any specific IdP specified in a query part
        query = self.environ.get("QUERY_STRING")
        if not idp_entity_id and query:
            try:
                _idp_entity_id = dict(parse_qs(query))[self.idp_query_param][0]
                if _idp_entity_id in idps:
                    idp_entity_id = _idp_entity_id
            except KeyError:
                logger.debug("No IdP entity ID in query: %s", query)
                pass

        if not idp_entity_id:

            if self.wayf:
                if query:
                    try:
                        wayf_selected = dict(
                            parse_qs(query))["wayf_selected"][0]
                    except KeyError:
                        return self._wayf_redirect(came_from)
                    idp_entity_id = wayf_selected
                else:
                    return self._wayf_redirect(came_from)
            elif self.discosrv:
                if query:
                    idp_entity_id = _cli.parse_discovery_service_response(
                        query=self.environ.get("QUERY_STRING"))
                if not idp_entity_id:
                    sid_ = sid()
                    self.cache.outstanding_queries[sid_] = came_from
                    logger.debug("Redirect to Discovery Service function")
                    eid = _cli.config.entityid
                    ret = _cli.config.getattr("endpoints",
                                              "sp")["discovery_response"][0][0]
                    ret += "?sid=%s" % sid_
                    loc = _cli.create_discovery_service_request(
                        self.discosrv, eid, **{"return": ret})
                    return -1, SeeOther(loc)
            elif len(idps) == 1:
                # idps is a dictionary
                idp_entity_id = list(idps.keys())[0]
            elif not len(idps):
                return -1, ServiceError("Misconfiguration")
            else:
                return -1, NotImplemented("No WAYF or DS present!")

        logger.info("Chosen IdP: '%s'", idp_entity_id)
        return 0, idp_entity_id