fedora-infra / flask-oidc

OpenID Connect support for Flask
24 stars 14 forks source link

Infinite logout redirect #17

Closed sleep-dev closed 1 year ago

sleep-dev commented 1 year ago

OpenIDConnect._before_request function has been registered in before_request of flask.

When token has been expired, it calls oidc_auth.logout by check_token_expiry() function on OpenIDConnect class.

But because it doesn't pop the session, so check_token_expiry() called again and again forever.

I think it should check whether requests.url is oidc_auth.logout or not and return by condition.

Current code is look like below. (flask_oidc/init.py)

  def _before_request(self):
        g._oidc_auth = self.oauth.oidc
        if not current_app.config["OIDC_RESOURCE_SERVER_ONLY"]:
            return self.check_token_expiry()
    def check_token_expiry(self):
        try:
            token = session.get("oidc_auth_token")
            if not token:
                return
            clock_skew = current_app.config["OIDC_CLOCK_SKEW"]
            if token["expires_at"] - clock_skew < int(time.time()):
                return redirect("{}?reason=expired".format(url_for("oidc_auth.logout")))
        except Exception as e:
            session.pop("oidc_auth_token", None)
            session.pop("oidc_auth_profile", None)
            logger.exception("Could not check token expiration")
            abort(500, f"{e.__class__.__name__}: {e}")

change like below

  def _before_request(self):
        g._oidc_auth = self.oauth.oidc
        if not current_app.config["OIDC_RESOURCE_SERVER_ONLY"]:
            return self.check_token_expiry()

    def check_token_expiry(self):
        try:
            token = session.get("oidc_auth_token")
            if not token:
                return
            clock_skew = current_app.config["OIDC_CLOCK_SKEW"]
            if request.path == url_for("oidc_auth.logout"):
                return
            if token["expires_at"] - clock_skew < int(time.time()):
                return redirect("{}?reason=expired".format(url_for("oidc_auth.logout")))
        except Exception as e:
            session.pop("oidc_auth_token", None)
            session.pop("oidc_auth_profile", None)
            logger.exception("Could not check token expiration")
            abort(500, f"{e.__class__.__name__}: {e}")
abompard commented 1 year ago

Thanks! I'll merge that right now and push a new release.