Пример #1
0
    def _logout(self):
        logger.debug('user logout')
        try:
            session = UserSession(flask.session)
        except UninitialisedSession as e:
            logger.info('user was already logged out, doing nothing')
            return None

        id_token_jwt = session.id_token_jwt
        client = self.clients[session.current_provider]
        session.clear()

        if client.provider_end_session_endpoint:
            flask.session['end_session_state'] = rndstr()

            end_session_request = EndSessionRequest(
                id_token_hint=id_token_jwt,
                post_logout_redirect_uri=self._get_post_logout_redirect_uri(
                    client),
                state=flask.session['end_session_state'])

            logger.debug('send endsession request: %s',
                         end_session_request.to_json())

            return redirect(
                end_session_request.request(
                    client.provider_end_session_endpoint), 303)
        return None
Пример #2
0
    def __call__(self):
        client = self.context.get_oauth2_client()
        # session = Session(self.request, use_session_data_manager=self.context.use_session_data_manager)
        # state is used to keep track of responses to outstanding requests (state).
        # https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/java/logout.adoc
        # session.set('end_session_state', rndstr())
        args = {
            # 'state': session.get('end_session_state'),
            # TODO: ....
            # 'post_logout_redirect_uri': api.portal.get().absolute_url(),
            "redirect_uri": api.portal.get().absolute_url(),
        }

        pas = getToolByName(self.context, "acl_users")
        auth_cookie_name = pas.credentials_cookie_auth.cookie_name

        # end_req = client.construct_EndSessionRequest(request_args=args)
        end_req = EndSessionRequest(**args)
        logout_url = end_req.request(client.end_session_endpoint)
        self.request.response.setHeader("Cache-Control", "no-cache, must-revalidate")
        # TODO: change path with portal_path
        self.request.response.expireCookie(auth_cookie_name, path="/")
        self.request.response.expireCookie("auth_token", path="/")
        self.request.response.redirect(logout_url)
        return
Пример #3
0
def end_session_endpoint():
    if flask.request.method == 'GET':
        # redirect from RP
        end_session_request = EndSessionRequest().deserialize(urlencode(flask.request.args))
        flask.session['end_session_request'] = end_session_request.to_dict()
        return render_template('logout.jinja2')
    else:
        form = parse_qs(flask.request.get_data().decode('utf-8'))
        if 'logout' in form:
            return do_logout(EndSessionRequest().from_dict(flask.session['end_session_request']))
        else:
            return make_response('You chose not to logout')
Пример #4
0
    def _logout(self):
        id_token_jwt = flask.session['id_token_jwt']
        flask.session.clear()

        if 'end_session_endpoint' in self.client.provider_info:
            flask.session['end_session_state'] = rndstr()
            end_session_request = EndSessionRequest(
                id_token_hint=id_token_jwt,
                post_logout_redirect_uri=self.client_registration_info['post_logout_redirect_uris'][0],
                state=flask.session['end_session_state'])
            return redirect(end_session_request.request(self.client.provider_info['end_session_endpoint']), 303)

        return None
Пример #5
0
def logout():

    end_session_request = EndSessionRequest().deserialize(
        urlencode(request.args))

    session['end_session_request'] = end_session_request.to_dict()

    try:
        redirect_url = logout_user()

    except InvalidSubjectIdentifier as error:
        raise BadRequest('Logout unsuccessful')

    return render_template('views/logout_info.html', next_url=redirect_url)
Пример #6
0
    def test_parse_end_session_request(self):
        esreq = EndSessionRequest(id_token=IDTOKEN.to_jwt(key=KC_SYM_S.get(
            alg2keytype("HS256")),
                                                          algorithm="HS256"),
                                  redirect_url="http://example.org/jqauthz",
                                  state="state0")

        request = self.srv.parse_end_session_request(
            query=esreq.to_urlencoded())
        assert isinstance(request, EndSessionRequest)
        assert _eq(request.keys(), ['id_token', 'redirect_url', 'state'])
        assert request["state"] == "state0"

        assert request["id_token"]["aud"] == ["client_1"]
    def test_parse_end_session_request(self):
        esreq = EndSessionRequest(
                id_token=IDTOKEN.to_jwt(key=KC_SYM_S.get(alg2keytype("HS256")),
                                        algorithm="HS256"),
                redirect_url="http://example.org/jqauthz",
                state="state0")

        request = self.srv.parse_end_session_request(
                query=esreq.to_urlencoded())
        assert isinstance(request, EndSessionRequest)
        assert _eq(request.keys(), ['id_token', 'redirect_url', 'state'])
        assert request["state"] == "state0"

        assert request["id_token"]["aud"] == ["client_1"]
