コード例 #1
0
    def _apply_filter(self, context, attributes, provider, requester):
        filter_allow = get_dict_defaults(self.attribute_allow, provider,
                                         requester)
        satosa_logging(
            logger, logging.DEBUG,
            "{} filter_allow: {}".format(self.logprefix,
                                         filter_allow), context.state)
        filter_deny = get_dict_defaults(self.attribute_deny, provider,
                                        requester)
        satosa_logging(
            logger, logging.DEBUG,
            "{} filter_deny: {}".format(self.logprefix,
                                        filter_deny), context.state)
        allow = self._filter_attributes(attributes, filter_allow)
        satosa_logging(logger, logging.DEBUG,
                       "{} allow: {}".format(self.logprefix,
                                             allow), context.state)
        deny = self._filter_attributes(attributes, filter_deny)
        satosa_logging(logger, logging.DEBUG,
                       "{} deny: {}".format(self.logprefix,
                                            deny), context.state)

        # Remove Denies (values) from Allows (values)
        for a, v in deny.items():
            for r in v:
                if a in allow and r in allow[a]:
                    allow[a].remove(r)

        result = {a: v for a, v in allow.items() if len(v)}
        satosa_logging(logger, logging.DEBUG,
                       "{} result: {}".format(self.logprefix,
                                              result), context.state)
        return result
コード例 #2
0
    def construct_requested_authn_context(self, entity_id):
        if not self.acr_mapping:
            return None

        acr_entry = util.get_dict_defaults(self.acr_mapping, entity_id)
        if not acr_entry:
            return None

        if type(acr_entry) is not dict:
            acr_entry = {
                "class_ref": acr_entry,
                "comparison": self.VALUE_ACR_COMPARISON_DEFAULT,
            }

        authn_context = requested_authn_context(
            acr_entry['class_ref'], comparison=acr_entry.get(
                'comparison', self.VALUE_ACR_COMPARISON_DEFAULT))

        return authn_context
