def setup_class(self): with closing(Server(dotname("idp_conf"))) as server: name_id = server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") self._resp_ = server.create_authn_response( IDENTITY, "id12", # in_response_to "http://lingon.catalogix.se:8087/", # consumer_url "urn:mace:example.com:saml:roland:sp", # sp_entity_id name_id=name_id, authn=AUTHN) self._sign_resp_ = server.create_authn_response( IDENTITY, "id12", # in_response_to "http://lingon.catalogix.se:8087/", # consumer_url "urn:mace:example.com:saml:roland:sp", # sp_entity_id name_id=name_id, sign_assertion=True, authn=AUTHN) self._resp_authn = server.create_authn_response( IDENTITY, "id12", # in_response_to "http://lingon.catalogix.se:8087/", # consumer_url "urn:mace:example.com:saml:roland:sp", # sp_entity_id name_id=name_id, authn=AUTHN) self.conf = config_factory("sp", dotname("server_conf")) self.conf.only_use_keys_in_metadata = False self.ar = authn_response(self.conf, "http://lingon.catalogix.se:8087/")
def setup_class(self): with closing(Server(dotname("idp_conf"))) as server: name_id = server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp","id12") self._resp_ = server.create_authn_response( IDENTITY, "id12", # in_response_to "http://lingon.catalogix.se:8087/", # consumer_url "urn:mace:example.com:saml:roland:sp", # sp_entity_id name_id=name_id, authn=AUTHN) self._sign_resp_ = server.create_authn_response( IDENTITY, "id12", # in_response_to "http://lingon.catalogix.se:8087/", # consumer_url "urn:mace:example.com:saml:roland:sp", # sp_entity_id name_id=name_id, sign_assertion=True, authn=AUTHN) self._resp_authn = server.create_authn_response( IDENTITY, "id12", # in_response_to "http://lingon.catalogix.se:8087/", # consumer_url "urn:mace:example.com:saml:roland:sp", # sp_entity_id name_id=name_id, authn=AUTHN) self.conf = config_factory("sp", dotname("server_conf")) self.conf.only_use_keys_in_metadata = False self.ar = authn_response(self.conf, "http://lingon.catalogix.se:8087/")
def test(): with closing(Server(config_file=dotname("idp_all_conf"))) as idp: conf = SPConfig() conf.load_file(dotname("servera_conf")) sp = Saml2Client(conf) srvs = sp.metadata.single_sign_on_service(idp.config.entityid, BINDING_HTTP_REDIRECT) destination = srvs[0]["location"] req_id, req = sp.create_authn_request(destination, id="id1") info = http_redirect_message( req, destination, relay_state="RS", typ="SAMLRequest", sigalg=SIG_RSA_SHA1, sign=True, backend=sp.sec.sec_backend, ) verified_ok = False for param, val in info["headers"]: if param == "Location": _dict = parse_qs(val.split("?")[1]) _certs = idp.metadata.certs(sp.config.entityid, "any", "signing") for cert in _certs: if verify_redirect_signature(list_values2simpletons(_dict), sp.sec.sec_backend, cert[1]): verified_ok = True assert verified_ok
def test(): with closing(Server(config_file=dotname("idp_all_conf"))) as idp: conf = SPConfig() conf.load_file(dotname("servera_conf")) sp = Saml2Client(conf) srvs = sp.metadata.single_sign_on_service(idp.config.entityid, BINDING_HTTP_REDIRECT) destination = srvs[0]["location"] req_id, req = sp.create_authn_request(destination, id="id1") try: key = sp.sec.key except AttributeError: key = import_rsa_key_from_file(sp.sec.key_file) info = http_redirect_message(req, destination, relay_state="RS", typ="SAMLRequest", sigalg=SIG_RSA_SHA1, key=key) verified_ok = False for param, val in info["headers"]: if param == "Location": _dict = parse_qs(val.split("?")[1]) _certs = idp.metadata.certs(sp.config.entityid, "any", "signing") for cert in _certs: if verify_redirect_signature(_dict, cert): verified_ok = True assert verified_ok
def test_construct_deconstruct_request(): sp = Saml2Client(config_file=dotname("servera_conf")) url = sp.create_discovery_service_request("http://example.com/saml/disco", "https://example.com/saml/sp.xml", is_passive=True, returnIDParam="foo", return_url="https://example.com/saml/sp/disc") print url ds = DiscoveryServer(config_file=dotname("disco_conf")) dsr = ds.parse_discovery_service_request(url) # policy is added by the parsing and verifying method assert _eq(dsr.keys(),["return_url", "entityID", "returnIDParam", "isPassive", "policy"])
def test_construct_deconstruct_response(): sp = Saml2Client(config_file=dotname("servera_conf")) url = sp.create_discovery_service_request("http://example.com/saml/disco", "https://example.com/saml/sp.xml", isPassive=True, returnIDParam="foo", return_url="https://example.com/saml/sp/disc") ds = DiscoveryServer(config_file=dotname("disco_conf")) dsr = ds.parse_discovery_service_request(url) args = dict([(key, dsr[key]) for key in ["returnIDParam", "return"]]) url = ds.create_discovery_service_response( entity_id="https://example.com/saml/idp.xml", **args) idp_id = sp.parse_discovery_service_response(url, returnIDParam="foo") assert idp_id == "https://example.com/saml/idp.xml"
def test_construct_deconstruct_request(): sp = Saml2Client(config_file=dotname("servera_conf")) url = sp.create_discovery_service_request( "http://example.com/saml/disco", "https://example.com/saml/sp.xml", is_passive=True, returnIDParam="foo", return_url="https://example.com/saml/sp/disc") print(url) ds = DiscoveryServer(config_file=dotname("disco_conf")) dsr = ds.parse_discovery_service_request(url) # policy is added by the parsing and verifying method assert _eq(list(dsr.keys()), ["return", "entityID", "returnIDParam", "isPassive", "policy"])
def test_construct_deconstruct_response(): sp = Saml2Client(config_file=dotname("servera_conf")) url = sp.create_discovery_service_request( "http://example.com/saml/disco", "https://example.com/saml/sp.xml", is_passive=True, returnIDParam="foo", return_url="https://example.com/saml/sp/disc") ds = DiscoveryServer(config_file=dotname("disco_conf")) dsr = ds.parse_discovery_service_request(url) args = dict([(key, dsr[key]) for key in ["returnIDParam", "return"]]) url = ds.create_discovery_service_response( entity_id="https://example.com/saml/idp.xml", **args) idp_id = sp.parse_discovery_service_response(url, returnIDParam="foo") assert idp_id == "https://example.com/saml/idp.xml"
def test_dual(): cnf = Config().load_file(dotname("idp_sp_conf")) spe = cnf.getattr("endpoints", "sp") idpe = cnf.getattr("endpoints", "idp") assert spe assert idpe assert spe != idpe
def test_assertion_consumer_service(): c = IdPConfig() c.load_file(dotname("idp_conf")) c.context = "idp" c.metadata.load("local", full_path("InCommon-metadata.xml")) entity_id = "https://www.zimride.com/shibboleth" acs = c.metadata.assertion_consumer_service(entity_id) assert len(acs) == 1 assert acs[0]["location"] == 'https://www.zimride.com/Shibboleth.sso/SAML2/POST'
def test_3(): cnf = Config() cnf.load_file(dotname("sp_1_conf")) assert cnf.entityid == "urn:mace:example.com:saml:roland:sp" assert cnf.debug == 1 assert cnf.key_file == full_path("test.key") assert cnf.cert_file == full_path("test.pem") #assert cnf.xmlsec_binary == "/usr/local/bin/xmlsec1" assert cnf.accepted_time_diff == 60 assert cnf.secret == "0123456789" assert cnf.metadata is not None assert cnf.attribute_converters is not None
def test_assertion_consumer_service(): c = IdPConfig() c.load_file(dotname("idp_conf")) c.context = "idp" c.metadata.load("local", full_path("InCommon-metadata.xml")) entity_id = "https://www.zimride.com/shibboleth" acs = c.metadata.assertion_consumer_service(entity_id) assert len(acs) == 1 assert acs[0][ "location"] == 'https://www.zimride.com/Shibboleth.sso/SAML2/POST'
def _get_test_response(self, path): conf = config_factory("idp", dotname("server_conf")) resp = authn_response( conf, "https://sp:443/.auth/saml/login", asynchop=False, allow_unsolicited=True, ) with open(path, "r") as fp: authn_response_xml = fp.read() resp.loads(authn_response_xml, False) return resp
def test_signed_response_with_hmac_should_fail(self, mock_validate_on_or_after): conf = config_factory("sp", dotname("server_conf")) ar = authn_response(conf, return_addrs="https://example.org/acs/post") ar.issue_instant_ok = Mock(return_value=True) with open(SIGNED_RESPONSE_HMAC) as fp: xml_response = fp.read() ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"} ar.timeslack = 10000 # .loads checks the response signature with raises(SignatureError): ar.loads(xml_response, decode=False) assert ar.ava is None assert ar.name_id is None
def test_signed_assertion_with_random_embedded_cert_should_be_ignored( self, mock_validate_on_or_after): """ if the embedded cert is not ignored then verification will fail """ conf = config_factory("sp", dotname("server_conf")) ar = authn_response( conf, return_addrs="https://51.15.251.81.xip.io/acs/post") ar.issue_instant_ok = Mock(return_value=True) with open(SIGNED_ASSERTION_RANDOM_EMBEDDED_CERT) as fp: xml_response = fp.read() ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"} ar.timeslack = 10000 # .loads does not check the assertion, only the response signature # use .verify to verify the contents of the response assert ar.loads(xml_response, decode=False) assert ar.verify()
def test_verify(): ds = DiscoveryServer(config_file=dotname("disco_conf")) assert ds assert ds.verify_sp_in_metadata("urn:mace:example.com:saml:roland:sp")
def test_sp(): cnf = SPConfig() cnf.load_file(dotname("sp_1_conf")) assert cnf.endpoint("assertion_consumer_service") == \ ["http://lingon.catalogix.se:8087/"]
def setup_class(self): self.conf = config_factory("sp", dotname("server_conf")) self.ar = authn_response(self.conf, return_addrs="https://example.org/acs/post")
def test_construct_1(): sp = Saml2Client(config_file=dotname("servera_conf")) url = sp.create_discovery_service_request( "http://example.com/saml/disco", "https://example.com/saml/sp.xml") assert url == "http://example.com/saml/disco?entityID=https%3A%2F%2Fexample.com%2Fsaml%2Fsp.xml"
def test_complete_flow(): client = ecp_client.Client("user", "password", metadata_file=full_path("idp_all.xml")) sp = Saml2Client(config_file=dotname("servera_conf")) with closing(Server(config_file=dotname("idp_all_conf"))) as idp: IDP_ENTITY_ID = idp.config.entityid #SP_ENTITY_ID = sp.config.entityid # ------------ @Client ----------------------------- headers = client.add_paos_headers([]) assert len(headers) == 2 # ------------ @SP ----------------------------- response = DummyResponse(set_list2dict(headers)) assert sp.can_handle_ecp_response(response) sid, message = sp.create_ecp_authn_request(IDP_ENTITY_ID, relay_state="XYZ") # ------------ @Client ----------------------------- respdict = client.parse_soap_message(message) cargs = client.parse_sp_ecp_response(respdict) assert isinstance(respdict["body"], AuthnRequest) assert len(respdict["header"]) == 2 item0 = respdict["header"][0] assert isinstance(item0, Request) or isinstance(item0, RelayState) destination = respdict["body"].destination ht_args = client.apply_binding(BINDING_SOAP, respdict["body"], destination) # Time to send to the IDP # ----------- @IDP ------------------------------- req = idp.parse_authn_request(ht_args["data"], BINDING_SOAP) assert isinstance(req.message, AuthnRequest) # create Response and return in the SOAP response sp_entity_id = req.sender() name_id = idp.ident.transient_nameid( "id12", sp.config.entityid) binding, destination = idp.pick_binding("assertion_consumer_service", [BINDING_PAOS], entity_id=sp_entity_id) resp = idp.create_ecp_authn_request_response( destination, {"eduPersonEntitlement": "Short stop", "surName": "Jeter", "givenName": "Derek", "mail": "*****@*****.**", "title": "The man" }, req.message.id, destination, sp_entity_id, name_id=name_id, authn=AUTHN) # ------------ @Client ----------------------------- # The client got the response from the IDP repackage and send it to the SP respdict = client.parse_soap_message(resp) idp_response = respdict["body"] assert isinstance(idp_response, Response) assert len(respdict["header"]) == 1 _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and item.c_namespace == ecp_prof.NAMESPACE: _ecp_response = item #_acs_url = _ecp_response.assertion_consumer_service_url # done phase2 at the client ht_args = client.use_soap(idp_response, cargs["rc_url"], [cargs["relay_state"]]) print(ht_args) # ------------ @SP ----------------------------- respdict = sp.unpack_soap_message(ht_args["data"]) # verify the relay_state for header in respdict["header"]: inst = create_class_from_xml_string(RelayState, header) if isinstance(inst, RelayState): assert inst.text == "XYZ" # parse the response # Explicitly allow unsigned responses for this test sp.want_response_signed = False resp = sp.parse_authn_request_response(respdict["body"], None, {sid: "/"}) print(resp.response) assert resp.response.destination == "http://lingon.catalogix.se:8087/paos" assert resp.response.status.status_code.value == STATUS_SUCCESS
def test_complete_flow(): client = ecp_client.Client("user", "password", metadata_file=full_path("idp_all.xml")) sp = Saml2Client(config_file=dotname("servera_conf")) with closing(Server(config_file=dotname("idp_all_conf"))) as idp: IDP_ENTITY_ID = idp.config.entityid #SP_ENTITY_ID = sp.config.entityid # ------------ @Client ----------------------------- headers = client.add_paos_headers([]) assert len(headers) == 2 # ------------ @SP ----------------------------- response = DummyResponse(set_list2dict(headers)) assert sp.can_handle_ecp_response(response) sid, message = sp.create_ecp_authn_request(IDP_ENTITY_ID, relay_state="XYZ") # ------------ @Client ----------------------------- respdict = client.parse_soap_message(message) cargs = client.parse_sp_ecp_response(respdict) assert isinstance(respdict["body"], AuthnRequest) assert len(respdict["header"]) == 2 item0 = respdict["header"][0] assert isinstance(item0, Request) or isinstance(item0, RelayState) destination = respdict["body"].destination ht_args = client.apply_binding(BINDING_SOAP, respdict["body"], destination) # Time to send to the IDP # ----------- @IDP ------------------------------- req = idp.parse_authn_request(ht_args["data"], BINDING_SOAP) assert isinstance(req.message, AuthnRequest) # create Response and return in the SOAP response sp_entity_id = req.sender() name_id = idp.ident.transient_nameid("id12", sp.config.entityid) binding, destination = idp.pick_binding("assertion_consumer_service", [BINDING_PAOS], entity_id=sp_entity_id) resp = idp.create_ecp_authn_request_response(destination, { "eduPersonEntitlement": "Short stop", "surName": "Jeter", "givenName": "Derek", "mail": "*****@*****.**", "title": "The man" }, req.message.id, destination, sp_entity_id, name_id=name_id, authn=AUTHN) # ------------ @Client ----------------------------- # The client got the response from the IDP repackage and send it to the SP respdict = client.parse_soap_message(resp) idp_response = respdict["body"] assert isinstance(idp_response, Response) assert len(respdict["header"]) == 1 _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and item.c_namespace == ecp_prof.NAMESPACE: _ecp_response = item #_acs_url = _ecp_response.assertion_consumer_service_url # done phase2 at the client ht_args = client.use_soap(idp_response, cargs["rc_url"], [cargs["relay_state"]]) print(ht_args) # ------------ @SP ----------------------------- respdict = sp.unpack_soap_message(ht_args["data"]) # verify the relay_state for header in respdict["header"]: inst = create_class_from_xml_string(RelayState, header) if isinstance(inst, RelayState): assert inst.text == "XYZ" # parse the response resp = sp.parse_authn_request_response(respdict["body"], None, {sid: "/"}) print(resp.response) assert resp.response.destination == "http://lingon.catalogix.se:8087/paos" assert resp.response.status.status_code.value == STATUS_SUCCESS
from saml2.pack import http_redirect_message from saml2.sigver import verify_redirect_signature from saml2.sigver import RSA_SHA1 from saml2.server import Server from saml2 import BINDING_HTTP_REDIRECT from saml2.client import Saml2Client from saml2.config import SPConfig from saml2.sigver import rsa_load from urlparse import parse_qs from pathutils import dotname __author__ = 'rolandh' idp = Server(config_file=dotname("idp_all_conf")) conf = SPConfig() conf.load_file(dotname("servera_conf")) sp = Saml2Client(conf) def test(): srvs = sp.metadata.single_sign_on_service(idp.config.entityid, BINDING_HTTP_REDIRECT) destination = srvs[0]["location"] req = sp.create_authn_request(destination, id="id1") try: key = sp.sec.key except AttributeError:
def setup_class(self): self.conf = config_factory("sp", dotname("server_conf")) self.ar = authn_response(self.conf, "http://lingon.catalogix.se:8087/")
from saml2.pack import http_redirect_message from saml2.sigver import verify_redirect_signature from saml2.sigver import import_rsa_key_from_file from saml2.sigver import RSA_SHA1 from saml2.server import Server from saml2 import BINDING_HTTP_REDIRECT from saml2.client import Saml2Client from saml2.config import SPConfig from urllib.parse import parse_qs from pathutils import dotname __author__ = 'rolandh' idp = Server(config_file=dotname("idp_all_conf")) conf = SPConfig() conf.load_file(dotname("servera_conf")) sp = Saml2Client(conf) def test(): srvs = sp.metadata.single_sign_on_service(idp.config.entityid, BINDING_HTTP_REDIRECT) destination = srvs[0]["location"] req_id, req = sp.create_authn_request(destination, id="id1") try: key = sp.sec.key except AttributeError:
def test_construct_1(): sp = Saml2Client(config_file=dotname("servera_conf")) url = sp.create_discovery_service_request("http://example.com/saml/disco", "https://example.com/saml/sp.xml") assert url == "http://example.com/saml/disco?entityID=https%3A%2F%2Fexample.com%2Fsaml%2Fsp.xml"