Пример #8
0
def end_session_endpoint():
    if flask.request.method == "GET":
        # redirect from RP
        end_session_request = EndSessionRequest().deserialize(
            urlencode(flask.request.args))
        flask.session["end_session_request"] = end_session_request.to_dict()
        return render_template("logout.jinja2")
    else:
        form = parse_qs(flask.request.get_data().decode("utf-8"))
        if "logout" in form:
            return do_logout(EndSessionRequest().from_dict(
                flask.session["end_session_request"]))
        else:
            return make_response("You chose not to logout")
def _provider_logout_url(id_token_jwt):
    client = current_app.extensions['oidc_client']
    endpoint = client.client.provider_info.get('end_session_endpoint')
    logout_urls = client.client_registration_info['post_logout_redirect_uris']

    if not endpoint:
        return None

    session['end_session_state'] = rndstr()

    end_session_request = EndSessionRequest(
        id_token_hint=id_token_jwt,
        post_logout_redirect_uri=logout_urls[0],
        state=session['end_session_state'])

    return end_session_request.request(endpoint)
Пример #10
0
    def logout_user(self, subject_identifier=None, end_session_request=None):
        # type: (Optional[str], Optional[oic.oic.message.EndSessionRequest]) -> None
        if not end_session_request:
            end_session_request = EndSessionRequest()
        if 'id_token_hint' in end_session_request:
            id_token = IdToken().from_jwt(end_session_request['id_token_hint'], key=[self.signing_key])
            subject_identifier = id_token['sub']

        self.authz_state.delete_state_for_subject_identifier(subject_identifier)
Пример #11
0
    def test_no_post_logout_redirect_uri(self):
        self.provider.cdb[CLIENT_ID]["post_logout_redirect_uris"] = [
            "https://example.com/plru",
            "https://example.com/plru2",
        ]
        esr = EndSessionRequest(state="foo")

        assert self.provider.verify_post_logout_redirect_uri(esr,
                                                             CLIENT_ID) is None
Пример #12
0
 def test_wrong_post_logout_redirect_uri(self):
     self.provider.cdb[CLIENT_ID]["post_logout_redirect_uris"] = [
         "https://example.com/plru"
     ]
     esr = EndSessionRequest(
         state="foo",
         post_logout_redirect_uri="https://localhost:8087/plru")
     assert self.provider.verify_post_logout_redirect_uri(esr,
                                                          CLIENT_ID) is None
Пример #13
0
    def _logout(self):
        logger.debug('user logout')
        id_token_jwt = flask.session['id_token_jwt']
        flask.session.clear()

        if 'end_session_endpoint' in self.client.provider_info:
            flask.session['end_session_state'] = rndstr()
            end_session_request = EndSessionRequest(
                id_token_hint=id_token_jwt,
                post_logout_redirect_uri=self.
                client_registration_info['post_logout_redirect_uris'][0],
                state=flask.session['end_session_state'])
            logger.debug('send endsession request: %s',
                         end_session_request.to_json())
            return redirect(
                end_session_request.request(
                    self.client.provider_info['end_session_endpoint']), 303)

        return None
Пример #14
0
 def test_let_user_verify_logout(self):
     self.provider.cdb[CLIENT_ID]["post_logout_redirect_uris"] = [
         "https://localhost:8087/plru"
     ]
     esr = EndSessionRequest(
         state="foo",
         post_logout_redirect_uri="https://localhost:8087/plru")
     res = self.provider.let_user_verify_logout("user", esr, None, None)
     assert isinstance(res, Response)
     assert res.headers == [("Content-type", "text/html")]
     assert res.status_code == 200
Пример #15
0
 def test_post_logout_redirect_with_unknown_post_logout_redirect_uri(self):
     auth_req = AuthorizationRequest(
         response_type='code id_token token',
         scope='openid',
         client_id='client1',
         redirect_uri='https://client.example.com/redirect')
     auth_resp = self.provider.authorize(auth_req, 'user1')
     end_session_request = EndSessionRequest(
         id_token_hint=auth_resp['id_token'],
         post_logout_redirect_uri='https://client.example.com/unknown')
     assert self.provider.do_post_logout_redirect(
         end_session_request) is None
Пример #16
0
def do_logout():

    end_session_request = EndSessionRequest().deserialize(urlencode(flask.request.args)).to_dict()
    try:
        current_app.provider.logout_user(end_session_request=end_session_request)
    except InvalidSubjectIdentifier as e:
        return make_response('Logout unsuccessful!', 400)

    redirect_url = current_app.provider.do_post_logout_redirect(end_session_request)
    if redirect_url:
        return redirect(redirect_url, 303)

    return make_response('Logout successful!')