コード例 #3
0
ファイル: saml2.py プロジェクト: vcruzcid/SATOSA
    def _handle_authn_response(self, context, internal_response, idp):
        """
        See super class satosa.frontends.base.FrontendModule

        :type context: satosa.context.Context
        :type internal_response: satosa.internal.InternalData
        :type idp: saml.server.Server

        :param context: The current context
        :param internal_response: The internal response
        :param idp: The saml frontend idp server
        :return: A saml response
        """
        request_state = self.load_state(context.state)

        resp_args = request_state["resp_args"]
        sp_entity_id = resp_args["sp_entity_id"]
        internal_response.attributes = self._filter_attributes(
            idp, internal_response, context)
        ava = self.converter.from_internal(
            self.attribute_profile, internal_response.attributes)

        auth_info = {}
        if self.acr_mapping:
            auth_info["class_ref"] = self.acr_mapping.get(
                internal_response.auth_info.issuer, self.acr_mapping[""])
        else:
            auth_info["class_ref"] = internal_response.auth_info.auth_class_ref

        auth_info["authn_auth"] = internal_response.auth_info.issuer

        if self.custom_attribute_release:
            custom_release = util.get_dict_defaults(
                self.custom_attribute_release,
                internal_response.auth_info.issuer,
                sp_entity_id)
            attributes_to_remove = custom_release.get("exclude", [])
            for k in attributes_to_remove:
                ava.pop(k, None)

        nameid_value = internal_response.subject_id
        nameid_format = subject_type_to_saml_nameid_format(
            internal_response.subject_type
        )

        # If the backend did not receive a SAML <NameID> and so
        # name_id is set to None then do not create a NameID instance.
        # Instead pass None as the name name_id to the IdP server
        # instance and it will use its configured policy to construct
        # a <NameID>, with the default to create a transient <NameID>.
        name_id = None if not nameid_value else NameID(
            text=nameid_value,
            format=nameid_format,
            sp_name_qualifier=None,
            name_qualifier=None,
        )

        msg = "returning attributes {}".format(json.dumps(ava))
        logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
        logger.debug(logline)

        idp_conf = self.idp_config.get('service', {}).get('idp', {})
        policies = idp_conf.get('policy', {})
        sp_policy = policies.get('default', {})
        sp_policy.update(policies.get(sp_entity_id, {}))

        sign_assertion = sp_policy.get('sign_assertion', False)
        sign_response = sp_policy.get('sign_response', True)
        encrypt_assertion = sp_policy.get('encrypt_assertion', False)
        encrypted_advice_attributes = sp_policy.get('encrypted_advice_attributes', False)

        signing_algorithm = idp_conf.get('signing_algorithm')
        digest_algorithm = idp_conf.get('digest_algorithm')
        sign_alg_attr = sp_policy.get('sign_alg', 'SIG_RSA_SHA256')
        digest_alg_attr = sp_policy.get('digest_alg', 'DIGEST_SHA256')

        # Construct arguments for method create_authn_response
        # on IdP Server instance
        args = {
            # Add the SP details
            **resp_args,
            # AuthnResponse data
            'identity': ava,
            'name_id': name_id,
            'authn': auth_info,
            'sign_response': sign_response,
            'sign_assertion': sign_assertion,
            'encrypt_assertion': encrypt_assertion,
            'encrypted_advice_attributes': encrypted_advice_attributes,
        }

        args['sign_alg'] = signing_algorithm
        if not args['sign_alg']:
            try:
                args['sign_alg'] = getattr(xmldsig, sign_alg_attr)
            except AttributeError as e:
                msg = "Unsupported sign algorithm {}".format(sign_alg)
                logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
                logger.error(logline)
                raise Exception(msg) from e

        msg = "signing with algorithm {}".format(args['sign_alg'])
        logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
        logger.debug(logline)

        args['digest_alg'] = digest_algorithm
        if not args['digest_alg']:
            try:
                args['digest_alg'] = getattr(xmldsig, digest_alg_attr)
            except AttributeError as e:
                msg = "Unsupported digest algorithm {}".format(digest_alg)
                logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
                logger.error(logline)
                raise Exception(msg) from e

        msg = "using digest algorithm {}".format(args['digest_alg'])
        logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
        logger.debug(logline)

        if sign_alg_attr or digest_alg_attr:
            msg = (
                "sign_alg and digest_alg are deprecated; "
                "instead, use signing_algorithm and digest_algorithm "
                "under the service/idp configuration path "
                "(not under policy/default)."
            )
            logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
            logger.warning(msg)

        resp = idp.create_authn_response(**args)
        http_args = idp.apply_binding(
            resp_args["binding"], str(resp), resp_args["destination"],
            request_state["relay_state"], response=True)

        # Set the common domain cookie _saml_idp if so configured.
        if self.config.get('common_domain_cookie'):
            self._set_common_domain_cookie(internal_response, http_args, context)

        del context.state[self.name]
        return make_saml_response(resp_args["binding"], http_args)
