Пример #1
0
    def test_attributes_general(self, ldap_attribute_store):
        ldap_to_internal_map = (self.ldap_attribute_store_config['default']
                                ['ldap_to_internal_map'])

        for dn, attributes in self.ldap_person_records:
            # Mock up the internal response the LDAP attribute store is
            # expecting to receive.
            response = InternalData(auth_info=AuthenticationInformation())

            # The LDAP attribute store configuration and the mock records
            # expect to use a LDAP search filter for the uid attribute.
            uid = attributes['uid']
            response.attributes = {'uid': uid}

            context = Context()
            context.state = dict()

            ldap_attribute_store.process(context, response)

            # Verify that the LDAP attribute store has retrieved the mock
            # records from the mock LDAP server and has added the appropriate
            # internal attributes.
            for ldap_attr, ldap_value in attributes.items():
                if ldap_attr in ldap_to_internal_map:
                    internal_attr = ldap_to_internal_map[ldap_attr]
                    response_attr = response.attributes[internal_attr]
                    assert(ldap_value in response_attr)
Пример #2
0
 def internal_response(self):
     auth_info = AuthenticationInformation("auth_class_ref", "timestamp",
                                           "issuer")
     internal_response = InternalData(auth_info=auth_info)
     internal_response.requester = "client"
     internal_response.attributes = ATTRIBUTES
     return internal_response
Пример #3
0
    def _authn_response(self, context):
        """
        Handles the authentication response from the AS.

        :type context: satosa.context.Context
        :rtype: satosa.response.Response
        :param context: The context in SATOSA
        :return: A SATOSA response. This method is only responsible to call the callback function
        which generates the Response object.
        """
        state_data = context.state[self.name]
        aresp = self.consumer.parse_response(AuthorizationResponse,
                                             info=json.dumps(context.request))
        self._verify_state(aresp, state_data, context.state)

        rargs = {
            "code": aresp["code"],
            "redirect_uri": self.redirect_url,
            "state": state_data["state"]
        }

        atresp = self.consumer.do_access_token_request(request_args=rargs,
                                                       state=aresp["state"])
        if "verify_accesstoken_state" not in self.config or self.config[
                "verify_accesstoken_state"]:
            self._verify_state(atresp, state_data, context.state)

        user_info = self.user_information(atresp["access_token"])
        internal_response = InternalData(
            auth_info=self.auth_info(context.request))
        internal_response.attributes = self.converter.to_internal(
            self.external_type, user_info)
        internal_response.subject_id = user_info[self.user_id_attr]
        del context.state[self.name]
        return self.auth_callback_func(context, internal_response)
Пример #4
0
    def test_use_of_disco_or_redirect_to_idp_when_using_mdq_and_forceauthn_is_set_1(
        self, context, sp_conf, idp_conf
    ):
        sp_conf["metadata"]["inline"] = [create_metadata_from_config_dict(idp_conf)]
        sp_conf["metadata"]["mdq"] = ["https://mdq.example.com"]

        context.decorate(Context.KEY_FORCE_AUTHN, "1")
        context.state[Context.KEY_MEMORIZED_IDP] = idp_conf["entityid"]

        backend_conf = {
            SAMLBackend.KEY_SP_CONFIG: sp_conf,
            SAMLBackend.KEY_DISCO_SRV: DISCOSRV_URL,
            SAMLBackend.KEY_MEMORIZE_IDP: True,
            SAMLBackend.KEY_MIRROR_FORCE_AUTHN: True,
        }
        samlbackend = SAMLBackend(
            None, INTERNAL_ATTRIBUTES, backend_conf, "base_url", "saml_backend"
        )
        resp = samlbackend.start_auth(context, InternalData())
        assert_redirect_to_discovery_server(resp, sp_conf, DISCOSRV_URL)

        backend_conf[SAMLBackend.KEY_USE_MEMORIZED_IDP_WHEN_FORCE_AUTHN] = True
        samlbackend = SAMLBackend(
            None, INTERNAL_ATTRIBUTES, backend_conf, "base_url", "saml_backend"
        )
        resp = samlbackend.start_auth(context, InternalData())
        assert_redirect_to_idp(resp, idp_conf)
Пример #5
0
 def internal_request(self):
     req = InternalData(
         subject_type=NAMEID_FORMAT_PERSISTENT,
         requester="example_requester",
     )
     req.attributes = FILTER + ["sn"]
     return req
