简体   繁体   中英

How to skip extra 'sign in with' page in Flask App Builder / Airflow

I have started using Apache Airflow (Built upon FAB) and enabled authentication through OAuth (as shown in FAB Security ). I have ONLY one OAUTH_PROVIDER (azure).

FYI, Airflow version 2.1.4

When I launch my airflow home page, it used to open the direct login page of my OAUTH_PROVIDER.

Airflow 2.1.4 登录页面

NOW, the real problem started when I upgraded my airflow to 2.2.4 AND configured the same OAUTH (Azure) provider.

When I launch my airflow home page, a page coming like this

Airflow 2.2.4 登录页面

After clicking the button "Sign In with azure", the user login page comes.

Compared to the older airflow, the latest version got an extra page.

Why is matter to me?

We are rendering airflow in a web app and this extra "sign in with" page does not look good.

Please provide some info on SKIPPING that extra interaction.

After upgrading Airflow, Flask Appbuilder version was probably also bumped and that caused change in behavior. Basically:

  • Flask Appbuilder < 3.4.0 made it possible to have automatic sign-in when just one oauth provider was configured
  • Flask Appbuilder >= 3.4.0 changed the behavior and made it impossible to achieve this. This is the PR (with justification) that removed this functionality: https://github.com/dpgaspar/Flask-AppBuilder/pull/1707

If you want previous behavior to be used in your deployment, this is what most likely would work (although I didn't test it):

  1. Prepare custom view class, let's call it CustomAuth0AuthView - it would bring back old behavior on login method. (I used v4.1.3 as reference code and modified it slightly).

webserver_config.py :

from flask_appbuilder.security.views import AuthOAuthView


class CustomAuthOAuthView(AuthOAuthView):
    @expose("/login/")
    @expose("/login/<provider>")
    @expose("/login/<provider>/<register>")
    def login(self, provider: Optional[str] = None) -> WerkzeugResponse:
        log.debug("Provider: {0}".format(provider))
        if g.user is not None and g.user.is_authenticated:
            log.debug("Already authenticated {0}".format(g.user))
            return redirect(self.appbuilder.get_url_for_index)

        if provider is None:
            if len(self.appbuilder.sm.oauth_providers) > 1:
                return self.render_template(
                    self.login_template,
                    providers=self.appbuilder.sm.oauth_providers,
                    title=self.title,
                    appbuilder=self.appbuilder,
                )
            else:
                provider = self.appbuilder.sm.oauth_providers[0]["name"]

        log.debug("Going to call authorize for: {0}".format(provider))
        state = jwt.encode(
            request.args.to_dict(flat=False),
            self.appbuilder.app.config["SECRET_KEY"],
            algorithm="HS256",
        )
        try:
            if provider == "twitter":
                return self.appbuilder.sm.oauth_remotes[provider].authorize_redirect(
                    redirect_uri=url_for(
                        ".oauth_authorized",
                        provider=provider,
                        _external=True,
                        state=state,
                    )
                )
            else:
                return self.appbuilder.sm.oauth_remotes[provider].authorize_redirect(
                    redirect_uri=url_for(
                        ".oauth_authorized", provider=provider, _external=True
                    ),
                    state=state.decode("ascii") if isinstance(state, bytes) else state,
                )
        except Exception as e:
            log.error("Error on OAuth authorize: {0}".format(e))
            flash(as_unicode(self.invalid_login_message), "warning")
            return redirect(self.appbuilder.get_url_for_index)
  1. Prepare custom security manager. Let's call it CustomSecurityManager . It would use your custom view to handle login.

webserver_config.py :

from airflow.www.security import AirflowSecurityManager


class CustomSecurityManager(AirflowSecurityManager):
    authoidview = CustomAuthOAuthView
  1. Configure Airflow to use your CustomSecurityManager

webserver_config.py :

SECURITY_MANAGER_CLASS = CustomSecurityManager

More on this:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM