예제 #1
0
 def get_metadata(self):
     """Returns SAML Identity Provider Metadata"""
     edesc = entity_descriptor(self._config, 24)
     if self._config.key_file:
         edesc = sign_entity_descriptor(edesc, 24, None, security_context(self._config))
     response = make_response(str(edesc))
     response.headers['Content-type'] = 'text/xml; charset=utf-8'
     return response
예제 #2
0
    def _metadata_endpoint(self, context):
        """
        Endpoint for retrieving the backend metadata
        :type context: satosa.context.Context
        :rtype: satosa.response.Response

        :param context: The current context
        :return: response with metadata
        """
        logger.debug("Sending metadata response")
        conf = self.sp.config

        metadata = entity_descriptor(conf)
        # creare gli attribute_consuming_service
        cnt = 0
        for (attribute_consuming_service
             ) in metadata.spsso_descriptor.attribute_consuming_service:
            attribute_consuming_service.index = str(cnt)
            cnt += 1

        cnt = 0
        for (assertion_consumer_service
             ) in metadata.spsso_descriptor.assertion_consumer_service:
            assertion_consumer_service.is_default = "true" if not cnt else ""
            assertion_consumer_service.index = str(cnt)
            cnt += 1

        # nameformat patch... tutto questo non rispecchia gli standard OASIS
        for reqattr in metadata.spsso_descriptor.attribute_consuming_service[
                0].requested_attribute:
            reqattr.name_format = None
            reqattr.friendly_name = None

        # attribute consuming service service name patch
        service_name = metadata.spsso_descriptor.attribute_consuming_service[
            0].service_name[0]
        service_name.lang = "it"
        service_name.text = metadata.entity_id

        # remove extension disco and uuinfo (spid-testenv2)
        # metadata.spsso_descriptor.extensions = []

        # load ContactPerson Extensions
        self._metadata_contact_person(metadata, conf)

        # metadata signature
        secc = security_context(conf)
        #
        sign_dig_algs = self.get_kwargs_sign_dig_algs()
        eid, xmldoc = sign_entity_descriptor(metadata, None, secc,
                                             **sign_dig_algs)

        valid_instance(eid)
        return Response(text_type(xmldoc).encode("utf-8"),
                        content="text/xml; charset=utf8")
예제 #3
0
def italian_sp_metadata(conf, md_type: str = "spid"):
    metadata = entity_descriptor(conf)

    # this will renumber acs starting from 0 and set index=0 as is_default
    cnt = 0
    for (attribute_consuming_service
         ) in metadata.spsso_descriptor.attribute_consuming_service:
        attribute_consuming_service.index = str(cnt)
        cnt += 1

    cnt = 0
    for (assertion_consumer_service
         ) in metadata.spsso_descriptor.assertion_consumer_service:
        assertion_consumer_service.is_default = "true" if not cnt else ""
        assertion_consumer_service.index = str(cnt)
        cnt += 1

    # nameformat patch
    for reqattr in metadata.spsso_descriptor.attribute_consuming_service[
            0].requested_attribute:
        reqattr.name_format = (
            None  # "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
        )
        reqattr.friendly_name = None

    metadata.extensions = None

    # attribute consuming service service name patch
    service_name = metadata.spsso_descriptor.attribute_consuming_service[
        0].service_name[0]
    service_name.lang = "it"
    service_name.text = conf._sp_name

    if md_type == 'spid':
        spid_contacts_29_v3(metadata)
    elif md_type == 'cie':
        cie_contacts(metadata)

    # metadata signature
    secc = security_context(conf)
    sign_dig_algs = dict(sign_alg=conf._sp_signing_algorithm,
                         digest_alg=conf._sp_digest_algorithm)
    eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs)
    return xmldoc
예제 #4
0
def _make_metadata(config_dict, option):
    """
    Creates metadata from the given idp config

    :type config_dict: dict[str, Any]
    :type option: vopaas.metadata_creation.make_vopaas_metadata.MetadataOption
    :rtype: str

    :param config_dict: config
    :param option: metadata creation settings
    :return: A xml string
    """
    eds = []
    cnf = Config()
    cnf.load(copy.deepcopy(config_dict), metadata_construction=True)

    if option.valid:
        cnf.valid_for = option.valid
    eds.append(entity_descriptor(cnf))

    conf = Config()
    conf.key_file = option.keyfile
    conf.cert_file = option.cert
    conf.debug = 1
    conf.xmlsec_binary = option.xmlsec
    secc = security_context(conf)

    if option.id:
        desc, xmldoc = entities_descriptor(eds, option.valid, option.name, option.id,
                                           option.sign, secc)
        valid_instance(desc)
        print(desc.to_string(NSPAIR))
    else:
        for eid in eds:
            if option.sign:
                assert conf.key_file
                assert conf.cert_file
                eid, xmldoc = sign_entity_descriptor(eid, option.id, secc)
            else:
                xmldoc = None

            valid_instance(eid)
            xmldoc = metadata_tostring_fix(eid, NSPAIR, xmldoc).decode()
            return xmldoc
