コード例 #1
0
ファイル: test_50_server.py プロジェクト: jkakavas/pysaml2
    def test_slo_soap(self):
        soon = time_util.in_a_while(days=1)
        sinfo = {
            "name_id": nid,
            "issuer": "urn:mace:example.com:saml:roland:idp",
            "not_on_or_after": soon,
            "user": {
                "givenName": "Leo",
                "sn": "Laport",
            }
        }

        sp = client.Saml2Client(config_file="server_conf")
        sp.users.add_information_about_person(sinfo)

        req_id, logout_request = sp.create_logout_request(
            name_id=nid, destination="http://localhost:8088/slo",
            issuer_entity_id="urn:mace:example.com:saml:roland:idp",
            reason="I'm tired of this")

        #_ = s_utils.deflate_and_base64_encode("%s" % (logout_request,))

        saml_soap = make_soap_enveloped_saml_thingy(logout_request)
        self.server.ident.close()

        with closing(Server("idp_soap_conf")) as idp:
            request = idp.parse_logout_request(saml_soap)
            idp.ident.close()
            assert request
コード例 #2
0
ファイル: client_base.py プロジェクト: peopledoc/pysaml2
    def create_ecp_authn_request(self, entityid=None, relay_state="",
                                 sign=False, **kwargs):
        """ Makes an authentication request.

        :param entityid: The entity ID of the IdP to send the request to
        :param relay_state: A token that can be used by the SP to know
            where to continue the conversation with the client
        :param sign: Whether the request should be signed or not.
        :return: SOAP message with the AuthnRequest
        """

        # ----------------------------------------
        # <paos:Request>
        # ----------------------------------------
        my_url = self.service_urls(BINDING_PAOS)[0]

        # must_understand and act according to the standard
        #
        paos_request = paos.Request(must_understand="1", actor=ACTOR,
                                    response_consumer_url=my_url,
                                    service=ECP_SERVICE)

        # ----------------------------------------
        # <ecp:RelayState>
        # ----------------------------------------

        relay_state = ecp.RelayState(actor=ACTOR, must_understand="1",
                                     text=relay_state)

        # ----------------------------------------
        # <samlp:AuthnRequest>
        # ----------------------------------------

        try:
            authn_req = kwargs["authn_req"]
        except KeyError:
            try:
                _binding = kwargs["binding"]
            except KeyError:
                _binding = BINDING_SOAP
                kwargs["binding"] = _binding

            logger.debug("entityid: %s, binding: %s" % (entityid, _binding))

            # The IDP publishes support for ECP by using the SOAP binding on
            # SingleSignOnService
            _, location = self.pick_binding("single_sign_on_service",
                                            [_binding], entity_id=entityid)
            authn_req = self.create_authn_request(
                location, service_url_binding=BINDING_PAOS, **kwargs)

        # ----------------------------------------
        # The SOAP envelope
        # ----------------------------------------

        soap_envelope = make_soap_enveloped_saml_thingy(authn_req,
                                                        [paos_request,
                                                         relay_state])

        return authn_req.id, "%s" % soap_envelope
コード例 #3
0
    def test_slo_soap(self):
        soon = time_util.in_a_while(days=1)
        sinfo = {
            "name_id": nid,
            "issuer": "urn:mace:example.com:saml:roland:idp",
            "not_on_or_after": soon,
            "user": {
                "givenName": "Leo",
                "surName": "Laport",
            }
        }

        sp = client.Saml2Client(config_file="server_conf")
        sp.users.add_information_about_person(sinfo)

        req_id, logout_request = sp.create_logout_request(
            name_id=nid,
            destination="http://localhost:8088/slo",
            issuer_entity_id="urn:mace:example.com:saml:roland:idp",
            reason="I'm tired of this")

        #_ = s_utils.deflate_and_base64_encode("%s" % (logout_request,))

        saml_soap = make_soap_enveloped_saml_thingy(logout_request)
        self.server.ident.close()

        with closing(Server("idp_soap_conf")) as idp:
            request = idp.parse_logout_request(saml_soap)
            idp.ident.close()
            assert request