Пример #6
0
 def handle_response(self, context):
     auth_info = AuthenticationInformation("test", str(datetime.now()),
                                           "test_issuer")
     internal_resp = InternalData(auth_info=auth_info)
     internal_resp.attributes = context.request
     internal_resp.user_id = "test_user"
     return self.auth_callback_func(context, internal_resp)
Пример #7
0
 def internal_response(self, idp_conf):
     auth_info = AuthenticationInformation(PASSWORD, "2015-09-30T12:21:37Z",
                                           idp_conf["entityid"])
     internal_response = InternalData(auth_info=auth_info)
     internal_response.attributes = AttributeMapper(
         INTERNAL_ATTRIBUTES).to_internal("saml", USERS["testuser1"])
     return internal_response
Пример #8
0
    def _authn_response(self, context):
        state_data = context.state[self.name]
        aresp = self.consumer.parse_response(AuthorizationResponse,
                                             info=json.dumps(context.request))
        self._verify_state(aresp, state_data, context.state)
        url = self.config['server_info']['token_endpoint']
        data = dict(
            grant_type='authorization_code',
            code=aresp['code'],
            redirect_uri=self.redirect_url,
            client_id=self.config['client_config']['client_id'],
            client_secret=self.config['client_secret'],
        )

        r = requests.post(url, data=data)
        response = r.json()
        if self.config.get('verify_accesstoken_state', True):
            self._verify_state(response, state_data, context.state)

        user_info = self.user_information(response["access_token"])
        auth_info = self.auth_info(context.request)
        internal_response = InternalData(auth_info=auth_info)
        internal_response.attributes = self.converter.to_internal(
            self.external_type, user_info)
        internal_response.subject_id = user_info[self.user_id_attr]
        del context.state[self.name]
        return self.auth_callback_func(context, internal_response)
Пример #9
0
    def _authn_response(self, context):
        state_data = context.state[self.name]
        aresp = self.consumer.parse_response(
            AuthorizationResponse, info=json.dumps(context.request))
        self._verify_state(aresp, state_data, context.state)
        url = self.config['server_info']['token_endpoint']
        data = dict(
            grant_type='authorization_code',
            code=aresp['code'],
            redirect_uri=self.redirect_url,
            client_id=self.config['client_config']['client_id'],
            client_secret=self.config['client_secret'], )

        r = requests.post(url, data=data)
        response = r.json()
        if self.config.get('verify_accesstoken_state', True):
            self._verify_state(response, state_data, context.state)

        user_info = self.user_information(response["access_token"])
        auth_info = self.auth_info(context.request)
        internal_response = InternalData(auth_info=auth_info)
        internal_response.attributes = self.converter.to_internal(
            self.external_type, user_info)
        internal_response.subject_id = user_info[self.user_id_attr]
        del context.state[self.name]
        return self.auth_callback_func(context, internal_response)
Пример #10
0
    def setup_for_authn_response(self, context, frontend, auth_req):
        context.state[frontend.name] = {"oidc_request": auth_req.to_urlencoded()}

        auth_info = AuthenticationInformation(PASSWORD, "2015-09-30T12:21:37Z", "unittest_idp.xml")
        internal_response = InternalData(auth_info=auth_info)
        internal_response.attributes = AttributeMapper(INTERNAL_ATTRIBUTES).to_internal("saml", USERS["testuser1"])
        internal_response.subject_id = USERS["testuser1"]["eduPersonTargetedID"][0]

        return internal_response
Пример #11
0
    def test_perun_identity_none_user(self, mock_adapter):
        mock_adapter.get_perun_user.return_value = None
        service = self.create_perun_identity_service()
        service.adapter = mock_adapter
        resp = InternalData(auth_info=AuthenticationInformation())
        resp.attributes = self.ATTRIBUTES

        returned_service = service.process(None, resp)
        assert 'perun_id' not in returned_service.attributes.keys()
    def test_filter_attribute_not_in_response(self):
        attribute_filters = {"": {"": {"a0": "foo:bar"}}}
        filter_service = self.create_filter_service(attribute_filters)

        resp = InternalData(auth_info=AuthenticationInformation())
        resp.attributes = {
            "a1": ["abc:xyz", "1:foo:bar:2"],
        }
        filtered = filter_service.process(None, resp)
        assert filtered.attributes == {"a1": ["abc:xyz", "1:foo:bar:2"]}