コード例 #4
0
ファイル: saml2.py プロジェクト: misi/SATOSA
    def _handle_authn_response(self, context, internal_response, idp):
        """
        See super class satosa.frontends.base.FrontendModule

        :type context: satosa.context.Context
        :type internal_response: satosa.internal.InternalData
        :type idp: saml.server.Server

        :param context: The current context
        :param internal_response: The internal response
        :param idp: The saml frontend idp server
        :return: A saml response
        """
        request_state = self.load_state(context.state)

        resp_args = request_state["resp_args"]
        sp_entity_id = resp_args["sp_entity_id"]
        internal_response.attributes = self._filter_attributes(
            idp, internal_response, context)
        ava = self.converter.from_internal(self.attribute_profile,
                                           internal_response.attributes)

        auth_info = {}
        if self.acr_mapping:
            auth_info["class_ref"] = self.acr_mapping.get(
                internal_response.auth_info.issuer, self.acr_mapping[""])
        else:
            auth_info["class_ref"] = internal_response.auth_info.auth_class_ref

        auth_info["authn_auth"] = internal_response.auth_info.issuer

        if self.custom_attribute_release:
            custom_release = util.get_dict_defaults(
                self.custom_attribute_release,
                internal_response.auth_info.issuer, sp_entity_id)
            attributes_to_remove = custom_release.get("exclude", [])
            for k in attributes_to_remove:
                ava.pop(k, None)

        nameid_value = internal_response.subject_id
        nameid_format = subject_type_to_saml_nameid_format(
            internal_response.subject_type)

        # If the backend did not receive a SAML <NameID> and so
        # name_id is set to None then do not create a NameID instance.
        # Instead pass None as the name name_id to the IdP server
        # instance and it will use its configured policy to construct
        # a <NameID>, with the default to create a transient <NameID>.
        name_id = None if not nameid_value else NameID(
            text=nameid_value,
            format=nameid_format,
            sp_name_qualifier=None,
            name_qualifier=None,
        )

        dbgmsg = "returning attributes %s" % json.dumps(ava)
        satosa_logging(logger, logging.DEBUG, dbgmsg, context.state)

        policies = self.idp_config.get('service',
                                       {}).get('idp', {}).get('policy', {})
        sp_policy = policies.get('default', {})
        sp_policy.update(policies.get(sp_entity_id, {}))

        sign_assertion = sp_policy.get('sign_assertion', False)
        sign_response = sp_policy.get('sign_response', True)
        sign_alg = sp_policy.get('sign_alg', 'SIG_RSA_SHA256')
        digest_alg = sp_policy.get('digest_alg', 'DIGEST_SHA256')

        # Construct arguments for method create_authn_response
        # on IdP Server instance
        args = {
            'identity': ava,
            'name_id': name_id,
            'authn': auth_info,
            'sign_response': sign_response,
            'sign_assertion': sign_assertion,
        }

        # Add the SP details
        args.update(**resp_args)

        try:
            args['sign_alg'] = getattr(xmldsig, sign_alg)
        except AttributeError as e:
            errmsg = "Unsupported sign algorithm %s" % sign_alg
            satosa_logging(logger, logging.ERROR, errmsg, context.state)
            raise Exception(errmsg) from e
        else:
            dbgmsg = "signing with algorithm %s" % args['sign_alg']
            satosa_logging(logger, logging.DEBUG, dbgmsg, context.state)

        try:
            args['digest_alg'] = getattr(xmldsig, digest_alg)
        except AttributeError as e:
            errmsg = "Unsupported digest algorithm %s" % digest_alg
            satosa_logging(logger, logging.ERROR, errmsg, context.state)
            raise Exception(errmsg) from e
        else:
            dbgmsg = "using digest algorithm %s" % args['digest_alg']
            satosa_logging(logger, logging.DEBUG, dbgmsg, context.state)

        resp = idp.create_authn_response(**args)
        http_args = idp.apply_binding(resp_args["binding"],
                                      str(resp),
                                      resp_args["destination"],
                                      request_state["relay_state"],
                                      response=True)

        # Set the common domain cookie _saml_idp if so configured.
        if self.config.get('common_domain_cookie'):
            self._set_common_domain_cookie(internal_response, http_args,
                                           context)

        del context.state[self.name]
        return make_saml_response(resp_args["binding"], http_args)