コード例 #4
0
    def attribute_query_endpoint(self, xml_str, binding):
        if binding == BINDING_SOAP:
            _str = parse_soap_enveloped_saml_attribute_query(xml_str)
        else:
            _str = xml_str

        aquery = attribute_query_from_string(_str)
        extra = {"eduPersonAffiliation": "faculty"}
        #userid = "Pavill"

        name_id = aquery.subject.name_id
        attr_resp = self.create_attribute_response(extra, aquery.id,
                                                   None,
                                                   sp_entity_id=aquery.issuer
                                                   .text,
                                                   name_id=name_id,
                                                   attributes=aquery.attribute)

        if binding == BINDING_SOAP:
            # SOAP packing
            #headers = {"content-type": "application/soap+xml"}
            soap_message = make_soap_enveloped_saml_thingy(attr_resp)
            #            if self.sign and self.sec:
            #                _signed = self.sec.sign_statement_using_xmlsec(soap_message,
            #                                                               class_name(attr_resp),
            #                                                               nodeid=attr_resp.id)
            #                soap_message = _signed
            response = "%s" % soap_message
        else:  # Just POST
            response = "%s" % attr_resp

        return DummyResponse(200, response)
コード例 #5
0
    def logout_endpoint(self, xml_str, binding):
        if binding == BINDING_SOAP:
            _str = parse_soap_enveloped_saml_logout_request(xml_str)
        else:
            _str = xml_str

        req = logout_request_from_string(_str)

        _resp = self.create_logout_response(req, [binding])

        if binding == BINDING_SOAP:
            # SOAP packing
            #headers = {"content-type": "application/soap+xml"}
            soap_message = make_soap_enveloped_saml_thingy(_resp)
            #            if self.sign and self.sec:
            #                _signed = self.sec.sign_statement_using_xmlsec(soap_message,
            #                                                               class_name(attr_resp),
            #                                                               nodeid=attr_resp.id)
            #                soap_message = _signed
            response = "%s" % soap_message
        else: # Just POST
            response = "%s" % _resp

        return DummyResponse(200, response)
コード例 #6
0
ファイル: client_base.py プロジェクト: erakli/pysaml2
    def create_ecp_authn_request(self,
                                 entityid=None,
                                 relay_state="",
                                 sign=False,
                                 **kwargs):
        """ Makes an authentication request.

        :param entityid: The entity ID of the IdP to send the request to
        :param relay_state: A token that can be used by the SP to know
            where to continue the conversation with the client
        :param sign: Whether the request should be signed or not.
        :return: SOAP message with the AuthnRequest
        """

        # ----------------------------------------
        # <paos:Request>
        # ----------------------------------------
        my_url = self.service_urls(BINDING_PAOS)[0]

        # must_understand and act according to the standard
        #
        paos_request = paos.Request(must_understand="1",
                                    actor=ACTOR,
                                    response_consumer_url=my_url,
                                    service=ECP_SERVICE)

        # ----------------------------------------
        # <ecp:RelayState>
        # ----------------------------------------

        relay_state = ecp.RelayState(actor=ACTOR,
                                     must_understand="1",
                                     text=relay_state)

        # ----------------------------------------
        # <samlp:AuthnRequest>
        # ----------------------------------------

        try:
            authn_req = kwargs["authn_req"]
            try:
                req_id = authn_req.id
            except AttributeError:
                req_id = 0  # Unknown but since it's SOAP it doesn't matter
        except KeyError:
            try:
                _binding = kwargs["binding"]
            except KeyError:
                _binding = BINDING_SOAP
                kwargs["binding"] = _binding

            logger.debug("entityid: %s, binding: %s", entityid, _binding)

            # The IDP publishes support for ECP by using the SOAP binding on
            # SingleSignOnService
            _, location = self.pick_binding("single_sign_on_service",
                                            [_binding],
                                            entity_id=entityid)
            req_id, authn_req = self.create_authn_request(
                location, service_url_binding=BINDING_PAOS, **kwargs)

        # ----------------------------------------
        # The SOAP envelope
        # ----------------------------------------

        soap_envelope = make_soap_enveloped_saml_thingy(
            authn_req, [paos_request, relay_state])

        return req_id, "%s" % soap_envelope