예제 #5
0
def create_metadata_string(configfile,
                           config=None,
                           valid=None,
                           cert=None,
                           keyfile=None,
                           mid=None,
                           name=None,
                           sign=None):
    """
    TODO: REMOVE THIS FUNCTION AFTER pysaml2 library is updated. to fix the above metadata_tostring_fix function
    """
    valid_for = 0
    nspair = {"xs": "http://www.w3.org/2001/XMLSchema"}
    # paths = [".", "/opt/local/bin"]

    if valid:
        valid_for = int(valid)  # Hours

    eds = []
    if config is None:
        if configfile.endswith(".py"):
            configfile = configfile[:-3]
        config = Config().load_file(configfile, metadata_construction=True)
    eds.append(entity_descriptor(config))

    conf = Config()
    conf.key_file = config.key_file or keyfile
    conf.cert_file = config.cert_file or cert
    conf.debug = 1
    conf.xmlsec_binary = config.xmlsec_binary
    secc = security_context(conf)

    if mid:
        eid, xmldoc = entities_descriptor(eds, valid_for, name, mid, sign,
                                          secc)
    else:
        eid = eds[0]
        if sign:
            eid, xmldoc = sign_entity_descriptor(eid, mid, secc)
        else:
            xmldoc = None

    valid_instance(eid)
    return metadata_tostring_fix(eid, nspair, xmldoc)
예제 #6
0
def _make_metadata(config_dict, option):
    """
    Creates metadata from the given idp config

    :type config_dict: dict[str, Any]
    :type option: vopaas.metadata_creation.make_vopaas_metadata.MetadataOption
    :rtype: str

    :param config_dict: config
    :param option: metadata creation settings
    :return: A xml string
    """
    eds = []
    cnf = Config()
    cnf.load(copy.deepcopy(config_dict), metadata_construction=True)

    if option.valid:
        cnf.valid_for = option.valid
    eds.append(entity_descriptor(cnf))

    conf = Config()
    conf.key_file = option.keyfile
    conf.cert_file = option.cert
    conf.debug = 1
    conf.xmlsec_binary = option.xmlsec
    secc = security_context(conf)

    if option.id:
        desc, xmldoc = entities_descriptor(eds, option.valid, option.name, option.id, option.sign, secc)
        valid_instance(desc)
        print(desc.to_string(NSPAIR))
    else:
        for eid in eds:
            if option.sign:
                assert conf.key_file
                assert conf.cert_file
                eid, xmldoc = sign_entity_descriptor(eid, option.id, secc)
            else:
                xmldoc = None

            valid_instance(eid)
            xmldoc = metadata_tostring_fix(eid, NSPAIR, xmldoc).decode()
            return xmldoc
예제 #7
0
def create_signed_entity_descriptor(entity_descriptor, security_context, valid_for=None):
    """
    :param entity_descriptor: the entity descriptor to sign
    :param security_context: security context for the signature
    :param valid_for: number of hours the metadata should be valid
    :return: the signed XML document

    :type entity_descriptor: saml2.md.EntityDescriptor]
    :type security_context: saml2.sigver.SecurityContext
    :type valid_for: Optional[int]
    """
    if valid_for:
        entity_descriptor.valid_until = in_a_while(hours=valid_for)

    entity_desc, xmldoc = sign_entity_descriptor(entity_descriptor, None, security_context)

    if not valid_instance(entity_desc):
        raise ValueError("Could not construct valid EntityDescriptor tag")

    return xmldoc