コード例 #5
0
ファイル: saml2.py プロジェクト: SUNET/SATOSA
    def _handle_authn_response(self, context, internal_response, idp):
        """
        See super class satosa.frontends.base.FrontendModule

        :type context: satosa.context.Context
        :type internal_response: satosa.internal.InternalData
        :type idp: saml.server.Server

        :param context: The current context
        :param internal_response: The internal response
        :param idp: The saml frontend idp server
        :return: A saml response
        """
        request_state = self.load_state(context.state)

        resp_args = request_state["resp_args"]
        sp_entity_id = resp_args["sp_entity_id"]
        internal_response.attributes = self._filter_attributes(
            idp, internal_response, context)
        ava = self.converter.from_internal(
            self.attribute_profile, internal_response.attributes)

        auth_info = {}
        if self.acr_mapping:
            auth_info["class_ref"] = self.acr_mapping.get(
                internal_response.auth_info.issuer, self.acr_mapping[""])
        else:
            auth_info["class_ref"] = internal_response.auth_info.auth_class_ref

        auth_info["authn_auth"] = internal_response.auth_info.issuer

        if self.custom_attribute_release:
            custom_release = util.get_dict_defaults(
                self.custom_attribute_release,
                internal_response.auth_info.issuer,
                sp_entity_id)
            attributes_to_remove = custom_release.get("exclude", [])
            for k in attributes_to_remove:
                ava.pop(k, None)

        nameid_value = internal_response.subject_id
        nameid_format = subject_type_to_saml_nameid_format(
            internal_response.subject_type
        )

        # If the backend did not receive a SAML <NameID> and so
        # name_id is set to None then do not create a NameID instance.
        # Instead pass None as the name name_id to the IdP server
        # instance and it will use its configured policy to construct
        # a <NameID>, with the default to create a transient <NameID>.
        name_id = None if not nameid_value else NameID(
            text=nameid_value,
            format=nameid_format,
            sp_name_qualifier=None,
            name_qualifier=None,
        )

        dbgmsg = "returning attributes %s" % json.dumps(ava)
        satosa_logging(logger, logging.DEBUG, dbgmsg, context.state)

        policies = self.idp_config.get(
            'service', {}).get('idp', {}).get('policy', {})
        sp_policy = policies.get('default', {})
        sp_policy.update(policies.get(sp_entity_id, {}))

        sign_assertion = sp_policy.get('sign_assertion', False)
        sign_response = sp_policy.get('sign_response', True)
        sign_alg = sp_policy.get('sign_alg', 'SIG_RSA_SHA256')
        digest_alg = sp_policy.get('digest_alg', 'DIGEST_SHA256')

        # Construct arguments for method create_authn_response
        # on IdP Server instance
        args = {
            'identity'      : ava,
            'name_id'       : name_id,
            'authn'         : auth_info,
            'sign_response' : sign_response,
            'sign_assertion': sign_assertion,
        }

        # Add the SP details
        args.update(**resp_args)

        try:
            args['sign_alg'] = getattr(xmldsig, sign_alg)
        except AttributeError as e:
            errmsg = "Unsupported sign algorithm %s" % sign_alg
            satosa_logging(logger, logging.ERROR, errmsg, context.state)
            raise Exception(errmsg) from e
        else:
            dbgmsg = "signing with algorithm %s" % args['sign_alg']
            satosa_logging(logger, logging.DEBUG, dbgmsg, context.state)

        try:
            args['digest_alg'] = getattr(xmldsig, digest_alg)
        except AttributeError as e:
            errmsg = "Unsupported digest algorithm %s" % digest_alg
            satosa_logging(logger, logging.ERROR, errmsg, context.state)
            raise Exception(errmsg) from e
        else:
            dbgmsg = "using digest algorithm %s" % args['digest_alg']
            satosa_logging(logger, logging.DEBUG, dbgmsg, context.state)

        resp = idp.create_authn_response(**args)
        http_args = idp.apply_binding(
            resp_args["binding"], str(resp), resp_args["destination"],
            request_state["relay_state"], response=True)

        # Set the common domain cookie _saml_idp if so configured.
        if self.config.get('common_domain_cookie'):
            self._set_common_domain_cookie(internal_response, http_args, context)

        del context.state[self.name]
        return make_saml_response(resp_args["binding"], http_args)