コード例 #7
0
ファイル: ecp_client.py プロジェクト: GSA/pysaml2
    def ecp_conversation(self, respdict, idp_entity_id=None):
        """  """

        if respdict is None:
            raise Exception("Unexpected reply from the SP")

        self._debug_info("[P1] SP response dict: %s" % respdict)

        # AuthnRequest in the body or not
        authn_request = respdict["body"]
        assert authn_request.c_tag == "AuthnRequest"

        # ecp.RelayState among headers
        _relay_state = None
        _paos_request = None
        for item in respdict["header"]:
            if item.c_tag == "RelayState" and\
               item.c_namespace == ecp.NAMESPACE:
                _relay_state = item
            if item.c_tag == "Request" and\
               item.c_namespace == paos.NAMESPACE:
                _paos_request = item

        _rc_url = _paos_request.response_consumer_url

        # **********************
        # Phase 2 - talk to the IdP
        # **********************

        idp_response = self.phase2(authn_request, _rc_url, idp_entity_id)

        # **********************************
        # Phase 3 - back to the SP
        # **********************************

        sp_response = soap.make_soap_enveloped_saml_thingy(idp_response,
            [_relay_state])

        self._debug_info("[P3] Post to SP: %s" % sp_response)

        headers = {'Content-Type': 'application/vnd.paos+xml', }

        # POST the package from the IdP to the SP
        response = self.http.post(sp_response, headers, _rc_url)

        if not response:
            if self.http.response.status == 302:
                # ignore where the SP is redirecting us to and go for the
                # url I started off with.
                pass
            else:
                print self.http.error_description
                raise Exception(
                    "Error POSTing package to SP: %s" % self.http.response.reason)

        self._debug_info("[P3] IdP response: %s" % response)

        self.done_ecp = True
        logger.debug("Done ECP")
            
        return None
コード例 #8
0
ファイル: ecp_client.py プロジェクト: GSA/pysaml2
    def phase2(self, authn_request, rc_url, idp_entity_id, headers=None,
               idp_endpoint=None, sign=False, sec=""):
        """
        Doing the second phase of the ECP conversation

        :param authn_request: The AuthenticationRequest
        :param rc_url: The assertion consumer service url
        :param idp_entity_id: The EntityID of the IdP
        :param headers: Possible extra headers
        :param idp_endpoint: Where to send it all
        :param sign: If the message should be signed
        :param sec: security context
        :return: The response from the IdP
        """
        idp_request = soap.make_soap_enveloped_saml_thingy(authn_request)
        if sign:
            _signed = sec.sign_statement_using_xmlsec(idp_request,
                                                      class_name(authn_request),
                                                      nodeid=authn_request.id)
            idp_request = _signed

        if not idp_endpoint:
            idp_endpoint = self.find_idp_endpoint(idp_entity_id)

        if self.user and self.passwd:
            self.http.add_credentials(self.user, self.passwd)

        self._debug_info("[P2] Sending request: %s" % idp_request)
            
        # POST the request to the IdP
        response = self.http.post(idp_request, headers=headers,
                                  path=idp_endpoint)

        self._debug_info("[P2] Got IdP response: %s" % response)

        if response is None or response is False:
            raise Exception(
                "Request to IdP failed (%s): %s" % (self.http.response.status,
                                                self.http.error_description))

        # SAMLP response in a SOAP envelope body, ecp response in headers
        respdict = soap.class_instances_from_soap_enveloped_saml_thingies(
                                                response, [paos, ecp,samlp])

        if respdict is None:
            raise Exception("Unexpected reply from the IdP")

        self._debug_info("[P2] IdP response dict: %s" % respdict)

        idp_response = respdict["body"]
        assert idp_response.c_tag == "Response"

        self._debug_info("[P2] IdP AUTHN response: %s" % idp_response)

        _ecp_response = None
        for item in respdict["header"]:
            if item.c_tag == "Response" and\
               item.c_namespace == ecp.NAMESPACE:
                _ecp_response = item

        _acs_url = _ecp_response.assertion_consumer_service_url
        if rc_url != _acs_url:
            error = ("response_consumer_url '%s' does not match" % rc_url,
                     "assertion_consumer_service_url '%s" % _acs_url)
            # Send an error message to the SP
            fault_text = soap.soap_fault(error)
            _ = self.http.post(fault_text, path=rc_url)
            # Raise an exception so the user knows something went wrong
            raise Exception(error)
        
        return idp_response