예제 #8
0
def create_metadata_string(configfile,
                           config=None,
                           valid=None,
                           cert=None,
                           keyfile=None,
                           mid=None,
                           name=None,
                           sign=None):
    valid_for = 0
    nspair = {"xs": "http://www.w3.org/2001/XMLSchema"}

    if valid:
        valid_for = int(valid)  # Hours

    eds = []
    if config is None:
        if configfile.endswith(".py"):
            configfile = configfile[:-3]
        config = Config().load_file(configfile, metadata_construction=True)
    eds.append(entity_descriptor(config))

    conf = Config()
    conf.key_file = config.key_file or keyfile
    conf.cert_file = config.cert_file or cert
    conf.debug = 1
    conf.xmlsec_binary = config.xmlsec_binary
    secc = security_context(conf)

    if mid:
        eid, xmldoc = entities_descriptor(eds, valid_for, name, mid, sign,
                                          secc)
    else:
        eid = eds[0]
        if sign:
            eid, xmldoc = sign_entity_descriptor(eid, mid, secc)
        else:
            xmldoc = None

    valid_instance(eid)
    return metadata_tostring_fix(eid, nspair, xmldoc)
예제 #9
0
def spid_sp_metadata(conf):
    metadata = entity_descriptor(conf)

    # this will renumber acs starting from 0 and set index=0 as is_default
    cnt = 0
    for attribute_consuming_service in metadata.spsso_descriptor.attribute_consuming_service:
        attribute_consuming_service.index = str(cnt)
        cnt += 1

    cnt = 0
    for assertion_consumer_service in metadata.spsso_descriptor.assertion_consumer_service:
        assertion_consumer_service.is_default = 'true' if not cnt else ''
        assertion_consumer_service.index = str(cnt)
        cnt += 1

    # nameformat patch
    for reqattr in metadata.spsso_descriptor.attribute_consuming_service[0].requested_attribute:
        reqattr.name_format = None  # "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
        reqattr.friendly_name = None

    metadata.extensions = None

    # attribute consuming service service name patch
    service_name = metadata.spsso_descriptor.attribute_consuming_service[0].service_name[0]
    service_name.lang = 'it'
    service_name.text = conf._sp_name

    avviso_29_v3(metadata)

    # metadata signature
    secc = security_context(conf)
    sign_dig_algs = dict(
        sign_alg=conf._sp_signing_algorithm,
        digest_alg=conf._sp_digest_algorithm
    )
    eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs)
    return xmldoc
예제 #10
0
    cnf = Config().load_file(fil, metadata_construction=True)
    if valid_for:
        cnf.valid_for = valid_for
    eds.append(entity_descriptor(cnf))

conf = Config()
conf.key_file = args.keyfile
conf.cert_file = args.cert
conf.debug = 1
conf.xmlsec_binary = args.xmlsec
secc = security_context(conf)

if args.id:
    desc, xmldoc = entities_descriptor(eds, valid_for, args.name, args.id,
                                       args.sign, secc)
    valid_instance(desc)
    xmldoc = metadata_tostring_fix(desc, nspair, xmldoc)
    print(xmldoc.decode("utf-8"))
else:
    for eid in eds:
        if args.sign:
            assert conf.key_file
            assert conf.cert_file
            eid, xmldoc = sign_entity_descriptor(eid, args.id, secc)
        else:
            xmldoc = None

        valid_instance(eid)
        xmldoc = metadata_tostring_fix(eid, nspair, xmldoc)
        print(xmldoc.decode("utf-8"))
예제 #11
0
    valid_for = int(args.valid) * 24
if args.xmlsec:
    xmlsec = args.xmlsec
else:
    xmlsec = get_xmlsec_binary(paths)

eds = []
for filespec in args.config:
    bas, fil = os.path.split(filespec)
    if bas != "":
        sys.path.insert(0, bas)
    if fil.endswith(".py"):
        fil = fil[:-3]
    cnf = Config().load_file(fil, metadata_construction=True)
    eds.append(entity_descriptor(cnf))

secc = SecurityContext(xmlsec, args.keyfile, cert_file=args.cert)
if args.id:
    desc = entities_descriptor(eds, valid_for, args.name, args.id, args.sign,
                               secc)
    valid_instance(desc)
    print desc.to_string(nspair)
else:
    for eid in eds:
        if args.sign:
            desc = sign_entity_descriptor(eid, id, secc)
        else:
            desc = eid
        valid_instance(desc)
        print desc.to_string(nspair)
예제 #12
0
if args.xmlsec:
    xmlsec = args.xmlsec
else:
    xmlsec = get_xmlsec_binary(paths)

eds = []
for filespec in args.config:
    bas, fil = os.path.split(filespec)
    if bas != "":
        sys.path.insert(0, bas)
    if fil.endswith(".py"):
        fil = fil[:-3]
    cnf = Config().load_file(fil, metadata_construction=True)
    eds.append(entity_descriptor(cnf))

