Exemple #1
0
    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"
        ])
Exemple #2
0
    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"])
Exemple #3
0
    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)
Exemple #4
0
    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)