コード例 #9
0
ファイル: ecp_client.py プロジェクト: datopian/pysaml2
    def ecp_conversation(self, respdict, idp_entity_id=None):
        """  """

        if respdict is None:
            raise Exception("Unexpected reply from the SP")

        self._debug_info("[P1] SP response dict: %s" % respdict)

        # AuthnRequest in the body or not
        authn_request = respdict["body"]
        assert authn_request.c_tag == "AuthnRequest"

        # ecp.RelayState among headers
        _relay_state = None
        _paos_request = None
        for item in respdict["header"]:
            if item.c_tag == "RelayState" and\
               item.c_namespace == ecp.NAMESPACE:
                _relay_state = item
            if item.c_tag == "Request" and\
               item.c_namespace == paos.NAMESPACE:
                _paos_request = item

        _rc_url = _paos_request.response_consumer_url

        # **********************
        # Phase 2 - talk to the IdP
        # **********************

        idp_response = self.phase2(authn_request, _rc_url, idp_entity_id)

        # **********************************
        # Phase 3 - back to the SP
        # **********************************

        sp_response = soap.make_soap_enveloped_saml_thingy(
            idp_response, [_relay_state])

        self._debug_info("[P3] Post to SP: %s" % sp_response)

        headers = {
            'Content-Type': 'application/vnd.paos+xml',
        }

        # POST the package from the IdP to the SP
        response = self.http.post(sp_response, headers, _rc_url)

        if not response:
            if self.http.response.status == 302:
                # ignore where the SP is redirecting us to and go for the
                # url I started off with.
                pass
            else:
                print self.http.error_description
                raise Exception("Error POSTing package to SP: %s" %
                                self.http.response.reason)

        self._debug_info("[P3] IdP response: %s" % response)

        self.done_ecp = True
        logger.debug("Done ECP")

        return None
コード例 #10
0
ファイル: ecp_client.py プロジェクト: datopian/pysaml2
    def phase2(self,
               authn_request,
               rc_url,
               idp_entity_id,
               headers=None,
               idp_endpoint=None,
               sign=False,
               sec=""):
        """
        Doing the second phase of the ECP conversation

        :param authn_request: The AuthenticationRequest
        :param rc_url: The assertion consumer service url
        :param idp_entity_id: The EntityID of the IdP
        :param headers: Possible extra headers
        :param idp_endpoint: Where to send it all
        :param sign: If the message should be signed
        :param sec: security context
        :return: The response from the IdP
        """
        idp_request = soap.make_soap_enveloped_saml_thingy(authn_request)
        if sign:
            _signed = sec.sign_statement_using_xmlsec(
                idp_request,
                class_name(authn_request),
                nodeid=authn_request.id)
            idp_request = _signed

        if not idp_endpoint:
            idp_endpoint = self.find_idp_endpoint(idp_entity_id)

        if self.user and self.passwd:
            self.http.add_credentials(self.user, self.passwd)

        self._debug_info("[P2] Sending request: %s" % idp_request)

        # POST the request to the IdP
        response = self.http.post(idp_request,
                                  headers=headers,
                                  path=idp_endpoint)

        self._debug_info("[P2] Got IdP response: %s" % response)

        if response is None or response is False:
            raise Exception(
                "Request to IdP failed (%s): %s" %
                (self.http.response.status, self.http.error_description))

        # SAMLP response in a SOAP envelope body, ecp response in headers
        respdict = soap.class_instances_from_soap_enveloped_saml_thingies(
            response, [paos, ecp, samlp])

        if respdict is None:
            raise Exception("Unexpected reply from the IdP")

        self._debug_info("[P2] IdP response dict: %s" % respdict)

        idp_response = respdict["body"]
        assert idp_response.c_tag == "Response"

        self._debug_info("[P2] IdP AUTHN response: %s" % idp_response)

        _ecp_response = None
        for item in respdict["header"]:
            if item.c_tag == "Response" and\
               item.c_namespace == ecp.NAMESPACE:
                _ecp_response = item

        _acs_url = _ecp_response.assertion_consumer_service_url
        if rc_url != _acs_url:
            error = ("response_consumer_url '%s' does not match" % rc_url,
                     "assertion_consumer_service_url '%s" % _acs_url)
            # Send an error message to the SP
            fault_text = soap.soap_fault(error)
            _ = self.http.post(fault_text, path=rc_url)
            # Raise an exception so the user knows something went wrong
            raise Exception(error)

        return idp_response