secc = SecurityContext(xmlsec, args.keyfile, cert_file=args.cert)
if args.id:
    desc = entities_descriptor(eds, valid_for, args.name, args.id,
                               args.sign, secc)
    valid_instance(desc)
    print desc.to_string(nspair)
else:
    for eid in eds:
        if args.sign:
            desc = sign_entity_descriptor(eid, id, secc)
        else:
            desc = eid
        valid_instance(desc)
        print desc.to_string(nspair)

예제 #13
0
    cnf = Config().load_file(fil, metadata_construction=True)
    if valid_for:
        cnf.valid_for = valid_for
    eds.append(entity_descriptor(cnf))

conf = Config()
conf.key_file = args.keyfile
conf.cert_file = args.cert
conf.debug = 1
conf.xmlsec_binary = args.xmlsec
secc = security_context(conf)

if args.id:
    desc, xmldoc = entities_descriptor(eds, valid_for, args.name, args.id,
                                       args.sign, secc)
    valid_instance(desc)
    xmldoc = metadata_tostring_fix(desc, nspair, xmldoc)
    print(xmldoc.decode("utf-8"))
else:
    for eid in eds:
        if args.sign:
            assert conf.key_file
            assert conf.cert_file
            eid, xmldoc = sign_entity_descriptor(eid, args.id, secc)
        else:
            xmldoc = None

        valid_instance(eid)
        xmldoc = metadata_tostring_fix(eid, nspair, xmldoc)
        print(xmldoc.decode("utf-8"))
예제 #14
0
def spid_sp_metadata(conf):
    metadata = entity_descriptor(conf)

    # this will renumber acs starting from 0 and set index=0 as is_default
    cnt = 0
    for attribute_consuming_service in metadata.spsso_descriptor.attribute_consuming_service:
        attribute_consuming_service.index = str(cnt)
        cnt += 1

    cnt = 0
    for assertion_consumer_service in metadata.spsso_descriptor.assertion_consumer_service:
        assertion_consumer_service.is_default = 'true' if not cnt else ''
        assertion_consumer_service.index = str(cnt)
        cnt += 1

    # nameformat patch... non proprio standard
    for reqattr in metadata.spsso_descriptor.attribute_consuming_service[
            0].requested_attribute:
        reqattr.name_format = None  #"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
        # reqattr.is_required = None
        reqattr.friendly_name = None

    # remove unecessary encryption and digest algs
    # supported_algs = ['http://www.w3.org/2009/xmldsig11#dsa-sha256',
    #                   'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256']
    # new_list = []
    # for alg in metadata.extensions.extension_elements:
    # if alg.attributes.get('Algorithm') in supported_algs:
    # new_list.append(alg)
    # metadata.extensions.extension_elements = new_list

    # ... Piuttosto non devo specificare gli algoritmi di firma/criptazione...
    metadata.extensions = None

    # attribute consuming service service name patch
    service_name = metadata.spsso_descriptor.attribute_consuming_service[
        0].service_name[0]
    service_name.lang = 'it'
    service_name.text = conf._sp_name

    ##############
    # avviso 29 v3
    #
    # https://www.agid.gov.it/sites/default/files/repository_files/spid-avviso-n29v3-specifiche_sp_pubblici_e_privati_0.pdf
    saml2.md.SamlBase.register_prefix(settings.SPID_PREFIXES)

    contact_map = settings.SPID_CONTACTS
    cnt = 0
    metadata.contact_person = []
    for contact in contact_map:
        spid_contact = saml2.md.ContactPerson()
        spid_contact.contact_type = contact['contact_type']
        contact_kwargs = {
            'email_address': [contact['email_address']],
            'telephone_number': [contact['telephone_number']]
        }
        if contact['contact_type'] == 'other':
            spid_contact.loadd(contact_kwargs)
            contact_kwargs['contact_type'] = contact['contact_type']
            spid_extensions = saml2.ExtensionElement(
                'Extensions', namespace='urn:oasis:names:tc:SAML:2.0:metadata')
            for k, v in contact.items():
                if k in contact_kwargs: continue
                ext = saml2.ExtensionElement(
                    k, namespace=settings.SPID_PREFIXES['spid'], text=v)
                spid_extensions.children.append(ext)

        elif contact['contact_type'] == 'billing':
            contact_kwargs['company'] = contact['company']
            spid_contact.loadd(contact_kwargs)
            spid_extensions = saml2.ExtensionElement(
                'Extensions', namespace='urn:oasis:names:tc:SAML:2.0:metadata')

            elements = {}
            for k, v in contact.items():
                if k in contact_kwargs: continue
                ext = saml2.ExtensionElement(
                    k, namespace=settings.SPID_PREFIXES['fpa'], text=v)
                elements[k] = ext

            # DatiAnagrafici
            IdFiscaleIVA = saml2.ExtensionElement(
                'IdFiscaleIVA',
                namespace=settings.SPID_PREFIXES['fpa'],
            )
            Anagrafica = saml2.ExtensionElement(
                'Anagrafica',
                namespace=settings.SPID_PREFIXES['fpa'],
            )
            Anagrafica.children.append(elements['Denominazione'])

            IdFiscaleIVA.children.append(elements['IdPaese'])
            IdFiscaleIVA.children.append(elements['IdCodice'])
            DatiAnagrafici = saml2.ExtensionElement(
                'DatiAnagrafici',
                namespace=settings.SPID_PREFIXES['fpa'],
            )
            if elements.get('CodiceFiscale'):
                DatiAnagrafici.children.append(elements['CodiceFiscale'])
            DatiAnagrafici.children.append(IdFiscaleIVA)
            DatiAnagrafici.children.append(Anagrafica)
            CessionarioCommittente = saml2.ExtensionElement(
                'CessionarioCommittente',
                namespace=settings.SPID_PREFIXES['fpa'],
            )
            CessionarioCommittente.children.append(DatiAnagrafici)

            # Sede
            Sede = saml2.ExtensionElement(
                'Sede',
                namespace=settings.SPID_PREFIXES['fpa'],
            )
            Sede.children.append(elements['Indirizzo'])
            Sede.children.append(elements['NumeroCivico'])
            Sede.children.append(elements['CAP'])
            Sede.children.append(elements['Comune'])
            Sede.children.append(elements['Provincia'])
            Sede.children.append(elements['Nazione'])
            CessionarioCommittente.children.append(Sede)

            spid_extensions.children.append(CessionarioCommittente)

        spid_contact.extensions = spid_extensions
        metadata.contact_person.append(spid_contact)
        cnt += 1
    #
    # fine avviso 29v3
    ###################

    # metadata signature
    secc = security_context(conf)
    sign_dig_algs = dict(sign_alg=conf._sp_signing_algorithm,
                         digest_alg=conf._sp_digest_algorithm)
    eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs)
    return xmldoc