Пример #13
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 = InternalData(auth_info=AuthenticationInformation("", "", ""))
        internal_resp.subject_id = "user1234"
        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)
        assert internal_resp.attributes["user_id"] == [internal_resp.subject_id]
Пример #14
0
    def test_perun_identity_test_user(self, mock_adapter):
        user = User(1, 'Test user')
        mock_adapter.get_perun_user.return_value = user
        service = self.create_perun_identity_service()
        service.adapter = mock_adapter
        resp = InternalData(auth_info=AuthenticationInformation())
        resp.attributes = self.ATTRIBUTES

        returned_service = service.process(None, resp)
        assert 'perun_id' in returned_service.attributes.keys()
        assert returned_service.attributes.get('perun_id') == [user.id]
    def test_filter_one_attribute_for_one_target_provider(self):
        target_provider = "test_provider"
        attribute_filters = {target_provider: {"": {"a1": "foo:bar"}}}
        filter_service = self.create_filter_service(attribute_filters)

        resp = InternalData(auth_info=AuthenticationInformation(
            issuer=target_provider))
        resp.attributes = {
            "a1": ["abc:xyz", "1:foo:bar:2"],
        }
        filtered = filter_service.process(None, resp)
        assert filtered.attributes == {"a1": ["1:foo:bar:2"]}
    def test_filter_one_attribute_from_all_target_providers_for_all_requesters(
            self):
        attribute_filters = {"": {"": {"a2": "^foo:bar$"}}}
        filter_service = self.create_filter_service(attribute_filters)

        resp = InternalData(AuthenticationInformation())
        resp.attributes = {
            "a1": ["abc:xyz"],
            "a2": ["foo:bar", "1:foo:bar:2"],
        }
        filtered = filter_service.process(None, resp)
        assert filtered.attributes == {"a1": ["abc:xyz"], "a2": ["foo:bar"]}
Пример #17
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 = InternalData(
            subject_type=NAMEID_FORMAT_TRANSIENT, requester_name=requester_name,
        )
        internal_req.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.attributes
Пример #18
0
 def test_generate_static(self):
     synthetic_attributes = {"": {"default": {"a0": "value1;value2"}}}
     authz_service = self.create_syn_service(synthetic_attributes)
     resp = InternalData(auth_info=AuthenticationInformation())
     resp.attributes = {
         "a1": ["*****@*****.**"],
     }
     ctx = Context()
     ctx.state = dict()
     authz_service.process(ctx, resp)
     assert ("value1" in resp.attributes['a0'])
     assert ("value2" in resp.attributes['a0'])
     assert ("*****@*****.**" in resp.attributes['a1'])
Пример #19
0
    def _handle_authn_request(self, context):
        """
        Parse and verify the authentication request into an internal request.
        :type context: satosa.context.Context
        :rtype: satosa.internal.InternalData

        :param context: the current context
        :return: the internal request
        """
        request = urlencode(context.request)
        msg = "Authn req from client: {}".format(request)
        logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state),
                                    message=msg)
        logger.debug(logline)

        try:
            authn_req = self.provider.parse_authentication_request(request)
        except InvalidAuthenticationRequest as e:
            msg = "Error in authn req: {}".format(str(e))
            logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state),
                                        message=msg)
            logger.error(logline)
            error_url = e.to_error_url()

            if error_url:
                return SeeOther(error_url)
            else:
                return BadRequest("Something went wrong: {}".format(str(e)))

        client_id = authn_req["client_id"]
        context.state[self.name] = {"oidc_request": request}
        subject_type = self.provider.clients[client_id].get(
            "subject_type", "pairwise")
        client_name = self.provider.clients[client_id].get("client_name")
        if client_name:
            # TODO should process client names for all languages, see OIDC Registration, Section 2.1
            requester_name = [{"lang": "en", "text": client_name}]
        else:
            requester_name = None
        internal_req = InternalData(
            subject_type=subject_type,
            requester=client_id,
            requester_name=requester_name,
        )

        internal_req.attributes = self.converter.to_internal_filter(
            "openid",
            self._get_approved_attributes(
                self.provider.configuration_information["claims_supported"],
                authn_req))
        return internal_req