Пример #17
0
    def _logout(self):
        logger.debug('user logout')
        session = UserSession(flask.session)
        id_token_jwt = session.id_token_jwt
        client = self.clients[session.current_provider]
        session.clear()

        if client.provider_end_session_endpoint:
            flask.session['end_session_state'] = rndstr()

            end_session_request = EndSessionRequest(
                id_token_hint=id_token_jwt,
                post_logout_redirect_uri=self._get_post_logout_redirect_uri(),
                state=flask.session['end_session_state'])

            logger.debug('send endsession request: %s',
                         end_session_request.to_json())

            return redirect(
                end_session_request.request(
                    client.provider_end_session_endpoint), 303)
        return None
Пример #18
0
def logout_user():
    params = session['end_session_request']

    current_app.logger.info("logout_user:{}".format(params))

    params.update({'id_token_hint': session['id_token_jwt']})

    current_app.logger.info("logout_user_post_update:{}".format(params))

    request = EndSessionRequest().from_dict(params)

    current_app.provider.logout_user(end_session_request=request)

    return current_app.provider.do_post_logout_redirect(request)
Пример #19
0
 def test_post_logout_redirect(self):
     auth_req = AuthorizationRequest(
         response_type='code id_token token',
         scope='openid',
         client_id='client1',
         redirect_uri='https://client.example.com/redirect')
     auth_resp = self.provider.authorize(auth_req, 'user1')
     end_session_request = EndSessionRequest(
         id_token_hint=auth_resp['id_token'],
         post_logout_redirect_uri='https://client.example.com/post_logout',
         state='state')
     redirect_url = self.provider.do_post_logout_redirect(
         end_session_request)
     assert redirect_url == EndSessionResponse(
         state='state').request('https://client.example.com/post_logout')
Пример #20
0
    def test_logout_user_with_id_token_hint(self):
        auth_req = AuthorizationRequest(
            response_type='code id_token token',
            scope='openid',
            client_id='client1',
            redirect_uri='https://client.example.com/redirect')
        auth_resp = self.provider.authorize(auth_req, 'user1')

        self.provider.logout_user(end_session_request=EndSessionRequest(
            id_token_hint=auth_resp['id_token']))
        with pytest.raises(InvalidAccessToken):
            self.provider.authz_state.introspect_access_token(
                auth_resp['access_token'])
        with pytest.raises(InvalidAuthorizationCode):
            self.provider.authz_state.exchange_code_for_token(
                auth_resp['code'])
Пример #21
0
 def test_let_user_verify_logout_with_redirect(self):
     self.provider.cdb[CLIENT_ID]["post_logout_redirect_uris"] = [
         "https://localhost:8087/plru"
     ]
     esr = EndSessionRequest(
         state="foo",
         post_logout_redirect_uri="https://localhost:8087/plru")
     res = self.provider.let_user_verify_logout(
         "user", esr, None, "https://example.com/redirect")
     assert isinstance(res, Response)
     assert set(res.headers) == {("Content-type", "text/html")}
     assert res.status_code == 200
     # make sure the redirect was propagated
     txt = '<input type="hidden" name="{}" value="{}"/>'.format(
         "post_logout_redirect_uri", "https://localhost:8087/plru")
     assert txt in res.message
Пример #22
0
 def test_missing_post_logout_redirect_uri(self):
     esr = EndSessionRequest(state="foo")
     assert self.provider.verify_post_logout_redirect_uri(esr,
                                                          CLIENT_ID) is None
Пример #23
0
 def test_post_logout_redirect_without_post_logout_redirect_uri(self):
     assert self.provider.do_post_logout_redirect(
         EndSessionRequest()) is None
Пример #24
0
 def test_post_logout_redirect_with_unknown_client_for_post_logout_redirect_uri(
         self):
     end_session_request = EndSessionRequest(
         post_logout_redirect_uri='https://client.example.com/post_logout')
     assert self.provider.do_post_logout_redirect(
         end_session_request) is None
Пример #25
0
                             application_type="web")

RSREQ = RefreshSessionRequest(id_token="id_token",
                              redirect_url="http://example.com/authz",
                              state="state0")

#key, type, usage, owner="."

alg = "HS256"
ktype = alg2keytype(alg)
keys = KC_SYM_S.get(ktype)
CSREQ = CheckSessionRequest(
    id_token=IDTOKEN.to_jwt(key=keys, algorithm="HS256"))

ESREQ = EndSessionRequest(id_token=IDTOKEN.to_jwt(key=keys, algorithm="HS256"),
                          redirect_url="http://example.org/jqauthz",
                          state="state0")

UINFO = Claims(name={"essential": True},
               nickname=None,
               email={"essential": True},
               email_verified={"essential": True},
               picture=None)

IDT2 = Claims(auth_time={
    "essential": True,
    "acr": {
        "values": ["urn:mace:incommon:iap:silver"]
    }
})