Ejemplo n.º 1
0
    def test_start_auth_no_request_info(self, sp_conf):
        """
        Performs a complete test for the module satosa.backends.saml2. The flow should be accepted.
        """
        disco_srv = "https://my.dicso.com/role/idp.ds"
        samlbackend = SamlBackend(
            None, INTERNAL_ATTRIBUTES, {
                "config": sp_conf,
                "disco_srv": disco_srv,
                "state_id": "saml_backend_test_id"
            })
        internal_data = InternalRequest(None, None)

        state = State()
        context = Context()
        context.state = state
        resp = samlbackend.start_auth(context, internal_data)
        assert resp.status == "303 See Other", "Must be a redirect to the discovery server."
        assert resp.message.startswith("https://my.dicso.com/role/idp.ds"), \
            "Redirect to wrong URL."

        # create_name_id_policy_transient()
        state = State()
        context = Context()
        context.state = state
        user_id_hash_type = UserIdHashType.transient
        internal_data = InternalRequest(user_id_hash_type, None)
        resp = samlbackend.start_auth(context, internal_data)
        assert resp.status == "303 See Other", "Must be a redirect to the discovery server."
Ejemplo n.º 2
0
    def test_auth_req_callback_stores_state_for_consent(self, context, satosa_config):
        base = SATOSABase(satosa_config)

        context.target_backend = satosa_config["BACKEND_MODULES"][0]["name"]
        requester_name = [{"lang": "en", "text": "Test EN"}, {"lang": "sv", "text": "Test SV"}]
        internal_req = InternalRequest(UserIdHashType.transient, None, requester_name)
        internal_req.approved_attributes = ["attr1", "attr2"]
        base._auth_req_callback_func(context, internal_req)

        assert context.state[consent.STATE_KEY]["requester_name"] == internal_req.requester_name
        assert context.state[consent.STATE_KEY]["filter"] == internal_req.approved_attributes
