Beispiel #1
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")
Beispiel #2
0
 def handle_authn_response(self, context, internal_resp):
     return Response("Auth response received, passed to test frontend")
Beispiel #3
0
 def start_auth(self, context, internal_request):
     return Response("Auth request received, passed to test backend")
Beispiel #4
0
 def test_constructor_adding_content_type_header(self):
     resp = Response("foo", content="bar")
     headers = dict(resp.headers)
     assert headers["Content-Type"] == "bar"
Beispiel #5
0
 def test_call_should_always_return_flat_list_to_comply_with_wsgi(
         self, data, expected):
     resp = Response(data)
     assert resp({}, lambda x, y: None) == expected
Beispiel #6
0
    def authn_request(self, context, entity_id, internal_req):
        """
        Do an authorization request on idp with given entity id.
        This is the start of the authorization.

        :type context: satosa.context.Context
        :type entity_id: str
        :type internal_req: satosa.internal_data.InternalRequest
        :rtype: satosa.response.Response

        :param context: The curretn context
        :param entity_id: Target IDP entity id
        :param internal_req: The request
        :return: Response
        """
        _cli = self.sp
        hash_type = UserIdHashType.persistent.name
        if "hash_type" in self.config:
            hash_type = self.config["hash_type"]
        req_args = {"name_id_policy": self.create_name_id_policy(hash_type)}

        state = context.state

        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)
            satosa_logging(
                LOGGER, logging.DEBUG,
                "binding: %s, destination: %s" % (_binding, destination),
                state)
            # 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,
                                                    **req_args)
            relay_state = rndstr()
            ht_args = _cli.apply_binding(_binding,
                                         "%s" % req,
                                         destination,
                                         relay_state=relay_state)
            satosa_logging(LOGGER, logging.DEBUG, "ht_args: %s" % ht_args,
                           state)
        except Exception as exc:
            satosa_logging(LOGGER,
                           logging.DEBUG,
                           "Failed to construct the AuthnRequest for state",
                           state,
                           exc_info=True)
            raise SATOSAAuthenticationError(
                state, "Failed to construct the AuthnRequest") from exc

        state.add(self.state_id, relay_state)

        if _binding == BINDING_HTTP_REDIRECT:
            for param, value in ht_args["headers"]:
                if param == "Location":
                    resp = SeeOther(str(value))
                    break
            else:
                satosa_logging(LOGGER, logging.DEBUG,
                               "Parameter error for state", state)
                raise SATOSAAuthenticationError(state, "Parameter error")
        else:
            resp = Response(ht_args["data"], headers=ht_args["headers"])

        return resp