Пример #20
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 = InternalData(auth_info=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"]

        base._auth_resp_callback_func(context, internal_resp)

        expected_user_id = "*****@*****.**"
        assert internal_resp.subject_id == expected_user_id
Пример #21
0
    def test_allow_one_requester(self, target_context):
        rules = {
            TARGET_ENTITY: {
                "allow": ["test_requester"],
            }
        }
        decide_service = self.create_decide_service(rules)

        req = InternalData(requester="test_requester")
        assert decide_service.process(target_context, req)

        req.requester = "somebody else"
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Пример #22
0
 def test_generate_static(self):
     synthetic_attributes = {
        "": { "default": {"a0": "value1;value2" }}
     }
     authz_service = self.create_syn_service(synthetic_attributes)
     resp = InternalData(auth_info=AuthenticationInformation())
     resp.attributes = {
         "a1": ["*****@*****.**"],
     }
     ctx = Context()
     ctx.state = dict()
     authz_service.process(ctx, resp)
     assert("value1" in resp.attributes['a0'])
     assert("value2" in resp.attributes['a0'])
     assert("*****@*****.**" in resp.attributes['a1'])
 def test_authz_deny_fail(self):
     attribute_deny = {"": {"default": {"a0": ['foo1', 'foo2']}}}
     attribute_allow = {}
     authz_service = self.create_authz_service(attribute_allow,
                                               attribute_deny)
     resp = InternalData(auth_info=AuthenticationInformation())
     resp.attributes = {
         "a0": ["foo3"],
     }
     try:
         ctx = Context()
         ctx.state = dict()
         authz_service.process(ctx, resp)
     except SATOSAAuthenticationError as ex:
         assert False
Пример #24
0
 def test_discovery_server_set_in_context(self, context, sp_conf):
     discosrv_url = 'https://my.org/saml_discovery_service'
     context.decorate(
         SAMLBackend.KEY_SAML_DISCOVERY_SERVICE_URL, discosrv_url
     )
     resp = self.samlbackend.start_auth(context, InternalData())
     assert_redirect_to_discovery_server(resp, sp_conf, discosrv_url)
Пример #25
0
    def _handle_consent_response(self, context):
        """
        Endpoint for handling consent service response
        :type context: satosa.context.Context
        :rtype: satosa.response.Response

        :param context: response context
        :return: response
        """
        consent_state = context.state[STATE_KEY]
        saved_resp = consent_state["internal_resp"]
        internal_response = InternalData.from_dict(saved_resp)

        hash_id = self._get_consent_id(internal_response.requester, internal_response.subject_id,
                                       internal_response.attributes)

        try:
            consent_attributes = self._verify_consent(hash_id)
        except ConnectionError as e:
            satosa_logging(logger, logging.ERROR,
                           "Consent service is not reachable, no consent given.", context.state)
            # Send an internal_response without any attributes
            consent_attributes = None

        if consent_attributes is None:
            satosa_logging(logger, logging.INFO, "Consent was NOT given", context.state)
            # If consent was not given, then don't send any attributes
            consent_attributes = []
        else:
            satosa_logging(logger, logging.INFO, "Consent was given", context.state)

        internal_response.attributes = self._filter_attributes(internal_response.attributes, consent_attributes)
        return self._end_consent(context, internal_response)
Пример #26
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, InternalData())
        assert_redirect_to_idp(resp, idp_conf)
Пример #27
0
 def test_authz_deny_fail(self):
     attribute_deny = {
        "": { "default": {"a0": ['foo1','foo2']} }
     }
     attribute_allow = {}
     authz_service = self.create_authz_service(attribute_allow, attribute_deny)
     resp = InternalData(auth_info=AuthenticationInformation())
     resp.attributes = {
         "a0": ["foo3"],
     }
     try:
        ctx = Context()
        ctx.state = dict()
        authz_service.process(ctx, resp)
     except SATOSAAuthenticationError as ex:
        assert False
Пример #28
0
    def _handle_al_response(self, context):
        """
        Endpoint for handling account linking service response. When getting here
        user might have approved or rejected linking their account

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

        :param context: The current context
        :return: response
        """
        saved_state = context.state[self.name]
        internal_response = InternalData.from_dict(saved_state)

        #subject_id here is the linked id , not the facebook one, Figure out what to do
        status_code, message = self._get_uuid(context, internal_response.auth_info.issuer, internal_response.attributes['issuer_user_id'])

        if status_code == 200:
            satosa_logging(logger, logging.INFO, "issuer/id pair is linked in AL service",
                           context.state)
            internal_response.subject_id = message
            if self.id_to_attr:
                internal_response.attributes[self.id_to_attr] = [message]

            del context.state[self.name]
            return super().process(context, internal_response)
        else:
            # User selected not to link their accounts, so the internal.response.subject_id is based on the
            # issuers id/sub which is fine
            satosa_logging(logger, logging.INFO, "User selected to not link their identity in AL service",
                           context.state)
            del context.state[self.name]
            return super().process(context, internal_response)
