Beispiel #1
0
    def __init__(self, config_file, entityid=None, debug=False):
        self.urls = []
        self.cache = {}
        self.debug = debug

        sp_conf = config_factory("sp", config_file)
        idp_conf = config_factory("idp", config_file)

        self.config = {"SP": sp_conf, "IDP": idp_conf}

        sys.path.insert(0, os.path.dirname(config_file))
        conf = importlib.import_module(os.path.basename(config_file))
        self.attribute_module = conf.ATTRIBUTE_MODULE
        # If entityID is set it means this is a proxy in front of one IdP.
        if entityid:
            self.entity_id = entityid
            self.sp_args = {}
        else:
            self.entity_id = None
            self.sp_args = {"discosrv": conf.DISCO_SRV}

        sp = SamlSP(None, None, self.config["SP"], self.cache, **self.sp_args)
        self.urls.extend(sp.register_endpoints())

        idp = SamlIDP(None, None, self.config["IDP"], self.cache, None)
        self.urls.extend(idp.register_endpoints())
Beispiel #2
0
    def __init__(self, config_file, entityid=None, debug=False):
        self.urls = []
        self.cache = {}
        self.debug = debug

        sp_conf = config_factory("sp", config_file)
        idp_conf = config_factory("idp", config_file)

        self.config = {
            "SP": sp_conf,
            "IDP": idp_conf
        }

        sys.path.insert(0, os.path.dirname(config_file))
        conf = importlib.import_module(os.path.basename(config_file))
        self.attribute_module = conf.ATTRIBUTE_MODULE
        # If entityID is set it means this is a proxy in front of one IdP.
        if entityid:
            self.entity_id = entityid
            self.sp_args = {}
        else:
            self.entity_id = None
            self.sp_args = {"discosrv": conf.DISCO_SRV}

        sp = SamlSP(None, None, self.config["SP"], self.cache, **self.sp_args)
        self.urls.extend(sp.register_endpoints())

        idp = SamlIDP(None, None, self.config["IDP"], self.cache, None)
        self.urls.extend(idp.register_endpoints())
Beispiel #3
0
    def outgoing(self, response, instance):
        """
        An authentication response has been received and now an authentication
        response from this server should be constructed.

        :param response: The Authentication response
        :param instance: SP instance that received the authentication response
        :return: response
        """

        _idp = SamlIDP(instance.environ, instance.start_response,
                       self.config["SP"], self.cache, self.outgoing)

        _state = instance.sp.state[response.in_response_to]
        orig_authn_req, relay_state, req_args = instance.sp.state[_state]

        # The Subject NameID.
        subject = response.get_subject()
        # Diverse arguments needed to construct the response.
        resp_args = _idp.idp.response_args(orig_authn_req)

        # TODO Slightly awkward, should be done better.
        _authn_info = response.authn_info()[0]

        # If the <AuthnContext> in the response contained one or more
        # <AuthenticatingAuthority> elements then use the first one, otherwise
        # default to using the issuer, which will be the issuing IdP.
        if _authn_info[1]:
            _authn = {
                "class_ref": _authn_info[0],
                "authn_auth": _authn_info[1][0]
            }
        else:
            _authn = {
                "class_ref": _authn_info[0],
                "authn_auth": response.issuer()
            }

        # This is where any possible modification of the assertion is made.
        try:
            response.ava = self.attribute_module.get_attributes(response.ava)
        except NoUserData as e:
            logger.error(
                "User authenticated at IdP but not found by attribute module.")
            raise

        # Will sign the response by default.
        resp = _idp.construct_authn_response(response.ava,
                                             name_id=subject,
                                             authn=_authn,
                                             resp_args=resp_args,
                                             relay_state=relay_state,
                                             sign_response=True)

        return resp
Beispiel #4
0
    def outgoing(self, response, instance):
        """
        An authentication response has been received and now an authentication
        response from this server should be constructed.

        :param response: The Authentication response
        :param instance: SP instance that received the authentication response
        :return: response
        """

        _idp = SamlIDP(instance.environ, instance.start_response,
                       self.config["SP"], self.cache, self.outgoing)

        _state = instance.sp.state[response.in_response_to]
        orig_authn_req, relay_state, req_args = instance.sp.state[_state]

        # The Subject NameID.
        subject = response.get_subject()
        # Diverse arguments needed to construct the response.
        resp_args = _idp.idp.response_args(orig_authn_req)

        # TODO Slightly awkward, should be done better.
        _authn_info = response.authn_info()[0]

        # If the <AuthnContext> in the response contained one or more
        # <AuthenticatingAuthority> elements then use the first one, otherwise
        # default to using the issuer, which will be the issuing IdP.
        if _authn_info[1]:
            _authn = {"class_ref": _authn_info[0], "authn_auth": _authn_info[1][0]}
        else:
            _authn = {"class_ref": _authn_info[0], "authn_auth": response.issuer()}

        # This is where any possible modification of the assertion is made.
        try:
            response.ava = self.attribute_module.get_attributes(response.ava)
        except NoUserData as e:
            logger.error(
                "User authenticated at IdP but not found by attribute module.")
            raise

        # Will sign the response by default.
        resp = _idp.construct_authn_response(
            response.ava, name_id=subject, authn=_authn,
            resp_args=resp_args, relay_state=relay_state, sign_response=True)

        return resp
Beispiel #5
0
    def run_entity(self, spec, environ, start_response):
        """
        Picks entity and method to run by that entity.

        :param spec: a tuple (entity_type, response_type, binding)
        :param environ: WSGI environ
        :param start_response: WSGI start_response
        :return:
        """

        if isinstance(spec, tuple):
            if spec[0] == "SP":
                inst = SamlSP(environ, start_response, self.config["SP"],
                              self.cache, self.outgoing, **self.sp_args)
            else:
                inst = SamlIDP(environ, start_response, self.config["IDP"],
                               self.cache, self.incoming)

            func = getattr(inst, spec[1])
            return func(*spec[2:])
        else:
            return spec()