def test_identify(self): # Create a SAMLResponse ava = { "givenName": ["Derek"], "surname": ["Jeter"], "mail": ["*****@*****.**"] } resp_str = "\n".join( self.server.authn_response( ava, "id1", "http://lingon.catalogix.se:8087/", "urn:mace:example.com:saml:roland:sp", samlp.NameIDPolicy(format=saml.NAMEID_FORMAT_TRANSIENT, allow_create="true"), "*****@*****.**")) resp_str = base64.encodestring(resp_str) self.sp.outstanding_queries = {"id1": "http://www.example.com/service"} session_info = self.sp._eval_authn_response({}, {"SAMLResponse": resp_str}) assert len(session_info) > 1 assert session_info["came_from"] == 'http://www.example.com/service' assert session_info["ava"] == { 'givenName': ['Derek'], 'mail': ['*****@*****.**'], 'sn': ['Jeter'] }
def test_sign_then_encrypt_assertion2(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement(assertion, class_name(assertion), key_file=self.client.sec.key_file, node_id=assertion.id) sigass = rm_xmltag(sigass) response = sigver.response_factory( in_response_to="_012345", destination="http://lingon.catalogix.se:8087/", status=s_utils.success_status_factory(), issuer=self.server._issuer(), encrypted_assertion=EncryptedAssertion()) xmldoc = "%s" % response # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) enctext = _sec.crypto.encrypt_assertion(xmldoc, _sec.cert_file, pre_encryption_part()) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.ava == {'givenName': ['Derek'], 'sn': ['Jeter']}
def test_unsolicited_response(self): """ """ self.server = Server("idp_conf") conf = config.SPConfig() conf.load_file("server_conf") self.client = Saml2Client(conf) for subject in self.client.users.subjects(): self.client.users.remove_person(subject) IDP = "urn:mace:example.com:saml:roland:idp" ava = { "givenName": ["Derek"], "surname": ["Jeter"], "mail": ["*****@*****.**"] } resp_str = "\n".join( self.server.authn_response( identity=ava, in_response_to="id1", destination="http://lingon.catalogix.se:8087/", sp_entity_id="urn:mace:example.com:saml:roland:sp", name_id_policy=samlp.NameIDPolicy( format=saml.NAMEID_FORMAT_PERSISTENT), userid="*****@*****.**")) resp_str = base64.encodestring(resp_str) self.client.allow_unsolicited = True authn_response = self.client.response({"SAMLResponse": resp_str}, ()) assert authn_response is not None assert authn_response.issuer() == IDP assert authn_response.response.assertion[0].issuer.text == IDP session_info = authn_response.session_info() print session_info assert session_info["ava"] == { 'mail': ['*****@*****.**'], 'givenName': ['Derek'], 'sn': ['Jeter'] } assert session_info["issuer"] == IDP assert session_info["came_from"] == "" response = samlp.response_from_string(authn_response.xmlstr) assert response.destination == "http://lingon.catalogix.se:8087/" # One person in the cache assert len(self.client.users.subjects()) == 1
def test_sign_then_encrypt_assertion2(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement( assertion, class_name(assertion), #key_file="pki/mykey.pem", key_file="test.key", node_id=assertion.id) # Create an Assertion instance from the signed assertion _ass = saml.assertion_from_string(sigass) response = sigver.response_factory( in_response_to="_012345", destination="https://www.example.com", status=s_utils.success_status_factory(), issuer=self.server._issuer(), assertion=_ass) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part()) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.ava == {'givenName': ['Derek'], 'sn': ['Jeter']}
def testAccessors(self): """Test for AuthnRequest accessors""" self.ar.id = "request id" self.ar.version = saml2.VERSION self.ar.issue_instant = "2007-09-14T01:05:02Z" self.ar.destination = "http://www.example.com/Destination" self.ar.consent = saml.CONSENT_UNSPECIFIED self.ar.issuer = saml.Issuer() self.ar.signature = ds.Signature() self.ar.extensions = samlp.Extensions() self.ar.subject = saml.Subject() self.ar.name_id_policy = samlp.NameIDPolicy() self.ar.conditions = saml.Conditions() self.ar.requested_authn_context = samlp.RequestedAuthnContext() self.ar.scoping = samlp.Scoping() self.ar.force_authn = 'true' self.ar.is_passive = 'true' self.ar.assertion_consumer_service_index = "1" self.ar.assertion_consumer_service_url = "http://www.example.com/acs" self.ar.protocol_binding = saml2.BINDING_HTTP_POST self.ar.attribute_consuming_service_index = "2" self.ar.provider_name = "provider name" new_ar = samlp.authn_request_from_string(self.ar.to_string()) assert new_ar.id == "request id" assert new_ar.version == saml2.VERSION assert new_ar.issue_instant == "2007-09-14T01:05:02Z" assert new_ar.destination == "http://www.example.com/Destination" assert new_ar.consent == saml.CONSENT_UNSPECIFIED assert isinstance(new_ar.issuer, saml.Issuer) assert isinstance(new_ar.signature, ds.Signature) assert isinstance(new_ar.extensions, samlp.Extensions) assert isinstance(new_ar.subject, saml.Subject) assert isinstance(new_ar.name_id_policy, samlp.NameIDPolicy) assert isinstance(new_ar.conditions, saml.Conditions) assert isinstance(new_ar.requested_authn_context, samlp.RequestedAuthnContext) assert isinstance(new_ar.scoping, samlp.Scoping) assert new_ar.force_authn == 'true' assert new_ar.is_passive == 'true' assert new_ar.assertion_consumer_service_index == '1' assert new_ar.assertion_consumer_service_url == \ 'http://www.example.com/acs' assert new_ar.protocol_binding == saml2.BINDING_HTTP_POST assert new_ar.attribute_consuming_service_index == '2' assert new_ar.provider_name == "provider name"
def test_authn_response_0(self): self.server = Server("idp_conf") conf = config.SPConfig() conf.load_file("server_conf") self.client = client.Saml2Client(conf) ava = { "givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"], "title": "The man" } npolicy = samlp.NameIDPolicy(format=saml.NAMEID_FORMAT_TRANSIENT, allow_create="true") resp_str = "%s" % self.server.create_authn_response( ava, "id1", "http://*****:*****@example.com", authn=AUTHN) response = samlp.response_from_string(resp_str) print((response.keyswv())) assert _eq(response.keyswv(), [ 'status', 'destination', 'assertion', 'in_response_to', 'issue_instant', 'version', 'issuer', 'id' ]) print((response.assertion[0].keyswv())) assert len(response.assertion) == 1 assert _eq(response.assertion[0].keyswv(), [ 'attribute_statement', 'issue_instant', 'version', 'subject', 'conditions', 'id', 'issuer', 'authn_statement' ]) assertion = response.assertion[0] assert len(assertion.attribute_statement) == 1 astate = assertion.attribute_statement[0] print(astate) assert len(astate.attribute) == 4
def test_sign_then_encrypt_assertion_advice(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") a_asser = Assertion({ "uid": "test01", "email": "*****@*****.**" }) a_assertion = a_asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") a_assertion.signature = sigver.pre_signature_part( a_assertion.id, _sec.my_cert, 1) assertion.advice = Advice() assertion.advice.encrypted_assertion = [] assertion.advice.encrypted_assertion.append(EncryptedAssertion()) assertion.advice.encrypted_assertion[0].add_extension_element( a_assertion) response = sigver.response_factory( in_response_to="_012345", destination="http://lingon.catalogix.se:8087/", status=s_utils.success_status_factory(), issuer=self.server._issuer()) response.assertion.append(assertion) response = _sec.sign_statement("%s" % response, class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id) #xmldoc = "%s" % response # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. #xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) node_xpath = ''.join([ "/*[local-name()=\"%s\"]" % v for v in [ "Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion" ] ]) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part(), node_xpath=node_xpath) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.assertion.advice assert resp.assertion.advice.assertion assert resp.ava == \ {'sn': ['Jeter'], 'givenName': ['Derek'], 'uid': ['test01'], 'email': ['*****@*****.**']}
def test_response(self): IDP = "urn:mace:example.com:saml:roland:idp" ava = { "givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"], "title": ["The man"] } nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) resp = self.server.create_authn_response( identity=ava, in_response_to="id1", destination="http://lingon.catalogix.se:8087/", sp_entity_id="urn:mace:example.com:saml:roland:sp", name_id_policy=nameid_policy, userid="*****@*****.**", authn=AUTHN) resp_str = "%s" % resp resp_str = base64.encodestring(resp_str) authn_response = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"id1": "http://foo.example.com/service"}) assert authn_response is not None assert authn_response.issuer() == IDP assert authn_response.response.assertion[0].issuer.text == IDP session_info = authn_response.session_info() print session_info assert session_info["ava"] == { 'mail': ['*****@*****.**'], 'givenName': ['Derek'], 'sn': ['Jeter'], 'title': ["The man"] } assert session_info["issuer"] == IDP assert session_info["came_from"] == "http://foo.example.com/service" response = samlp.response_from_string(authn_response.xmlstr) assert response.destination == "http://lingon.catalogix.se:8087/" # One person in the cache assert len(self.client.users.subjects()) == 1 subject_id = self.client.users.subjects()[0] print "||||", self.client.users.get_info_from(subject_id, IDP) # The information I have about the subject comes from one source assert self.client.users.issuers_of_info(subject_id) == [IDP] # --- authenticate another person ava = { "givenName": ["Alfonson"], "surName": ["Soriano"], "mail": ["*****@*****.**"], "title": ["outfielder"] } resp_str = "%s" % self.server.create_authn_response( identity=ava, in_response_to="id2", destination="http://lingon.catalogix.se:8087/", sp_entity_id="urn:mace:example.com:saml:roland:sp", name_id_policy=nameid_policy, userid="*****@*****.**", authn=AUTHN) resp_str = base64.encodestring(resp_str) self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"id2": "http://foo.example.com/service"}) # Two persons in the cache assert len(self.client.users.subjects()) == 2 issuers = [ self.client.users.issuers_of_info(s) for s in self.client.users.subjects() ] # The information I have about the subjects comes from the same source print issuers assert issuers == [[IDP], [IDP]]
def create_authn_request(self, destination, vorg="", scoping=None, binding=saml2.BINDING_HTTP_POST, nameid_format=None, service_url_binding=None, message_id=0, consent=None, extensions=None, sign=None, allow_create=None, sign_prepare=False, sign_alg=None, digest_alg=None, **kwargs): """ Creates an authentication request. :param destination: Where the request should be sent. :param vorg: The virtual organization the service belongs to. :param scoping: The scope of the request :param binding: The protocol to use for the Response !! :param nameid_format: Format of the NameID :param service_url_binding: Where the reply should be sent dependent on reply binding. :param message_id: The identifier for this request :param consent: Whether the principal have given her consent :param extensions: Possible extensions :param sign: Whether the request should be signed or not. :param sign_prepare: Whether the signature should be prepared or not. :param allow_create: If the identity provider is allowed, in the course of fulfilling the request, to create a new identifier to represent the principal. :param kwargs: Extra key word arguments :return: tuple of request ID and <samlp:AuthnRequest> instance """ client_crt = None if "client_crt" in kwargs: client_crt = kwargs["client_crt"] args = {} if self.config.getattr('hide_assertion_consumer_service', 'sp'): args["assertion_consumer_service_url"] = None binding = None else: try: args["assertion_consumer_service_url"] = kwargs[ "assertion_consumer_service_urls"][0] del kwargs["assertion_consumer_service_urls"] except KeyError: try: args["assertion_consumer_service_url"] = kwargs[ "assertion_consumer_service_url"] del kwargs["assertion_consumer_service_url"] except KeyError: try: args["assertion_consumer_service_index"] = str( kwargs["assertion_consumer_service_index"]) del kwargs["assertion_consumer_service_index"] except KeyError: if service_url_binding is None: service_urls = self.service_urls(binding) else: service_urls = self.service_urls( service_url_binding) args["assertion_consumer_service_url"] = service_urls[ 0] try: args["provider_name"] = kwargs["provider_name"] except KeyError: if binding == BINDING_PAOS: pass else: args["provider_name"] = self._my_name() # Allow argument values either as class instances or as dictionaries # all of these have cardinality 0..1 _msg = AuthnRequest() for param in [ "scoping", "requested_authn_context", "conditions", "subject" ]: try: _item = kwargs[param] except KeyError: pass else: del kwargs[param] # either class instance or argument dictionary if isinstance(_item, _msg.child_class(param)): args[param] = _item elif isinstance(_item, dict): args[param] = RequestedAuthnContext(**_item) else: raise ValueError("%s or wrong type expected %s" % (_item, param)) try: args["name_id_policy"] = kwargs["name_id_policy"] del kwargs["name_id_policy"] except KeyError: if allow_create is None: allow_create = self.config.getattr( "name_id_format_allow_create", "sp") if allow_create is None: allow_create = "false" else: if allow_create is True: allow_create = "true" else: allow_create = "false" if nameid_format == "": name_id_policy = None else: if nameid_format is None: nameid_format = self.config.getattr("name_id_format", "sp") # If no nameid_format has been set in the configuration # or passed in then transient is the default. if nameid_format is None: nameid_format = NAMEID_FORMAT_TRANSIENT # If a list has been configured or passed in choose the # first since NameIDPolicy can only have one format specified. elif isinstance(nameid_format, list): nameid_format = nameid_format[0] # Allow a deployer to signal that no format should be specified # in the NameIDPolicy by passing in or configuring the string 'None'. elif nameid_format == 'None': nameid_format = None name_id_policy = samlp.NameIDPolicy(allow_create=allow_create, format=nameid_format) if name_id_policy and vorg: try: name_id_policy.sp_name_qualifier = vorg name_id_policy.format = saml.NAMEID_FORMAT_PERSISTENT except KeyError: pass args["name_id_policy"] = name_id_policy try: nsprefix = kwargs["nsprefix"] except KeyError: nsprefix = None try: force_authn = kwargs['force_authn'] except KeyError: force_authn = self.config.getattr('force_authn', 'sp') finally: if force_authn: args['force_authn'] = 'true' conf_sp_type = self.config.getattr('sp_type', 'sp') conf_sp_type_in_md = self.config.getattr('sp_type_in_metadata', 'sp') if conf_sp_type and conf_sp_type_in_md is False: if not extensions: extensions = Extensions() item = sp_type.SPType(text=conf_sp_type) extensions.add_extension_element(item) requested_attrs = self.config.getattr('requested_attributes', 'sp') if requested_attrs: if not extensions: extensions = Extensions() attributemapsmods = [] for modname in attributemaps.__all__: attributemapsmods.append(getattr(attributemaps, modname)) items = [] for attr in requested_attrs: friendly_name = attr.get('friendly_name') name = attr.get('name') name_format = attr.get('name_format') is_required = str(attr.get('required', False)).lower() if not name and not friendly_name: raise ValueError( "Missing required attribute: '{}' or '{}'".format( 'name', 'friendly_name')) if not name: for mod in attributemapsmods: try: name = mod.MAP['to'][friendly_name] except KeyError: continue else: if not name_format: name_format = mod.MAP['identifier'] break if not friendly_name: for mod in attributemapsmods: try: friendly_name = mod.MAP['fro'][name] except KeyError: continue else: if not name_format: name_format = mod.MAP['identifier'] break items.append( requested_attributes.RequestedAttribute( is_required=is_required, name_format=name_format, friendly_name=friendly_name, name=name)) item = requested_attributes.RequestedAttributes( extension_elements=items) extensions.add_extension_element(item) if kwargs: _args, extensions = self._filter_args(AuthnRequest(), extensions, **kwargs) args.update(_args) try: del args["id"] except KeyError: pass if sign is None: sign = self.authn_requests_signed if (sign and self.sec.cert_handler.generate_cert()) or \ client_crt is not None: with self.lock: self.sec.cert_handler.update_cert(True, client_crt) if client_crt is not None: sign_prepare = True return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args) return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args)
def create_authn_request(self, destination, vorg="", scoping=None, binding=saml2.BINDING_HTTP_POST, nameid_format=None, service_url_binding=None, message_id=0, consent=None, extensions=None, sign=None, allow_create=None, sign_prepare=False, sign_alg=None, digest_alg=None, **kwargs): """ Creates an authentication request. :param destination: Where the request should be sent. :param vorg: The virtual organization the service belongs to. :param scoping: The scope of the request :param binding: The protocol to use for the Response !! :param nameid_format: Format of the NameID :param service_url_binding: Where the reply should be sent dependent on reply binding. :param message_id: The identifier for this request :param consent: Whether the principal have given her consent :param extensions: Possible extensions :param sign: Whether the request should be signed or not. :param sign_prepare: Whether the signature should be prepared or not. :param allow_create: If the identity provider is allowed, in the course of fulfilling the request, to create a new identifier to represent the principal. :param kwargs: Extra key word arguments :return: tuple of request ID and <samlp:AuthnRequest> instance """ client_crt = None if "client_crt" in kwargs: client_crt = kwargs["client_crt"] args = {} try: args["assertion_consumer_service_url"] = kwargs[ "assertion_consumer_service_urls"][0] del kwargs["assertion_consumer_service_urls"] except KeyError: try: args["assertion_consumer_service_url"] = kwargs[ "assertion_consumer_service_url"] del kwargs["assertion_consumer_service_url"] except KeyError: try: args["assertion_consumer_service_index"] = str( kwargs["assertion_consumer_service_index"]) del kwargs["assertion_consumer_service_index"] except KeyError: if service_url_binding is None: service_urls = self.service_urls(binding) else: service_urls = self.service_urls(service_url_binding) args["assertion_consumer_service_url"] = service_urls[0] try: args["provider_name"] = kwargs["provider_name"] except KeyError: if binding == BINDING_PAOS: pass else: args["provider_name"] = self._my_name() # Allow argument values either as class instances or as dictionaries # all of these have cardinality 0..1 _msg = AuthnRequest() for param in [ "scoping", "requested_authn_context", "conditions", "subject" ]: try: _item = kwargs[param] except KeyError: pass else: del kwargs[param] # either class instance or argument dictionary if isinstance(_item, _msg.child_class(param)): args[param] = _item elif isinstance(_item, dict): args[param] = RequestedAuthnContext(**_item) else: raise ValueError("%s or wrong type expected %s" % (_item, param)) try: args["name_id_policy"] = kwargs["name_id_policy"] del kwargs["name_id_policy"] except KeyError: if allow_create is None: allow_create = self.config.getattr( "name_id_format_allow_create", "sp") if allow_create is None: allow_create = "false" else: if allow_create is True: allow_create = "true" else: allow_create = "false" if nameid_format == "": name_id_policy = None else: if nameid_format is None: nameid_format = self.config.getattr("name_id_format", "sp") if nameid_format is None: nameid_format = NAMEID_FORMAT_TRANSIENT elif isinstance(nameid_format, list): # NameIDPolicy can only have one format specified nameid_format = nameid_format[0] name_id_policy = samlp.NameIDPolicy(allow_create=allow_create, format=nameid_format) if name_id_policy and vorg: try: name_id_policy.sp_name_qualifier = vorg name_id_policy.format = saml.NAMEID_FORMAT_PERSISTENT except KeyError: pass args["name_id_policy"] = name_id_policy try: nsprefix = kwargs["nsprefix"] except KeyError: nsprefix = None if kwargs: _args, extensions = self._filter_args(AuthnRequest(), extensions, **kwargs) args.update(_args) try: del args["id"] except KeyError: pass if sign is None: sign = self.authn_requests_signed if (sign and self.sec.cert_handler.generate_cert()) or \ client_crt is not None: with self.lock: self.sec.cert_handler.update_cert(True, client_crt) if client_crt is not None: sign_prepare = True return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args) return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args)
def create_authn_request(self, destination, vorg="", scoping=None, binding=saml2.BINDING_HTTP_POST, nameid_format=NAMEID_FORMAT_TRANSIENT, service_url_binding=None, message_id=0, consent=None, extensions=None, sign=None, allow_create=False, sign_prepare=False, **kwargs): """ Creates an authentication request. :param destination: Where the request should be sent. :param vorg: The virtual organization the service belongs to. :param scoping: The scope of the request :param binding: The protocol to use for the Response !! :param nameid_format: Format of the NameID :param service_url_binding: Where the reply should be sent dependent on reply binding. :param message_id: The identifier for this request :param consent: Whether the principal have given her consent :param extensions: Possible extensions :param sign: Whether the request should be signed or not. :param sign_prepare: Whether the signature should be prepared or not. :param allow_create: If the identity provider is allowed, in the course of fulfilling the request, to create a new identifier to represent the principal. :param kwargs: Extra key word arguments :return: tuple of request ID and <samlp:AuthnRequest> instance """ client_crt = None if "client_crt" in kwargs: client_crt = kwargs["client_crt"] args = {} try: args["assertion_consumer_service_url"] = kwargs[ "assertion_consumer_service_urls"][0] del kwargs["assertion_consumer_service_urls"] except KeyError: try: args["assertion_consumer_service_url"] = kwargs[ "assertion_consumer_service_url"] del kwargs["assertion_consumer_service_urls"] except KeyError: try: args["attribute_consuming_service_index"] = str( kwargs["attribute_consuming_service_index"]) del kwargs["attribute_consuming_service_index"] except KeyError: if service_url_binding is None: service_urls = self.service_urls(binding) else: service_urls = self.service_urls(service_url_binding) args["assertion_consumer_service_url"] = service_urls[0] try: args["provider_name"] = kwargs["provider_name"] except KeyError: if binding == BINDING_PAOS: pass else: args["provider_name"] = self._my_name() try: args["name_id_policy"] = kwargs["name_id_policy"] del kwargs["name_id_policy"] except KeyError: if allow_create: allow_create = "true" else: allow_create = "false" # Profile stuff, should be configurable if nameid_format is None: name_id_policy = samlp.NameIDPolicy( allow_create=allow_create, format=NAMEID_FORMAT_TRANSIENT) elif nameid_format == "": name_id_policy = None else: name_id_policy = samlp.NameIDPolicy(allow_create=allow_create, format=nameid_format) if name_id_policy and vorg: try: name_id_policy.sp_name_qualifier = vorg name_id_policy.format = saml.NAMEID_FORMAT_PERSISTENT except KeyError: pass args["name_id_policy"] = name_id_policy if kwargs: _args, extensions = self._filter_args(AuthnRequest(), extensions, **kwargs) args.update(_args) try: del args["id"] except KeyError: pass if (sign and self.sec.cert_handler.generate_cert()) or \ client_crt is not None: with self.lock: self.sec.cert_handler.update_cert(True, client_crt) if client_crt is not None: sign_prepare = True return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, **args) return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, **args)
def create_authn_request(self, destination, vorg="", scoping=None, binding=saml2.BINDING_HTTP_POST, nameid_format=None, service_url_binding=None, message_id=0, consent=None, extensions=None, sign=None, allow_create=None, sign_prepare=False, sign_alg=None, digest_alg=None, requested_attributes=None, **kwargs): """ Creates an authentication request. :param destination: Where the request should be sent. :param vorg: The virtual organization the service belongs to. :param scoping: The scope of the request :param binding: The protocol to use for the Response !! :param nameid_format: Format of the NameIDPolicy :param service_url_binding: Where the reply should be sent dependent on reply binding. :param message_id: The identifier for this request :param consent: Whether the principal have given her consent :param extensions: Possible extensions :param sign: Whether the request should be signed or not. :param sign_prepare: Whether the signature should be prepared or not. :param allow_create: If the identity provider is allowed, in the course of fulfilling the request, to create a new identifier to represent the principal. :param requested_attributes: A list of dicts which define attributes to be used as eIDAS Requested Attributes for this request. If not defined the configuration option requested_attributes will be used, if defined. The format is the same as the requested_attributes configuration option. :param kwargs: Extra key word arguments :return: either a tuple of request ID and <samlp:AuthnRequest> instance or a tuple of request ID and str when sign is set to True """ args = {} # AssertionConsumerServiceURL # AssertionConsumerServiceIndex hide_assertion_consumer_service = self.config.getattr( 'hide_assertion_consumer_service', 'sp') assertion_consumer_service_url = ( kwargs.pop("assertion_consumer_service_urls", [None])[0] or kwargs.pop("assertion_consumer_service_url", None)) assertion_consumer_service_index = kwargs.pop( "assertion_consumer_service_index", None) service_url = (self.service_urls(service_url_binding or binding) or [None])[0] if hide_assertion_consumer_service: args["assertion_consumer_service_url"] = None binding = None elif assertion_consumer_service_url: args[ "assertion_consumer_service_url"] = assertion_consumer_service_url elif assertion_consumer_service_index: args[ "assertion_consumer_service_index"] = assertion_consumer_service_index elif service_url: args["assertion_consumer_service_url"] = service_url # ProviderName provider_name = kwargs.get("provider_name") if not provider_name and binding != BINDING_PAOS: provider_name = self._my_name() args["provider_name"] = provider_name # Allow argument values either as class instances or as dictionaries # all of these have cardinality 0..1 _msg = AuthnRequest() for param in [ "scoping", "requested_authn_context", "conditions", "subject" ]: _item = kwargs.pop(param, None) if not _item: continue if isinstance(_item, _msg.child_class(param)): args[param] = _item elif isinstance(_item, dict): args[param] = RequestedAuthnContext(**_item) else: raise ValueError( "Wrong type for param {name}".format(name=param)) # NameIDPolicy nameid_policy_format_config = self.config.getattr( "name_id_policy_format", "sp") nameid_policy_format = (nameid_format or nameid_policy_format_config or None) allow_create_config = self.config.getattr( "name_id_format_allow_create", "sp") allow_create = ( None # SAML 2.0 errata says AllowCreate MUST NOT be used for transient ids if nameid_policy_format == NAMEID_FORMAT_TRANSIENT else allow_create if allow_create else str( bool(allow_create_config)).lower()) name_id_policy = ( kwargs.pop("name_id_policy", None) if "name_id_policy" in kwargs else None if not nameid_policy_format else samlp.NameIDPolicy( allow_create=allow_create, format=nameid_policy_format)) if name_id_policy and vorg: name_id_policy.sp_name_qualifier = vorg name_id_policy.format = nameid_policy_format or NAMEID_FORMAT_PERSISTENT args["name_id_policy"] = name_id_policy # eIDAS SPType conf_sp_type = self.config.getattr('sp_type', 'sp') conf_sp_type_in_md = self.config.getattr('sp_type_in_metadata', 'sp') if conf_sp_type and conf_sp_type_in_md is False: if not extensions: extensions = Extensions() item = sp_type.SPType(text=conf_sp_type) extensions.add_extension_element(item) # eIDAS RequestedAttributes requested_attrs = (requested_attributes or self.config.getattr('requested_attributes', 'sp') or []) if requested_attrs: req_attrs_node = create_requested_attribute_node( requested_attrs, self.config.attribute_converters) if not extensions: extensions = Extensions() extensions.add_extension_element(req_attrs_node) # ForceAuthn force_authn = str( kwargs.pop("force_authn", None) or self.config.getattr("force_authn", "sp")).lower() in [ "true", "1" ] if force_authn: kwargs["force_authn"] = "true" if kwargs: _args, extensions = self._filter_args(AuthnRequest(), extensions, **kwargs) args.update(_args) args.pop("id", None) client_crt = kwargs.get("client_crt") nsprefix = kwargs.get("nsprefix") sign = self.authn_requests_signed if sign is None else sign if (sign and self.sec.cert_handler.generate_cert() ) or client_crt is not None: with self.lock: self.sec.cert_handler.update_cert(True, client_crt) if client_crt is not None: sign_prepare = True msg = self._message( AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args, ) else: msg = self._message( AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args, ) return msg
def setup_class(self): self.name_id_policy = samlp.NameIDPolicy()
def authn_request(self, query_id, destination, service_url, spentityid, my_name="", vorg="", scoping=None, log=None, sign=None, binding=BINDING_HTTP_POST, nameid_format=saml.NAMEID_FORMAT_TRANSIENT, **kwargs): """ Creates an authentication request. :param query_id: The identifier for this request :param destination: Where the request should be sent. :param service_url: Where the reply should be sent. :param spentityid: The entity identifier for this service. :param my_name: The name of this service. :param vorg: The vitual organization the service belongs to. :param scoping: The scope of the request :param log: A service to which logs should be written :param sign: Whether the request should be signed or not. :param binding: The protocol to use for the Response !! :return: <samlp:AuthnRequest> instance added: we want additional kw arguments, namely is_passive """ request = samlp.AuthnRequest( id=query_id, version=VERSION, issue_instant=instant(), assertion_consumer_service_url=service_url, protocol_binding=binding, **kwargs) if destination: request.destination = destination if my_name: request.provider_name = my_name if scoping: request.scoping = scoping # Profile stuff, should be configurable if nameid_format == saml.NAMEID_FORMAT_TRANSIENT: name_id_policy = samlp.NameIDPolicy(allow_create="true", format=nameid_format) else: name_id_policy = samlp.NameIDPolicy(format=nameid_format) if vorg: try: name_id_policy.sp_name_qualifier = vorg name_id_policy.format = saml.NAMEID_FORMAT_PERSISTENT except KeyError: pass if sign is None: sign = self.authn_requests_signed if sign: request.signature = pre_signature_part(request.id, self.sec.my_cert, 1) to_sign = [(class_name(request), request.id)] else: to_sign = [] request.name_id_policy = name_id_policy request.issuer = self._issuer(spentityid) logger.info("REQUEST: %s" % request) return signed_instance_factory(request, self.sec, to_sign)
def create_authn_request(self, destination, vorg="", scoping=None, binding=saml2.BINDING_HTTP_POST, nameid_format=NAMEID_FORMAT_TRANSIENT, service_url_binding=None, id=0, consent=None, extensions=None, sign=None, allow_create=False): """ Creates an authentication request. :param destination: Where the request should be sent. :param vorg: The virtual organization the service belongs to. :param scoping: The scope of the request :param binding: The protocol to use for the Response !! :param nameid_format: Format of the NameID :param service_url_binding: Where the reply should be sent dependent on reply binding. :param id: The identifier for this request :param consent: Whether the principal have given her consent :param extensions: Possible extensions :param sign: Whether the request should be signed or not. :param allow_create: If the identity provider is allowed, in the course of fulfilling the request, to create a new identifier to represent the principal. :return: <samlp:AuthnRequest> instance """ if service_url_binding is None: service_url = self.service_url(binding) else: service_url = self.service_url(service_url_binding) if binding == BINDING_PAOS: my_name = None location = None else: my_name = self._my_name() if allow_create: allow_create = "true" else: allow_create = "false" # Profile stuff, should be configurable if nameid_format is None or nameid_format == NAMEID_FORMAT_TRANSIENT: name_id_policy = samlp.NameIDPolicy(allow_create=allow_create, format=NAMEID_FORMAT_TRANSIENT) else: name_id_policy = samlp.NameIDPolicy(allow_create=allow_create, format=nameid_format) if vorg: try: name_id_policy.sp_name_qualifier = vorg name_id_policy.format = saml.NAMEID_FORMAT_PERSISTENT except KeyError: pass return self._message(AuthnRequest, destination, id, consent, extensions, sign, assertion_consumer_service_url=service_url, protocol_binding=binding, name_id_policy=name_id_policy, provider_name=my_name, scoping=scoping)