Пример #29
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 = InternalData(subject_type=NAMEID_FORMAT_TRANSIENT,
                                        requester='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()
Пример #30
0
    def test_start_auth_redirects_directly_to_mirrored_idp(
            self, context, idp_conf):
        entityid = idp_conf["entityid"]
        context.decorate(Context.KEY_TARGET_ENTITYID, entityid)

        resp = self.samlbackend.start_auth(context, InternalData())
        assert_redirect_to_idp(resp, idp_conf)
Пример #31
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 = InternalData(requester=requester)

        assert decide_service.process(target_context, req)

        req.requester = "somebody else"
        with pytest.raises(SATOSAError):
            decide_service.process(target_context, req)
Пример #32
0
 def test_generate_mustache2(self):
     synthetic_attributes = {
        "": { "default": {"a0": "{{kaka.first}}#{{eppn.scope}}" }}
     }
     authz_service = self.create_syn_service(synthetic_attributes)
     resp = InternalData(auth_info=AuthenticationInformation())
     resp.attributes = {
         "kaka": ["kaka1","kaka2"],
         "eppn": ["*****@*****.**","*****@*****.**"]
     }
     ctx = Context()
     ctx.state = dict()
     authz_service.process(ctx, resp)
     assert("kaka1#example.com" in resp.attributes['a0'])
     assert("kaka1" in resp.attributes['kaka'])
     assert("*****@*****.**" in resp.attributes['eppn'])
     assert("*****@*****.**" in resp.attributes['eppn'])
Пример #33
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 = InternalData(auth_info=AuthenticationInformation("", "", ""))
        internal_resp.attributes = copy.copy(attributes)
        internal_resp.subject_id = "test_user"
        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] == [
                util.hash_data(satosa_config.get("USER_ID_HASH_SALT", ""), v)
                for v in attributes[attr]
            ]
Пример #34
0
    def _translate_response(self, response, issuer):
        """
        Translates oidc response to SATOSA internal response.
        :type response: dict[str, str]
        :type issuer: str
        :type subject_type: str
        :rtype: InternalData

        :param response: Dictioary with attribute name as key.
        :param issuer: The oidc op that gave the repsonse.
        :param subject_type: public or pairwise according to oidc standard.
        :return: A SATOSA internal response.
        """
        auth_info = AuthenticationInformation(UNSPECIFIED, str(datetime.now()), issuer)
        internal_resp = InternalData(auth_info=auth_info)
        internal_resp.attributes = self.converter.to_internal("openid", response)
        internal_resp.subject_id = response["sub"]
        return internal_resp
Пример #35
0
 def from_dict(cls, data):
     instance = InternalData.from_dict(data)
     instance.attributes = data.get("attributes") or data.get(
         "approved_attributes")
     instance.subject_type = data.get("subject_type") or data.get(
         "user_id_hash_type")
     instance.subject_id = (data.get("subject_id") or data.get("user_id")
                            or data.get("name_id"))
     return instance
Пример #36
0
    def _handle_authn_request(self, context):
        """
        Parse and verify the authentication request into an internal request.
        :type context: satosa.context.Context
        :rtype: satosa.internal.InternalData

        :param context: the current context
        :return: the internal request
        """
        request = urlencode(context.request)
        satosa_logging(logger, logging.DEBUG, "Authn req from client: {}".format(request),
                       context.state)

        try:
            authn_req = self.provider.parse_authentication_request(request)
        except InvalidAuthenticationRequest as e:
            satosa_logging(logger, logging.ERROR, "Error in authn req: {}".format(str(e)),
                           context.state)
            error_url = e.to_error_url()

            if error_url:
                return SeeOther(error_url)
            else:
                return BadRequest("Something went wrong: {}".format(str(e)))

        client_id = authn_req["client_id"]
        context.state[self.name] = {"oidc_request": request}
        subject_type = self.provider.clients[client_id].get("subject_type", "pairwise")
        client_name = self.provider.clients[client_id].get("client_name")
        if client_name:
            # TODO should process client names for all languages, see OIDC Registration, Section 2.1
            requester_name = [{"lang": "en", "text": client_name}]
        else:
            requester_name = None
        internal_req = InternalData(
            subject_type=subject_type,
            requester=client_id,
            requester_name=requester_name,
        )

        internal_req.attributes = self.converter.to_internal_filter(
            "openid", self._get_approved_attributes(self.provider.configuration_information["claims_supported"],
                                                    authn_req))
        return internal_req
