def test_get_filter_attributes_with_sp_requested_attributes_without_friendlyname( self, idp_conf): sp_metadata_str = """<?xml version="1.0"?> <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://sp.example.com"> <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol"> <md:AttributeConsumingService> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> </md:AttributeConsumingService> </md:SPSSODescriptor> </md:EntityDescriptor> """ idp_conf["metadata"] = {"inline": [sp_metadata_str]} base = self.construct_base_url_from_entity_id(idp_conf["entityid"]) conf = { "idp_config": idp_conf, "endpoints": ENDPOINTS, "base": base, "state_id": "state_id" } internal_attributes = { "attributes": { attr_name: { "saml": [attr_name] } for attr_name in [ "edupersontargetedid", "edupersonprincipalname", "edupersonaffiliation", "mail", "displayname", "sn", "givenname" ] } } # no op mapping for saml attribute names samlfrontend = SamlFrontend(None, internal_attributes, conf) samlfrontend.register_endpoints(["testprovider"]) internal_req = InternalRequest( saml_name_format_to_hash_type(NAMEID_FORMAT_PERSISTENT), "http://sp.example.com", "Example SP") filtered_attributes = samlfrontend.get_filter_attributes( samlfrontend.idp, samlfrontend.idp.config.getattr("policy", "idp"), internal_req.requestor, None) assert set(filtered_attributes) == set([ "edupersontargetedid", "edupersonprincipalname", "edupersonaffiliation", "mail", "displayname", "sn", "givenname" ])
def test_get_filter_attributes_with_sp_requested_attributes_without_friendlyname(self, idp_conf): sp_metadata_str = """<?xml version="1.0"?> <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://sp.example.com"> <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol"> <md:AttributeConsumingService> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> </md:AttributeConsumingService> </md:SPSSODescriptor> </md:EntityDescriptor> """ idp_conf["metadata"] = {"inline": [sp_metadata_str]} base = self.construct_base_url_from_entity_id(idp_conf["entityid"]) conf = {"idp_config": idp_conf, "endpoints": ENDPOINTS, "base": base, "state_id": "state_id"} internal_attributes = {"attributes": {attr_name: {"saml": [attr_name]} for attr_name in ["edupersontargetedid", "edupersonprincipalname", "edupersonaffiliation", "mail", "displayname", "sn", "givenname"]}} # no op mapping for saml attribute names samlfrontend = SamlFrontend(None, internal_attributes, conf) samlfrontend.register_endpoints(["testprovider"]) internal_req = InternalRequest(saml_name_format_to_hash_type(NAMEID_FORMAT_PERSISTENT), "http://sp.example.com", "Example SP") filtered_attributes = samlfrontend.get_filter_attributes(samlfrontend.idp, samlfrontend.idp.config.getattr( "policy", "idp"), internal_req.requestor, None) assert set(filtered_attributes) == set( ["edupersontargetedid", "edupersonprincipalname", "edupersonaffiliation", "mail", "displayname", "sn", "givenname"])
def _handle_authn_request(self, context, binding_in, idp): """ See doc for handle_authn_request method. :type context: satosa.context.Context :type binding_in: str :type idp: saml.server.Server :rtype: satosa.response.Response :param context: The current context :param binding_in: The pysaml binding type :param idp: The saml frontend idp server :return: response """ request = context.request try: extracted_request = self.extract_request(idp, request["SAMLRequest"], binding_in, context.state) except UnknownPrincipal as excp: satosa_logging(LOGGER, logging.ERROR, "UnknownPrincipal", context.state, exc_info=True) return ServiceError("UnknownPrincipal: %s" % excp) except UnsupportedBinding as excp: satosa_logging(LOGGER, logging.ERROR, "UnsupportedBinding", context.state, exc_info=True) return ServiceError("UnsupportedBinding: %s" % excp) _binding = extracted_request["resp_args"]["binding"] if extracted_request["response"]: # An error response http_args = idp.apply_binding( _binding, "%s" % extracted_request["response"], extracted_request["resp_args"]["destination"], request["RelayState"], response=True, ) satosa_logging(LOGGER, logging.DEBUG, "HTTPargs: %s" % http_args, context.state, exc_info=True) return response(_binding, http_args) else: try: context.internal_data["saml2.target_entity_id"] = request["entityID"] except KeyError: pass request_state = self.save_state( context, idp.response_args(extracted_request["authn_req"]), request["RelayState"] ) context.state.add(self.state_id, request_state) extensions = idp.metadata.extension( extracted_request["resp_args"]["sp_entity_id"], "spsso_descriptor", "urn:oasis:names:tc:SAML:metadata:ui&UIInfo", ) requester_name = None try: requester_name = extensions[0]["display_name"] except IndexError: pass name_format = None if "name_id_policy" in extracted_request["req_args"]: name_format = saml_name_format_to_hash_type(extracted_request["req_args"]["name_id_policy"].format) if name_format is None: # default to requesting transient name id name_format = UserIdHashType.transient internal_req = InternalRequest(name_format, extracted_request["resp_args"]["sp_entity_id"], requester_name) # Get attribute filter idp_policy = idp.config.getattr("policy", "idp") if idp_policy: attribute_filter = self.get_filter_attributes(idp, idp_policy, internal_req.requestor, context.state) internal_req.add_filter(attribute_filter) return self.auth_req_callback_func(context, internal_req)
def _handle_authn_request(self, context, binding_in, idp): """ See doc for handle_authn_request method. :type context: satosa.context.Context :type binding_in: str :type idp: saml.server.Server :rtype: satosa.response.Response :param context: The current context :param binding_in: The pysaml binding type :param idp: The saml frontend idp server :return: response """ request = context.request try: extracted_request = self.extract_request(idp, request["SAMLRequest"], binding_in, context.state) except UnknownPrincipal as excp: satosa_logging(LOGGER, logging.ERROR, "UnknownPrincipal", context.state, exc_info=True) return ServiceError("UnknownPrincipal: %s" % excp) except UnsupportedBinding as excp: satosa_logging(LOGGER, logging.ERROR, "UnsupportedBinding", context.state, exc_info=True) return ServiceError("UnsupportedBinding: %s" % excp) _binding = extracted_request["resp_args"]["binding"] if extracted_request["response"]: # An error response http_args = idp.apply_binding( _binding, "%s" % extracted_request["response"], extracted_request["resp_args"]["destination"], request["RelayState"], response=True) satosa_logging(LOGGER, logging.DEBUG, "HTTPargs: %s" % http_args, context.state, exc_info=True) return response(_binding, http_args) else: try: context.internal_data["saml2.target_entity_id"] = request["entityID"] except KeyError: pass request_state = self.save_state(context, idp.response_args(extracted_request["authn_req"]), request["RelayState"]) context.state.add(self.state_id, request_state) extensions = idp.metadata.extension( extracted_request['resp_args']['sp_entity_id'], 'spsso_descriptor', 'urn:oasis:names:tc:SAML:metadata:ui&UIInfo' ) requester_name = None try: requester_name = extensions[0]['display_name'] except IndexError: pass name_format = None if 'name_id_policy' in extracted_request['req_args']: name_format = saml_name_format_to_hash_type( extracted_request['req_args']['name_id_policy'].format) if name_format is None: # default to requesting transient name id name_format = UserIdHashType.transient internal_req = InternalRequest(name_format, extracted_request["resp_args"]["sp_entity_id"], requester_name) # Get attribute filter idp_policy = idp.config.getattr("policy", "idp") if idp_policy: attribute_filter = self.get_filter_attributes(idp, idp_policy, internal_req.requestor, context.state) internal_req.add_filter(attribute_filter) return self.auth_req_callback_func(context, internal_req)