def create_ecp_authn_request_response(self, acs_url, identity, in_response_to, destination, sp_entity_id, name_id_policy=None, userid=None, name_id=None, authn=None, issuer=None, sign_response=False, sign_assertion=False, **kwargs): # ---------------------------------------- # <ecp:Response # ---------------------------------------- ecp_response = ecp.Response(assertion_consumer_service_url=acs_url) header = soapenv.Header() header.extension_elements = [element_to_extension_element(ecp_response)] # ---------------------------------------- # <samlp:Response # ---------------------------------------- response = self.create_authn_response(identity, in_response_to, destination, sp_entity_id, name_id_policy, userid, name_id, authn, issuer, sign_response, sign_assertion) body = soapenv.Body() body.extension_elements = [element_to_extension_element(response)] soap_envelope = soapenv.Envelope(header=header, body=body) return "%s" % soap_envelope
def create_artifact_response(self, request, artifact, bindings=None, status=None, sign=False, issuer=None): """ Create an ArtifactResponse :return: """ rinfo = self.response_args(request, bindings) response = self._status_response(ArtifactResponse, issuer, status, sign=sign, **rinfo) msg = element_to_extension_element(self.artifact[artifact]) response.extension_elements = [msg] logger.info("Response: %s" % (response, )) return response
def _x(val, onts): if isinstance(val, dict): if "__type__" in val: ns, typ = val["__type__"].split("&") cls = getattr(onts[ns], typ) if cls is md.Extensions: lv = [] for key, ditems in val.items(): if key in SKIP: continue for _k, items in ditems.items(): for item in items: ns, typ = item["__type__"].split("&") cls = getattr(onts[ns], typ) kwargs = _kwa(item, onts) inst = cls(**kwargs) lv.append(element_to_extension_element(inst)) return lv else: kwargs = _kwa(val, onts) inst = cls(**kwargs) return inst else: res = {} for key, v in val.items(): res[key] = _x(v, onts) return res elif isinstance(val, basestring): return val elif isinstance(val, list): return [_x(v, onts) for v in val] else: return val
def _redirect_to_auth(self, _cli, entity_id, came_from, vorg_name="", cert_str=None, cert_key_str=None): try: _binding, destination = _cli.pick_binding( "single_sign_on_service", self.bindings, "idpsso", entity_id=entity_id) self.logger.debug("binding: %s, destination: %s" % (_binding, destination)) extensions = None if cert_key_str is not None: spcertenc = SPCertEnc(x509_data=ds.X509Data(x509_certificate=ds.X509Certificate(text=cert_key_str))) extensions = Extensions(extension_elements=[element_to_extension_element(spcertenc)]) if _cli.authn_requests_signed: _sid = saml2.s_utils.sid(_cli.seed) req_id, msg_str = _cli.create_authn_request(destination, vorg=vorg_name, sign=_cli.authn_requests_signed, message_id=_sid, client_crt=cert_str, extensions=extensions) _sid = req_id else: req_id, req = _cli.create_authn_request(destination, vorg=vorg_name, sign=False) msg_str = "%s" % req _sid = req_id _rstate = rndstr() self.cache.relay_state[_rstate] = came_from ht_args = _cli.apply_binding(_binding, msg_str, destination, relay_state=_rstate) self.logger.debug("ht_args: %s" % ht_args) except Exception, exc: self.logger.exception(exc) raise ServiceErrorException( "Failed to construct the AuthnRequest: %s" % exc)
def _create_header(self, relay_state_prefix): relay_state_text = relay_state_prefix + uuid.uuid4().hex relay_state = ecp.RelayState(actor=client_base.ACTOR, must_understand='1', text=relay_state_text) header = soapenv.Header() header.extension_elements = ( [saml2.element_to_extension_element(relay_state)]) return header
def sp_initiated(): saml_client = saml_client_for( current_app.config.get('SECURITY_SAML_IDP_METADATA').split(',')[0]) faa = FAAALevel( text=str(current_app.config.get('SECURITY_SAML_FAAALEVEL'))) spcertenc = RequestedAttributes([ RequestedAttribute( name="http://interop.gov.pt/MDC/Cidadao/CorreioElectronico", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required='True'), RequestedAttribute( name="http://interop.gov.pt/MDC/Cidadao/NICCifrado", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required='False'), RequestedAttribute( name="http://interop.gov.pt/MDC/Cidadao/NomeProprio", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required='False'), RequestedAttribute( name="http://interop.gov.pt/MDC/Cidadao/NomeApelido", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required='False') ]) extensions = Extensions(extension_elements=[ element_to_extension_element(faa), element_to_extension_element(spcertenc) ]) args = { 'binding': BINDING_HTTP_POST, 'relay_state': 'dWRhdGEtZ291dnB0', 'sign': True, 'force_authn': 'true', 'is_passive': 'false', 'nameid_format': '', 'extensions': extensions } reqid, info = saml_client.prepare_for_authenticate(**args) response = info['data'] return response
def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=None): 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) logger.debug("binding: %s, destination: %s", _binding, destination) # 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] logger.debug("Binding response to: {}, {}".format(return_binding, endp)) extensions = None cert = None logger.debug("cli config: {}".format(dir(_cli.config))) if _cli.config.generate_cert_func is not None: cert_str, req_key_str = _cli.config.generate_cert_func() cert = { "cert": cert_str, "key": req_key_str } spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert_str))) extensions = Extensions(extension_elements=[ element_to_extension_element(spcertenc)]) req_id, req = _cli.create_authn_request(destination, binding=return_binding, extensions=extensions, nameid_format=NAMEID_FORMAT_PERSISTENT) _rstate = rndstr() self.cache.relay_state[_rstate] = came_from apply_binding_kwargs = dict(relay_state=_rstate) if sigalg: apply_binding_kwargs['sigalg'] = sigalg ht_args = _cli.apply_binding(_binding, "%s" % req, destination, **apply_binding_kwargs) _sid = req_id if cert is not None: self.cache.outstanding_certs[_sid] = cert except Exception as exc: logger.exception(exc) resp = ServiceError( "Failed to construct the AuthnRequest: %s" % exc) return resp # remember the request self.cache.outstanding_queries[_sid] = came_from return self.response(_binding, ht_args, do_not_start_response=True)
def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=None): 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) logger.debug("binding: %s, destination: %s", _binding, destination) # 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] logger.debug("Binding response to: {}, {}".format( return_binding, endp)) extensions = None cert = None logger.debug("cli config: {}".format(dir(_cli.config))) if _cli.config.generate_cert_func is not None: cert_str, req_key_str = _cli.config.generate_cert_func() cert = {"cert": cert_str, "key": req_key_str} spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert_str))) extensions = Extensions(extension_elements=[ element_to_extension_element(spcertenc) ]) req_id, req = _cli.create_authn_request( destination, binding=return_binding, extensions=extensions, nameid_format=NAMEID_FORMAT_PERSISTENT) _rstate = rndstr() self.cache.relay_state[_rstate] = came_from apply_binding_kwargs = dict(relay_state=_rstate) if sigalg: apply_binding_kwargs['sigalg'] = sigalg ht_args = _cli.apply_binding(_binding, "%s" % req, destination, **apply_binding_kwargs) _sid = req_id if cert is not None: self.cache.outstanding_certs[_sid] = cert except Exception as exc: logger.exception(exc) resp = ServiceError("Failed to construct the AuthnRequest: %s" % exc) return resp # remember the request self.cache.outstanding_queries[_sid] = came_from return self.response(_binding, ht_args, do_not_start_response=True)
def ecp_response(target_url, response): # ---------------------------------------- # <ecp:Response # ---------------------------------------- ecp_response = ecp.Response(assertion_consumer_service_url=target_url) header = soapenv.Header() header.extension_elements = [element_to_extension_element(ecp_response)] # ---------------------------------------- # <samlp:Response # ---------------------------------------- body = soapenv.Body() body.extension_elements = [element_to_extension_element(response)] soap_envelope = soapenv.Envelope(header=header, body=body) return "%s" % soap_envelope
def test(): # The needed key is the private key, not for encryption but for decryption _key = import_rsa_key_from_file("mykey.pem") idp_conf = config_factory("idp", "idp_conf") generate_metadata = MetadataGeneration(idp_proxy_conf.SERVICE, _key, idp_conf, idp_conf.xmlsec_path) sps = idp_conf.metadata.service_providers() qs = { "entityId": sps[0], "secret": { "Google": { "key": "lingon", "secret": "aaaaa" }, "Facebook": { "key": "hallon", "secret": "bbbbb" }, "Twitter": { "key": "jordgubb", "secret": "ccccc" } } } res = generate_metadata.handle_metadata_save( { 'wsgi.url_scheme': "https", 'HTTP_HOST': "example.com" }, None, qs) s = res[0].index("<mdattr:EntityAttributes") e = res[0].index("</mdattr:EntityAttributes>") snippet = res[0][s:e + len("</mdattr:EntityAttributes>")] entity_attributes = mdattr.entity_attributes_from_string(snippet) entdescr = idp_conf.metadata.metadata["./sp/sp.xml"].entity_descr ext = element_to_extension_element(entity_attributes) entdescr.spsso_descriptor[0].extensions.extension_elements.append(ext) print entity_attributes qs = {secret.CONST_BODY: json.dumps({"xml": "%s" % entdescr})} generate_metadata.handle_metadata_verify_json( { 'wsgi.url_scheme': "https", 'HTTP_HOST': "example.com" }, None, qs)
def _redirect_to_auth(self, _cli, entity_id, came_from, vorg_name="", cert_str=None, cert_key_str=None): try: _binding, destination = _cli.pick_binding("single_sign_on_service", self.bindings, "idpsso", entity_id=entity_id) self.logger.debug("binding: %s, destination: %s" % (_binding, destination)) extensions = None if cert_key_str is not None: spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert_key_str))) extensions = Extensions(extension_elements=[ element_to_extension_element(spcertenc) ]) if _cli.authn_requests_signed: _sid = saml2.s_utils.sid(_cli.seed) req_id, msg_str = _cli.create_authn_request( destination, vorg=vorg_name, sign=_cli.authn_requests_signed, message_id=_sid, client_crt=cert_str, extensions=extensions) _sid = req_id else: req_id, req = _cli.create_authn_request(destination, vorg=vorg_name, sign=False) msg_str = "%s" % req _sid = req_id _rstate = rndstr() self.cache.relay_state[_rstate] = came_from ht_args = _cli.apply_binding(_binding, msg_str, destination, relay_state=_rstate) self.logger.debug("ht_args: %s" % ht_args) except Exception, exc: self.logger.exception(exc) raise ServiceErrorException( "Failed to construct the AuthnRequest: %s" % exc)
def _filter_args(self, instance, extensions=None, **kwargs): args = {} if extensions is None: extensions = [] allowed_attributes = instance.keys() for key, val in kwargs.items(): if key in allowed_attributes: args[key] = val elif isinstance(val, SamlBase): # extension elements allowed ? extensions.append(element_to_extension_element(val)) return args, extensions
def create_authn_request(self): try: #sid_ = sid() #self.outstanding_queries[sid_] = came_from idps = self.sp.metadata.with_descriptor("idpsso") if len(idps) == 1: self.entity_id = idps.keys()[0] elif len(idps) > 1: raise Exception("TestSp only supports 1 idp in the metadata!") else: Exception("No IdP metadata found!") _binding, destination = self.sp.pick_binding("single_sign_on_service", self.bindings, "idpsso", entity_id=self.entity_id) self.cert_str, self.cert_key_str = self.generate_cert() cert = { "cert": self.cert_str, "key": self.cert_key_str } spcertenc = SPCertEnc( x509_data=xmldsig.X509Data(x509_certificate=xmldsig.X509Certificate(text=self.cert_str))) extensions = Extensions(extension_elements=[element_to_extension_element(spcertenc)]) try: vorg_name = self.sp.vorg._name except AttributeError: vorg_name = "" if self.sp.authn_requests_signed: self.sid = s_utils.sid() req_id, self.msg_str = self.sp.create_authn_request(destination, vorg=vorg_name, sign=self.sp.authn_requests_signed, message_id=self.sid, extensions=extensions) self.sid = req_id else: req_id, req = self.sp.create_authn_request(destination, vorg=vorg_name, sign=False) self.msg_str = "%s" % req self.sid = req_id if cert is not None: self.outstanding_certs[self.sid] = cert self.rstate = rndstr() self.ht_args = self.sp.apply_binding(_binding, self.msg_str, destination, relay_state=self.rstate) url = self.ht_args["headers"][0][1] except Exception, exc: raise Exception("Failed to construct the AuthnRequest: %s" % exc)
def test(): # The needed key is the private key, not for encryption but for decryption _key = import_rsa_key_from_file("mykey.pem") idp_conf = config_factory("idp", "idp_conf") generate_metadata = MetadataGeneration( idp_proxy_conf.SERVICE, _key, idp_conf, idp_conf.xmlsec_path) sps = idp_conf.metadata.service_providers() qs = { "entityId": sps[0], "secret": { "Google": { "key": "lingon", "secret": "aaaaa"}, "Facebook": { "key": "hallon", "secret": "bbbbb"}, "Twitter": { "key": "jordgubb", "secret": "ccccc"} } } res = generate_metadata.handle_metadata_save({'wsgi.url_scheme': "https", 'HTTP_HOST': "example.com"}, None, qs) s = res[0].index("<mdattr:EntityAttributes") e = res[0].index("</mdattr:EntityAttributes>") snippet = res[0][s:e+len("</mdattr:EntityAttributes>")] entity_attributes = mdattr.entity_attributes_from_string(snippet) entdescr = idp_conf.metadata.metadata["./sp/sp.xml"].entity_descr ext = element_to_extension_element(entity_attributes) entdescr.spsso_descriptor[0].extensions.extension_elements.append(ext) print entity_attributes qs = {secret.CONST_BODY: json.dumps({"xml": "%s" % entdescr})} generate_metadata.handle_metadata_verify_json({'wsgi.url_scheme':"https", 'HTTP_HOST': "example.com"}, None, qs)
def test_attribute_element_to_extension_element(): attr = create_class_from_xml_string(Attribute, saml2_data.TEST_ATTRIBUTE) ee = saml2.element_to_extension_element(attr) print ee.__dict__ assert ee.tag == "Attribute" assert ee.namespace == 'urn:oasis:names:tc:SAML:2.0:assertion' assert _eq(ee.attributes.keys(), ['FriendlyName', 'Name', 'NameFormat']) assert ee.attributes["FriendlyName"] == 'test attribute' assert ee.attributes["Name"] == "testAttribute" assert ee.attributes["NameFormat"] == \ 'urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified' assert len(ee.children) == 2 for child in ee.children: # children are also extension element instances assert child.namespace == 'urn:oasis:names:tc:SAML:2.0:assertion' assert child.tag == "AttributeValue"
def create_artifact_response(self, request, artifact, bindings=None, status=None, sign=False, issuer=None): """ Create an ArtifactResponse :return: """ rinfo = self.response_args(request, bindings) response = self._status_response(ArtifactResponse, issuer, status, sign=sign, **rinfo) msg = element_to_extension_element(self.artifact[artifact]) response.extension_elements = [msg] logger.info("Response: %s" % (response,)) return response
def authn_request(self, entity_id, state_key, encrypt_cert=None): _cli = self.sp req_args = self.cache[state_key][2] 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) logger.debug("binding: %s, destination: %s" % (_binding, destination)) # 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] if self.force_persistant_nameid: if "name_id_policy" in req_args: req_args["name_id_policy"].format = NAMEID_FORMAT_PERSISTENT else: req_args["nameid_format"] = NAMEID_FORMAT_PERSISTENT if encrypt_cert is not None: spcertenc = SPCertEnc(x509_data=xmldsig.X509Data(x509_certificate=xmldsig.X509Certificate( text=encrypt_cert))) extensions = Extensions(extension_elements=[element_to_extension_element(spcertenc)]) req_id, req = _cli.create_authn_request(destination, binding=return_binding, extensions=extensions, **req_args) else: req_id, req = _cli.create_authn_request(destination, binding=return_binding, **req_args) ht_args = _cli.apply_binding(_binding, "%s" % req, destination, relay_state=state_key) _sid = req_id logger.debug("ht_args: %s" % ht_args) except Exception, exc: logger.exception(exc) resp = ServiceError( "Failed to construct the AuthnRequest: %s" % exc) return resp
def redirect_to_auth(self, _cli, entity_id, came_from): 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) logger.debug("binding: %s, destination: %s" % (_binding, destination)) # 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] extensions = None cert = None if _cli.config.generate_cert_func is not None: cert_str, req_key_str = _cli.config.generate_cert_func() cert = { "cert": cert_str, "key": req_key_str } spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert_str))) extensions = Extensions(extension_elements=[ element_to_extension_element(spcertenc)]) req_id, req = _cli.create_authn_request(destination, binding=return_binding, extensions=extensions) _rstate = rndstr() self.cache.relay_state[_rstate] = came_from ht_args = _cli.apply_binding(_binding, "%s" % req, destination, relay_state=_rstate) _sid = req_id if cert is not None: self.cache.outstanding_certs[_sid] = cert except Exception, exc: logger.exception(exc) resp = ServiceError( "Failed to construct the AuthnRequest: %s" % exc) return resp
def from_dict(val, onts, mdb_safe=False): """ Converts a dictionary into a pysaml2 object :param val: A dictionary :param onts: Dictionary of schemas to use in the conversion :return: The pysaml2 object instance """ if isinstance(val, dict): if "__class__" in val: ns, typ = val["__class__"].split("&") cls = getattr(onts[ns], typ) if cls is md.Extensions: lv = [] for key, ditems in val.items(): if key in EXP_SKIP: continue for item in ditems: ns, typ = item["__class__"].split("&") cls = getattr(onts[ns], typ) kwargs = _kwa(item, onts, mdb_safe) inst = cls(**kwargs) lv.append(element_to_extension_element(inst)) return lv else: kwargs = _kwa(val, onts, mdb_safe) inst = cls(**kwargs) return inst else: res = {} for key, v in val.items(): if mdb_safe: key = key.replace("__", ".") res[key] = from_dict(v, onts) return res elif isinstance(val, basestring): return val elif isinstance(val, list): return [from_dict(v, onts) for v in val] else: return val
def _create_body(self, saml_assertion): body = soapenv.Body() body.extension_elements = ([ saml2.element_to_extension_element(saml_assertion) ]) return body
def ecp_auth_request(cls, entityid=None, relay_state="", sign=False): """ Makes an authentication request. :param entityid: The entity ID of the IdP to send the request to :param relay_state: To where the user should be returned after successfull log in. :param sign: Whether the request should be signed or not. :return: AuthnRequest response """ eelist = [] # ---------------------------------------- # <paos:Request> # ---------------------------------------- my_url = cls.service_url(BINDING_PAOS) # must_understand and actor according to the standard # paos_request = paos.Request(must_understand="1", actor=ACTOR, response_consumer_url=my_url, service=SERVICE) eelist.append(element_to_extension_element(paos_request)) # ---------------------------------------- # <ecp:Request> # ---------------------------------------- # idp = samlp.IDPEntry( # provider_id = "https://idp.example.org/entity", # name = "Example identity provider", # loc = "https://idp.example.org/saml2/sso", # ) # # idp_list = samlp.IDPList(idp_entry= [idp]) # # ecp_request = ecp.Request( # actor = ACTOR, must_understand = "1", # provider_name = "Example Service Provider", # issuer=saml.Issuer(text="https://sp.example.org/entity"), # idp_list = idp_list) # # eelist.append(element_to_extension_element(ecp_request)) # ---------------------------------------- # <ecp:RelayState> # ---------------------------------------- relay_state = ecp.RelayState(actor=ACTOR, must_understand="1", text=relay_state) eelist.append(element_to_extension_element(relay_state)) header = soapenv.Header() header.extension_elements = eelist # ---------------------------------------- # <samlp:AuthnRequest> # ---------------------------------------- logger.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP)) location = cls._sso_location(entityid, binding=BINDING_SOAP) authn_req = cls.create_authn_request(location, binding=BINDING_PAOS, service_url_binding=BINDING_PAOS) body = soapenv.Body() body.extension_elements = [element_to_extension_element(authn_req)] # ---------------------------------------- # The SOAP envelope # ---------------------------------------- soap_envelope = soapenv.Envelope(header=header, body=body) return authn_req.id, "%s" % soap_envelope
__author__ = 'roland' conf = config.SPConfig() conf.load_file("server_conf") client = Saml2Client(conf) # place a certificate in an authn request cert = read_cert_from_file(full_path("test.pem"), "pem") spcertenc = SPCertEnc( x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert))) extensions = Extensions( extension_elements=[element_to_extension_element(spcertenc)]) req_id, req = client.create_authn_request( "http://www.example.com/sso", "urn:mace:example.com:it:tek", nameid_format=saml.NAMEID_FORMAT_PERSISTENT, message_id="666", extensions=extensions) print req # Get a certificate from an authn request xml = "%s" % req
def challenge(self, environ, _status, _app_headers, _forget_headers): _cli = self.saml_client if 'REMOTE_USER' in environ: name_id = decode(environ["REMOTE_USER"]) _cli = self.saml_client path_info = environ['PATH_INFO'] if 'samlsp.logout' in environ: responses = _cli.global_logout(name_id) return self._handle_logout(responses) if 'samlsp.pending' in environ: response = environ['samlsp.pending'] if isinstance(response, HTTPRedirection): response.headers += _forget_headers return response #logger = environ.get('repoze.who.logger','') # Which page was accessed to get here came_from = construct_came_from(environ) environ["myapp.came_from"] = came_from logger.debug("[sp.challenge] RelayState >> '%s'" % came_from) # Am I part of a virtual organization or more than one ? try: vorg_name = environ["myapp.vo"] except KeyError: try: vorg_name = _cli.vorg._name except AttributeError: vorg_name = "" logger.info("[sp.challenge] VO: %s" % vorg_name) # If more than one idp and if none is selected, I have to do wayf (done, response) = self._pick_idp(environ, came_from) # Three cases: -1 something went wrong or Discovery service used # 0 I've got an IdP to send a request to # >0 ECP in progress logger.debug("_idp_pick returned: %s" % done) if done == -1: return response elif done > 0: self.outstanding_queries[done] = came_from return ECP_response(response) else: entity_id = response logger.info("[sp.challenge] entity_id: %s" % entity_id) # Do the AuthnRequest _binding = BINDING_HTTP_REDIRECT try: srvs = _cli.metadata.single_sign_on_service(entity_id, _binding) logger.debug("srvs: %s" % srvs) dest = srvs[0]["location"] logger.debug("destination: %s" % dest) extensions = None cert = None if _cli.config.generate_cert_func is not None: cert_str, req_key_str = _cli.config.generate_cert_func() cert = { "cert": cert_str, "key": req_key_str } spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert_str))) extensions = Extensions(extension_elements=[ element_to_extension_element(spcertenc)]) if _cli.authn_requests_signed: _sid = saml2.s_utils.sid(_cli.seed) req_id, msg_str = _cli.create_authn_request( dest, vorg=vorg_name, sign=_cli.authn_requests_signed, message_id=_sid, extensions=extensions) _sid = req_id else: req_id, req = _cli.create_authn_request( dest, vorg=vorg_name, sign=False, extensions=extensions) msg_str = "%s" % req _sid = req_id if cert is not None: self.outstanding_certs[_sid] = cert ht_args = _cli.apply_binding(_binding, msg_str, destination=dest, relay_state=came_from) logger.debug("ht_args: %s" % ht_args) except Exception, exc: logger.exception(exc) raise Exception( "Failed to construct the AuthnRequest: %s" % exc) try: ret = _cli.config.getattr( "endpoints","sp")["discovery_response"][0][0] if (environ["PATH_INFO"]) in ret and ret.split( environ["PATH_INFO"])[1] == "": query = parse_qs(environ["QUERY_STRING"]) sid = query["sid"][0] came_from = self.outstanding_queries[sid] except: pass # remember the request self.outstanding_queries[_sid] = came_from if not ht_args["data"] and ht_args["headers"][0][0] == "Location": logger.debug('redirect to: %s' % ht_args["headers"][0][1]) return HTTPSeeOther(headers=ht_args["headers"]) else: return ht_args["data"]
def ecp_auth_request(cls, entityid=None, relay_state="", sign=False): """ Makes an authentication request. :param entityid: The entity ID of the IdP to send the request to :param relay_state: To where the user should be returned after successfull log in. :param sign: Whether the request should be signed or not. :return: AuthnRequest response """ eelist = [] # ---------------------------------------- # <paos:Request> # ---------------------------------------- my_url = cls.service_url(BINDING_PAOS) # must_understan and actor according to the standard # paos_request = paos.Request(must_understand="1", actor=ACTOR, response_consumer_url=my_url, service=SERVICE) eelist.append(element_to_extension_element(paos_request)) # ---------------------------------------- # <ecp:Request> # ---------------------------------------- # idp = samlp.IDPEntry( # provider_id = "https://idp.example.org/entity", # name = "Example identity provider", # loc = "https://idp.example.org/saml2/sso", # ) # # idp_list = samlp.IDPList(idp_entry= [idp]) # # ecp_request = ecp.Request(actor = ACTOR, must_understand = "1", # provider_name = "Example Service Provider", # issuer=saml.Issuer(text="https://sp.example.org/entity"), # idp_list = idp_list) # # eelist.append(element_to_extension_element(ecp_request)) # ---------------------------------------- # <ecp:RelayState> # ---------------------------------------- relay_state = ecp.RelayState(actor=ACTOR, must_understand="1", text=relay_state) eelist.append(element_to_extension_element(relay_state)) header = soapenv.Header() header.extension_elements = eelist # ---------------------------------------- # <samlp:AuthnRequest> # ---------------------------------------- logger.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP)) location = cls._sso_location(entityid, binding=BINDING_SOAP) session_id = sid() authn_req = cls.authn(location, session_id, binding=BINDING_PAOS, service_url_binding=BINDING_PAOS) body = soapenv.Body() body.extension_elements = [element_to_extension_element(authn_req)] # ---------------------------------------- # The SOAP envelope # ---------------------------------------- soap_envelope = soapenv.Envelope(header=header, body=body) return session_id, "%s" % soap_envelope
from pathutils import full_path __author__ = 'roland' conf = config.SPConfig() conf.load_file("server_conf") client = Saml2Client(conf) # place a certificate in an authn request cert = read_cert_from_file(full_path("test.pem"), "pem") spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert))) extensions = Extensions( extension_elements=[element_to_extension_element(spcertenc)]) req_id, req = client.create_authn_request( "http://www.example.com/sso", "urn:mace:example.com:it:tek", nameid_format=saml.NAMEID_FORMAT_PERSISTENT, message_id="666", extensions=extensions) print req # Get a certificate from an authn request xml = "%s" % req parsed = authn_request_from_string(xml)
def challenge(self, environ, _status, _app_headers, _forget_headers): _cli = self.saml_client if 'REMOTE_USER' in environ: name_id = decode(environ["REMOTE_USER"]) _cli = self.saml_client path_info = environ['PATH_INFO'] if 'samlsp.logout' in environ: responses = _cli.global_logout(name_id) return self._handle_logout(responses) if 'samlsp.pending' in environ: response = environ['samlsp.pending'] if isinstance(response, HTTPRedirection): response.headers += _forget_headers return response #logger = environ.get('repoze.who.logger','') # Which page was accessed to get here came_from = construct_came_from(environ) environ["myapp.came_from"] = came_from logger.debug("[sp.challenge] RelayState >> '%s'" % came_from) # Am I part of a virtual organization or more than one ? try: vorg_name = environ["myapp.vo"] except KeyError: try: vorg_name = _cli.vorg._name except AttributeError: vorg_name = "" logger.info("[sp.challenge] VO: %s" % vorg_name) # If more than one idp and if none is selected, I have to do wayf (done, response) = self._pick_idp(environ, came_from) # Three cases: -1 something went wrong or Discovery service used # 0 I've got an IdP to send a request to # >0 ECP in progress logger.debug("_idp_pick returned: %s" % done) if done == -1: return response elif done > 0: self.outstanding_queries[done] = came_from return ECP_response(response) else: entity_id = response logger.info("[sp.challenge] entity_id: %s" % entity_id) # Do the AuthnRequest _binding = BINDING_HTTP_REDIRECT try: srvs = _cli.metadata.single_sign_on_service(entity_id, _binding) logger.debug("srvs: %s" % srvs) dest = srvs[0]["location"] logger.debug("destination: %s" % dest) extensions = None cert = None if _cli.config.generate_cert_func is not None: cert_str, req_key_str = _cli.config.generate_cert_func() cert = { "cert": cert_str, "key": req_key_str } spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert_str))) extensions = Extensions(extension_elements=[ element_to_extension_element(spcertenc)]) if _cli.authn_requests_signed: _sid = saml2.s_utils.sid(_cli.seed) req_id, msg_str = _cli.create_authn_request( dest, vorg=vorg_name, sign=_cli.authn_requests_signed, message_id=_sid, extensions=extensions) _sid = req_id else: req_id, req = _cli.create_authn_request( dest, vorg=vorg_name, sign=False, extensions=extensions) msg_str = "%s" % req _sid = req_id if cert is not None: self.outstanding_certs[_sid] = cert ht_args = _cli.apply_binding(_binding, msg_str, destination=dest, relay_state=came_from) logger.debug("ht_args: %s" % ht_args) except Exception, exc: logger.exception(exc) raise Exception( "Failed to construct the AuthnRequest: %s" % exc) try: ret = _cli.config.getattr( "endpoints", "sp")["discovery_response"][0][0] if (environ["PATH_INFO"]) in ret and ret.split( environ["PATH_INFO"])[1] == "": query = parse_qs(environ["QUERY_STRING"]) sid = query["sid"][0] came_from = self.outstanding_queries[sid] except: pass # remember the request self.outstanding_queries[_sid] = came_from if not ht_args["data"] and ht_args["headers"][0][0] == "Location": logger.debug('redirect to: %s' % ht_args["headers"][0][1]) return HTTPSeeOther(headers=ht_args["headers"]) else: return ht_args["data"]
def _create_body(self, saml_assertion): body = soapenv.Body() body.extension_elements = ( [saml2.element_to_extension_element(saml_assertion)]) return body