Пример #37
0
    def _authn_response(self, context):
        aresp = self.consumer.parse_response(
            AuthorizationResponse, info=json.dumps(context.request))
        url = self.config['server_info']['token_endpoint']
        data = dict(
            grant_type='authorization_code',
            code=aresp['code'],
            redirect_uri=self.redirect_url,
            client_id=self.config['client_config']['client_id'],
            client_secret=self.config['client_secret'], )
        headers = {'Accept': 'application/json'}

        r = requests.post(url, data=data, headers=headers)
        response = r.json()
        token = response['access_token']
        orcid, name = response['orcid'], response['name']
        user_info = self.user_information(token, orcid, name)
        auth_info = self.auth_info(context.request)
        internal_response = InternalData(auth_info=auth_info)
        internal_response.attributes = self.converter.to_internal(
            self.external_type, user_info)
        internal_response.subject_id = orcid
        return self.auth_callback_func(context, internal_response)
Пример #38
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
        """
        req_info = idp.parse_authn_request(context.request["SAMLRequest"], binding_in)
        authn_req = req_info.message
        satosa_logging(logger, logging.DEBUG, "%s" % authn_req, context.state)

        try:
            resp_args = idp.response_args(authn_req)
        except SAMLError as e:
            satosa_logging(logger, logging.ERROR, "Could not find necessary info about entity: %s" % e, context.state)
            return ServiceError("Incorrect request from requester: %s" % e)

        requester = resp_args["sp_entity_id"]
        context.state[self.name] = self._create_state_data(context, idp.response_args(authn_req),
                                                           context.request.get("RelayState"))

        subject = authn_req.subject
        name_id_value = subject.name_id.text if subject else None

        nameid_formats = {
            "from_policy": authn_req.name_id_policy and authn_req.name_id_policy.format,
            "from_response": subject and subject.name_id and subject.name_id.format,
            "from_metadata": (
                idp.metadata[requester]
                .get("spsso_descriptor", [{}])[0]
                .get("name_id_format", [{}])[0]
                .get("text")
            ),
            "default": NAMEID_FORMAT_TRANSIENT,
        }

        name_id_format = (
            nameid_formats["from_policy"]
            or (
                nameid_formats["from_response"] != NAMEID_FORMAT_UNSPECIFIED
                and nameid_formats["from_response"]
            )
            or nameid_formats["from_metadata"]
            or nameid_formats["from_response"]
            or nameid_formats["default"]
        )

        requester_name = self._get_sp_display_name(idp, requester)
        internal_req = InternalData(
            subject_id=name_id_value,
            subject_type=name_id_format,
            requester=requester,
            requester_name=requester_name,
        )

        idp_policy = idp.config.getattr("policy", "idp")
        if idp_policy:
            internal_req.attributes = self._get_approved_attributes(
                idp, idp_policy, requester, context.state
            )

        return self.auth_req_callback_func(context, internal_req)
Пример #39
0
 def handle_response(self, context):
     auth_info = AuthenticationInformation("test", str(datetime.now()), "test_issuer")
     internal_resp = InternalData(auth_info=auth_info)
     internal_resp.attributes = context.request
     internal_resp.user_id = "test_user"
     return self.auth_callback_func(context, internal_resp)
Пример #40
0
 def internal_response(self):
     auth_info = AuthenticationInformation("auth_class_ref", "timestamp", "issuer")
     internal_response = InternalData(auth_info=auth_info)
     internal_response.subject_id = "user1"
     return internal_response
Пример #41
0
 def internal_response(self, idp_conf):
     auth_info = AuthenticationInformation(PASSWORD, "2015-09-30T12:21:37Z", idp_conf["entityid"])
     internal_response = InternalData(auth_info=auth_info)
     internal_response.attributes = AttributeMapper(INTERNAL_ATTRIBUTES).to_internal("saml", USERS["testuser1"])
     return internal_response