Ejemplo n.º 3
0
    def test_allow_one_requester(self, target_context):
        rules = {
            TARGET_ENTITY: {
                "allow": ["test_requester"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, "test_requester", None)
        assert decide_service.process(target_context, req)

        req.requester = "somebody else"
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Ejemplo n.º 4
0
    def test_allow_one_requester(self, target_context):
        rules = {
            TARGET_ENTITY: {
                "allow": ["test_requester"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, "test_requester", None)
        assert decide_service.process(target_context, req)

        req.requester = "somebody else"
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Ejemplo n.º 5
0
    def test_entire_flow(self, context):
        """Tests start of authentication (incoming auth req) and receiving auth response."""
        responses.add(responses.POST,
                      "https://graph.facebook.com/v2.5/oauth/access_token",
                      body=json.dumps({
                          "access_token": "qwerty",
                          "token_type": "bearer",
                          "expires_in": 9999999999999
                      }),
                      status=200,
                      content_type='application/json')
        self.setup_facebook_response()

        context.path = 'facebook/sso/redirect'
        internal_request = InternalRequest(UserIdHashType.transient,
                                           'test_requester')

        self.fb_backend.start_auth(context, internal_request, mock_get_state)
        context.request = {
            "code": FB_RESPONSE_CODE,
            "state": mock_get_state.return_value
        }
        self.fb_backend._authn_response(context)
        assert self.fb_backend.name not in context.state
        self.assert_expected_attributes()
Ejemplo n.º 6
0
    def test_defaults_to_allow_all_requesters_for_target_entity_without_specific_rules(
            self, target_context):
        rules = {"some other entity": {"allow": ["foobar"]}}
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, "test_requester", None)
        assert decide_service.process(target_context, req)
Ejemplo n.º 7
0
    def disco_response(self, context):
        """
        Endpoint for the discovery server response

        :type context: satosa.context.Context
        :rtype: satosa.response.Response

        :param context: The current context
        :return: response
        """
        info = context.request

        state = context.state

        try:
            entity_id = info[self.idp_disco_query_param]
        except KeyError as err:
            satosa_logging(LOGGER,
                           logging.DEBUG,
                           "No IDP chosen for state",
                           state,
                           exc_info=True)
            raise SATOSAAuthenticationError(state, "No IDP chosen") from err
        else:
            request_info = InternalRequest(None, None)
            return self.authn_request(context, entity_id, request_info)
Ejemplo n.º 8
0
    def test_with_pyoidc(self):
        responses.add(responses.POST,
                      "https://graph.facebook.com/v2.5/oauth/access_token",
                      body=json.dumps({
                          "access_token": "qwerty",
                          "token_type": "bearer",
                          "expires_in": 9999999999999
                      }),
                      adding_headers={"set-cookie": "TEST=testing; path=/"},
                      status=200,
                      content_type='application/json')
        responses.add(responses.GET,
                      "https://graph.facebook.com/v2.5/me",
                      match_querystring=False,
                      body=json.dumps(FB_RESPONSE),
                      status=200,
                      content_type='application/json')

        context = Context()
        context.path = 'facebook/sso/redirect'
        context.state = State()
        internal_request = InternalRequest(UserIdHashType.transient,
                                           'http://localhost:8087/sp.xml')
        get_state = Mock()
        get_state.return_value = STATE
        resp = self.fb_backend.start_auth(context, internal_request, get_state)
        context.cookie = resp.headers[0][1]
        context.request = {"code": FB_RESPONSE_CODE, "state": STATE}
        self.fb_backend.auth_callback_func = self.verify_callback
        self.fb_backend.authn_response(context)
Ejemplo n.º 9
0
    def test_auth_resp_callback_func_user_id_from_attrs_is_used_to_override_user_id(
            self, context, satosa_config):
        satosa_config["INTERNAL_ATTRIBUTES"]["user_id_from_attrs"] = [
            "user_id", "domain"
        ]
        base = SATOSABase(satosa_config)

        internal_resp = InternalResponse(AuthenticationInformation("", "", ""))
        internal_resp.attributes = {
            "user_id": ["user"],
            "domain": ["@example.com"]
        }
        internal_resp.requester = "test_requester"
        context.state[satosa.base.STATE_KEY] = {"requester": "test_requester"}
        context.state[satosa.routing.
                      STATE_KEY] = satosa_config["FRONTEND_MODULES"][0]["name"]
        UserIdHasher.save_state(InternalRequest(UserIdHashType.persistent, ""),
                                context.state)

        base._auth_resp_callback_func(context, internal_resp)

        expected_user_id = UserIdHasher.hash_data(
            satosa_config["USER_ID_HASH_SALT"], "*****@*****.**")
        expected_user_id = UserIdHasher.hash_id(
            satosa_config["USER_ID_HASH_SALT"], expected_user_id,
            internal_resp.requester, context.state)
        assert internal_resp.user_id == expected_user_id
Ejemplo n.º 10
0
    def handle_authn_request(self, context):
        """
        Parse and verify the authentication request and pass it on to the backend.
        :type context: satosa.context.Context
        :rtype: oic.utils.http_util.Response

        :param context: the current context
        :return: HTTP response to the client
        """

        # verify auth req (correct redirect_uri, contains nonce and response_type='id_token')
        request = urlencode(context.request)
        satosa_logging(LOGGER, logging.DEBUG,
                       "Authn req from client: {}".format(request),
                       context.state)

        info = self.provider.auth_init(request,
                                       request_class=AuthorizationRequest)
        if isinstance(info, Response):
            satosa_logging(LOGGER, logging.ERROR,
                           "Error in authn req: {}".format(info.message),
                           context.state)
            return info

        client_id = info["areq"]["client_id"]

        context.state.add(self.state_id, {"oidc_request": request})
        hash_type = oidc_subject_type_to_hash_type(
            self.provider.cdb[client_id].get("subject_type",
                                             self.subject_type_default))
        internal_req = InternalRequest(
            hash_type, client_id,
            self.provider.cdb[client_id].get("client_name"))

        return self.auth_req_callback_func(context, internal_req)
Ejemplo n.º 11
0
    def test_start_auth_name_id_policy(self, sp_conf):
        """
        Performs a complete test for the module satosa.backends.saml2. The flow should be accepted.
        """
        samlbackend = SamlBackend(
            None, INTERNAL_ATTRIBUTES, {
                "config": sp_conf,
                "disco_srv": "https://my.dicso.com/role/idp.ds",
                "state_id": "saml_backend_test_id"
            })
        test_state_key = "sauyghj34589fdh"

        state = State()
        state.add(test_state_key, "my_state")
        context = Context()
        context.state = state

        internal_req = InternalRequest(UserIdHashType.transient, None)
        resp = samlbackend.start_auth(context, internal_req)

        assert resp.status == "303 See Other", "Must be a redirect to the discovery server."

        disco_resp = parse_qs(urlparse(resp.message).query)
        sp_disco_resp = \
            sp_conf["service"]["sp"]["endpoints"]["discovery_response"][0][0]
        assert "return" in disco_resp and disco_resp["return"][0].startswith(sp_disco_resp), \
            "Not a valid return url in the call to the discovery server"
        assert "entityID" in disco_resp and disco_resp["entityID"][0] == sp_conf["entityid"], \
            "Not a valid entity id in the call to the discovery server"

        request_info_tmp = context.state
        assert request_info_tmp.get(
            test_state_key) == "my_state", "Wrong state!"
Ejemplo n.º 12
0
def _get_id(requestor, user_id, hash_type):
    state = State()

    internal_request = InternalRequest(hash_type, requestor)

    UserIdHasher.save_state(internal_request, state)

    return UserIdHasher.hash_id(SALT, user_id, requestor, state)
Ejemplo n.º 13
0
    def test_allow_takes_precedence_over_deny_all(self, target_context):
        requester = "test_requester"
        rules = {
            TARGET_ENTITY: {
                "allow": requester,
                "deny": ["*"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, requester, None)

        assert decide_service.process(target_context, req)

        req.requester = "somebody else"
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Ejemplo n.º 14
0
    def test_start_auth_redirects_directly_to_mirrored_idp(
            self, context, idp_conf):
        context.internal_data["mirror.target_entity_id"] = urlsafe_b64encode(
            idp_conf["entityid"].encode("utf-8")).decode("utf-8")

        resp = self.samlbackend.start_auth(context,
                                           InternalRequest(None, None))
        self.assert_redirect_to_idp(resp, idp_conf)
Ejemplo n.º 15
0
    def test_allow_takes_precedence_over_deny_all(self, target_context):
        requester = "test_requester"
        rules = {
            TARGET_ENTITY: {
                "allow": requester,
                "deny": ["*"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, requester, None)

        assert decide_service.process(target_context, req)

        req.requester = "somebody else"
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Ejemplo n.º 16
0
    def test_allow_all_requesters(self, target_context, requester):
        rules = {
            TARGET_ENTITY: {
                "allow": ["*"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, requester, None)
        assert decide_service.process(target_context, req)
Ejemplo n.º 17
0
    def test_start_auth_redirects_directly_to_mirrored_idp(
            self, context, idp_conf):
        entityid = idp_conf["entityid"]
        entityid_bytes = entityid.encode("utf-8")
        entityid_b64_str = urlsafe_b64encode(entityid_bytes).decode("utf-8")
        context.decorate(Context.KEY_MIRROR_TARGET_ENTITYID, entityid_b64_str)

        resp = self.samlbackend.start_auth(context,
                                           InternalRequest(None, None))
        self.assert_redirect_to_idp(resp, idp_conf)
Ejemplo n.º 18
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"
        ])
Ejemplo n.º 19
0
    def test_deny_one_requester(self, target_context):
        rules = {
            TARGET_ENTITY: {
                "deny": ["test_requester"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, "test_requester", None)
        with pytest.raises(SATOSAError):
            assert decide_service.process(target_context, req)
Ejemplo n.º 20
0
    def test_deny_all_requesters(self, target_context, requester):
        rules = {
            TARGET_ENTITY: {
                "deny": ["*"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, requester, None)
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Ejemplo n.º 21
0
    def test_redirect_to_idp_if_only_one_idp_in_metadata(
            self, context, sp_conf, idp_conf):
        sp_conf["metadata"]["inline"] = [
            create_metadata_from_config_dict(idp_conf)
        ]
        # instantiate new backend, without any discovery service configured
        samlbackend = SAMLBackend(None, INTERNAL_ATTRIBUTES,
                                  {"sp_config": sp_conf}, "base_url",
                                  "saml_backend")

        resp = samlbackend.start_auth(context, InternalRequest(None, None))
        self.assert_redirect_to_idp(resp, idp_conf)
Ejemplo n.º 22
0
    def test_missing_target_entity_id_from_context(self, context):
        target_entity = "entity1"
        rules = {
            target_entity: {
                "deny": ["*"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalRequest(None, "test_requester", None)
        with pytest.raises(SATOSAError):
            decide_service.process(context, req)
Ejemplo n.º 23
0
    def test_auth_req_callback_stores_state_for_consent(
            self, context, satosa_config):
        base = SATOSABase(satosa_config)

        context.target_backend = satosa_config["BACKEND_MODULES"][0]["name"]
        requester_name = [{
            "lang": "en",
            "text": "Test EN"
        }, {
            "lang": "sv",
            "text": "Test SV"
        }]
        internal_req = InternalRequest(UserIdHashType.transient, None,
                                       requester_name)
        internal_req.approved_attributes = ["attr1", "attr2"]
        base._auth_req_callback_func(context, internal_req)

        assert context.state[
            consent.STATE_KEY]["requester_name"] == internal_req.requester_name
        assert context.state[
            consent.STATE_KEY]["filter"] == internal_req.approved_attributes
Ejemplo n.º 24
0
 def test_always_redirect_to_discovery_service_if_using_mdq(
         self, context, sp_conf, idp_conf):
     # one IdP in the metadata, but MDQ also configured so should always redirect to the discovery service
     sp_conf["metadata"]["inline"] = [
         create_metadata_from_config_dict(idp_conf)
     ]
     sp_conf["metadata"]["mdq"] = ["https://mdq.example.com"]
     samlbackend = SAMLBackend(None, INTERNAL_ATTRIBUTES, {
         "sp_config": sp_conf,
         "disco_srv": DISCOSRV_URL,
     }, "base_url", "saml_backend")
     resp = samlbackend.start_auth(context, InternalRequest(None, None))
     self.assert_redirect_to_discovery_server(resp, sp_conf)
Ejemplo n.º 25
0
    def test_auth_resp_callback_func_respects_user_id_to_attr(
            self, context, satosa_config):
        satosa_config["INTERNAL_ATTRIBUTES"]["user_id_to_attr"] = "user_id"
        base = SATOSABase(satosa_config)

        internal_resp = InternalResponse(AuthenticationInformation("", "", ""))
        internal_resp.user_id = "user1234"
        context.state[satosa.base.STATE_KEY] = {"requester": "test_requester"}
        context.state[satosa.routing.
                      STATE_KEY] = satosa_config["FRONTEND_MODULES"][0]["name"]
        UserIdHasher.save_state(InternalRequest(UserIdHashType.transient, ""),
                                context.state)

        base._auth_resp_callback_func(context, internal_resp)
        assert internal_resp.attributes["user_id"] == [internal_resp.user_id]
Ejemplo n.º 26
0
    def test_start_auth(self, context):
        context.path = 'facebook/sso/redirect'
        internal_request = InternalRequest(UserIdHashType.transient,
                                           'test_requester')

        resp = self.fb_backend.start_auth(context, internal_request,
                                          mock_get_state)
        login_url = resp.message
        assert login_url.startswith(FB_AUTH_ENDPOINT)
        expected_params = {
            "client_id": CLIENT_ID,
            "state": mock_get_state.return_value,
            "response_type": "code",
            "redirect_uri": "%s/%s" % (BASE_URL, AUTHZ_PAGE)
        }
        actual_params = dict(parse_qsl(urlparse(login_url).query))
        assert actual_params == expected_params
Ejemplo n.º 27
0
    def test_full_flow(self, context, idp_conf, sp_conf):
        test_state_key = "test_state_key_456afgrh"
        response_binding = BINDING_HTTP_REDIRECT
        fakeidp = FakeIdP(USERS,
                          config=IdPConfig().load(idp_conf,
                                                  metadata_construction=False))

        context.state[test_state_key] = "my_state"

        # start auth flow (redirecting to discovery server)
        resp = self.samlbackend.start_auth(context,
                                           InternalRequest(None, None))
        self.assert_redirect_to_discovery_server(resp, sp_conf)

        # fake response from discovery server
        disco_resp = parse_qs(urlparse(resp.message).query)
        info = parse_qs(urlparse(disco_resp["return"][0]).query)
        info["entityID"] = idp_conf["entityid"]
        request_context = Context()
        request_context.request = info
        request_context.state = context.state

        # pass discovery response to backend and check that it redirects to the selected IdP
        resp = self.samlbackend.disco_response(request_context)
        self.assert_redirect_to_idp(resp, idp_conf)

        # fake auth response to the auth request
        req_params = dict(parse_qsl(urlparse(resp.message).query))
        url, fake_idp_resp = fakeidp.handle_auth_req(
            req_params["SAMLRequest"],
            req_params["RelayState"],
            BINDING_HTTP_REDIRECT,
            "testuser1",
            response_binding=response_binding)
        response_context = Context()
        response_context.request = fake_idp_resp
        response_context.state = request_context.state

        # pass auth response to backend and verify behavior
        self.samlbackend.authn_response(response_context, response_binding)
        context, internal_resp = self.samlbackend.auth_callback_func.call_args[
            0]
        assert self.samlbackend.name not in context.state
        assert context.state[test_state_key] == "my_state"
        self.assert_authn_response(internal_resp)
Ejemplo n.º 28
0
 def test_authn_response(self):
     context = Context()
     context.path = 'facebook/sso/redirect'
     context.state = State()
     internal_request = InternalRequest(UserIdHashType.transient,
                                        'http://localhost:8087/sp.xml')
     get_state = Mock()
     get_state.return_value = STATE
     resp = self.fb_backend.start_auth(context, internal_request, get_state)
     context.cookie = resp.headers[0][1]
     context.request = {"code": FB_RESPONSE_CODE, "state": STATE}
     # context.request = json.dumps(context.request)
     self.fb_backend.auth_callback_func = self.verify_callback
     tmp_consumer = self.fb_backend.get_consumer()
     tmp_consumer.do_access_token_request = self.verify_do_access_token_request
     self.fb_backend.get_consumer = Mock()
     self.fb_backend.get_consumer.return_value = tmp_consumer
     self.fb_backend.request_fb = self.verify_request_fb
     self.fb_backend.authn_response(context)
Ejemplo n.º 29
0
 def test_start_auth(self):
     context = Context()
     context.path = 'facebook/sso/redirect'
     context.state = State()
     internal_request = InternalRequest(UserIdHashType.transient,
                                        'http://localhost:8087/sp.xml')
     get_state = Mock()
     get_state.return_value = STATE
     resp = self.fb_backend.start_auth(context, internal_request, get_state)
     # assert resp.headers[0][0] == "Set-Cookie", "Not the correct return cookie"
     # assert len(resp.headers[0][1]) > 1, "Not the correct return cookie"
     resp_url = resp.message.split("?")
     test_url = FB_REDIRECT_URL.split("?")
     resp_attr = parse_qs(resp_url[1])
     test_attr = parse_qs(test_url[1])
     assert resp_url[0] == test_url[0]
     assert len(resp_attr) == len(test_attr), "Redirect url is not correct!"
     for key in test_attr:
         assert key in resp_attr, "Redirect url is not correct!"
         assert test_attr[key] == resp_attr[
             key], "Redirect url is not correct!"
Ejemplo n.º 30
0
    def test_auth_resp_callback_func_hashes_all_specified_attributes(
            self, context, satosa_config):
        satosa_config["INTERNAL_ATTRIBUTES"]["hash"] = ["user_id", "mail"]
        base = SATOSABase(satosa_config)

        attributes = {
            "user_id": ["user"],
            "mail": ["*****@*****.**", "*****@*****.**"]
        }
        internal_resp = InternalResponse(AuthenticationInformation("", "", ""))
        internal_resp.attributes = copy.copy(attributes)
        internal_resp.user_id = "test_user"
        UserIdHasher.save_state(InternalRequest(UserIdHashType.transient, ""),
                                context.state)
        context.state[satosa.base.STATE_KEY] = {"requester": "test_requester"}
        context.state[satosa.routing.
                      STATE_KEY] = satosa_config["FRONTEND_MODULES"][0]["name"]

        base._auth_resp_callback_func(context, internal_resp)
        for attr in satosa_config["INTERNAL_ATTRIBUTES"]["hash"]:
            assert internal_resp.attributes[attr] == [
                UserIdHasher.hash_data(satosa_config["USER_ID_HASH_SALT"], v)
                for v in attributes[attr]
            ]
Ejemplo n.º 31
0
    def test_redirect_to_idp_if_only_one_idp_in_metadata(
            self, sp_conf, idp_conf):
        sp_conf["metadata"]["inline"] = [
            create_metadata_from_config_dict(idp_conf)
        ]
        samlbackend = SamlBackend(None, INTERNAL_ATTRIBUTES, {
            "config": sp_conf,
            "state_id": "saml_backend_test_id"
        })

        state = State()
        state.add("test", "state")
        context = Context()
        context.state = state
        internal_req = InternalRequest(UserIdHashType.transient, None)

        resp = samlbackend.start_auth(context, internal_req)

        assert resp.status == "303 See Other"
        parsed = urlparse(resp.message)
        assert "{parsed.scheme}://{parsed.netloc}{parsed.path}".format(
                parsed=parsed) == \
               idp_conf["service"]["idp"]["endpoints"]["single_sign_on_service"][0][0]
        assert "SAMLRequest" in parse_qs(parsed.query)
Ejemplo n.º 32
0
def internal_request():
    req = InternalRequest(UserIdHashType.persistent, "example_requestor")
    req.add_filter(FILTER)
    return req
Ejemplo n.º 33
0
 def handle_request(self, context):
     internal_req = InternalRequest(UserIdHashType.transient, "test_client", None)
     return self.auth_req_callback_func(context, internal_req)
Ejemplo n.º 34
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)
Ejemplo n.º 35
0
def internal_request():
    req = InternalRequest(UserIdHashType.persistent, "example_requestor")
    req.add_filter(FILTER)
    return req
Ejemplo n.º 36
0
 def internal_request(self):
     req = InternalRequest(UserIdHashType.persistent, "example_requester")
     req.approved_attributes = FILTER + ["sn"]
     return req