예제 #15
0
        xmlsec = get_xmlsec_binary(path)
        
    eds = []
    for filespec in args:
        bas, fil = os.path.split(filespec)
        if bas != "":
            sys.path.insert(0, bas)
        if fil.endswith(".py"):
            fil = fil[:-3]
        cnf = Config().load_file(fil, metadata_construction=True)
        eds.append(entity_descriptor(cnf, valid_for))

    secc = SecurityContext(xmlsec, keyfile, cert_file=pubkeyfile)
    if entitiesid:
        desc = entities_descriptor(eds, valid_for, name, id, sign, secc)
        valid_instance(desc)
        print desc.to_string(nspair)
    else:
        for eid in eds:
            if sign:
                desc = sign_entity_descriptor(eid, valid_for, id, secc)
            else:
                desc = eid
            valid_instance(desc)
            print desc.to_string(nspair)

if __name__ == "__main__":
    import sys
    
    main(sys.argv[1:])
예제 #16
0
    def _metadata_endpoint(self, context):
        """
        Endpoint for retrieving the backend metadata
        :type context: satosa.context.Context
        :rtype: satosa.response.Response

        :param context: The current context
        :return: response with metadata
        """
        logger.debug("Sending metadata response")
        conf = self.sp.config

        metadata = entity_descriptor(conf)
        # creare gli attribute_consuming_service
        cnt = 0
        for attribute_consuming_service in metadata.spsso_descriptor.attribute_consuming_service:
            attribute_consuming_service.index = str(cnt)
            cnt += 1

        cnt = 0
        for assertion_consumer_service in metadata.spsso_descriptor.assertion_consumer_service:
            assertion_consumer_service.is_default = 'true' if not cnt else ''
            assertion_consumer_service.index = str(cnt)
            cnt += 1

        # nameformat patch... tutto questo non rispecchia gli standard OASIS
        for reqattr in metadata.spsso_descriptor.attribute_consuming_service[
                0].requested_attribute:
            reqattr.name_format = None
            reqattr.friendly_name = None

        # attribute consuming service service name patch
        service_name = metadata.spsso_descriptor.attribute_consuming_service[
            0].service_name[0]
        service_name.lang = 'it'
        service_name.text = metadata.entity_id

        # remove extension disco and uuinfo (spid-testenv2)
        #metadata.spsso_descriptor.extensions = []

        ##############
        # avviso 29 v3
        #
        # https://www.agid.gov.it/sites/default/files/repository_files/spid-avviso-n29v3-specifiche_sp_pubblici_e_privati_0.pdf
        # Avviso 29v3
        SPID_PREFIXES = dict(spid="https://spid.gov.it/saml-extensions",
                             fpa="https://spid.gov.it/invoicing-extensions")
        saml2.md.SamlBase.register_prefix(SPID_PREFIXES)
        metadata.contact_person = []
        contact_map = conf.contact_person
        cnt = 0
        metadata.contact_person = []
        for contact in contact_map:
            spid_contact = saml2.md.ContactPerson()
            spid_contact.contact_type = contact['contact_type']
            contact_kwargs = {
                'email_address': [contact['email_address']],
                'telephone_number': [contact['telephone_number']]
            }
            if contact['contact_type'] == 'other':
                spid_contact.loadd(contact_kwargs)
                contact_kwargs['contact_type'] = contact['contact_type']
                spid_extensions = saml2.ExtensionElement(
                    'Extensions',
                    namespace='urn:oasis:names:tc:SAML:2.0:metadata')
                for k, v in contact.items():
                    if k in contact_kwargs: continue
                    ext = saml2.ExtensionElement(
                        k, namespace=SPID_PREFIXES['spid'], text=v)
                    spid_extensions.children.append(ext)

            elif contact['contact_type'] == 'billing':
                contact_kwargs['company'] = contact['company']
                spid_contact.loadd(contact_kwargs)
                spid_extensions = saml2.ExtensionElement(
                    'Extensions',
                    namespace='urn:oasis:names:tc:SAML:2.0:metadata')

                elements = {}
                for k, v in contact.items():
                    if k in contact_kwargs: continue
                    ext = saml2.ExtensionElement(
                        k, namespace=SPID_PREFIXES['fpa'], text=v)
                    elements[k] = ext

                # DatiAnagrafici
                IdFiscaleIVA = saml2.ExtensionElement(
                    'IdFiscaleIVA',
                    namespace=SPID_PREFIXES['fpa'],
                )
                Anagrafica = saml2.ExtensionElement(
                    'Anagrafica',
                    namespace=SPID_PREFIXES['fpa'],
                )
                Anagrafica.children.append(elements['Denominazione'])

                IdFiscaleIVA.children.append(elements['IdPaese'])
                IdFiscaleIVA.children.append(elements['IdCodice'])
                DatiAnagrafici = saml2.ExtensionElement(
                    'DatiAnagrafici',
                    namespace=SPID_PREFIXES['fpa'],
                )
                if elements.get('CodiceFiscale'):
                    DatiAnagrafici.children.append(elements['CodiceFiscale'])
                DatiAnagrafici.children.append(IdFiscaleIVA)
                DatiAnagrafici.children.append(Anagrafica)
                CessionarioCommittente = saml2.ExtensionElement(
                    'CessionarioCommittente',
                    namespace=SPID_PREFIXES['fpa'],
                )
                CessionarioCommittente.children.append(DatiAnagrafici)

                # Sede
                Sede = saml2.ExtensionElement(
                    'Sede',
                    namespace=SPID_PREFIXES['fpa'],
                )
                Sede.children.append(elements['Indirizzo'])
                Sede.children.append(elements['NumeroCivico'])
                Sede.children.append(elements['CAP'])
                Sede.children.append(elements['Comune'])
                Sede.children.append(elements['Provincia'])
                Sede.children.append(elements['Nazione'])
                CessionarioCommittente.children.append(Sede)

                spid_extensions.children.append(CessionarioCommittente)

            spid_contact.extensions = spid_extensions
            metadata.contact_person.append(spid_contact)
            cnt += 1
        #
        # fine avviso 29v3
        ###################

        # metadata signature
        secc = security_context(conf)
        #
        sign_dig_algs = self.get_kwargs_sign_dig_algs()
        eid, xmldoc = sign_entity_descriptor(metadata, None, secc,
                                             **sign_dig_algs)

        valid_instance(eid)
        return Response(text_type(xmldoc).encode('utf-8'),
                        content="text/xml; charset=utf8")