šŸ“£ New release v2.3.0 of dash-auth

Hey all, dash-auth 2.3 is now available :tada: it adds the following capabilities:

  • OIDC authentication, you can now ask your users to log into your app via social login or SSO
  • Protect parts of your app (page, callbacks, functions) by checking that users are part of the right groups (or have the roles)
  • BasicAuth also gets an uplift:
    • the username of the user is available in the flask session
    • Usernames can be linked to groups to enable the above RBAC feature

Read more about implementing this in your apps at GitHub - plotly/dash-auth: Basic Auth and Plotly Authentication for Dash Apps

25 Likes

This is big news. Thank you so much for the hard work and the PR, @RenaudLN .

And it also works with Pages for a multi-page Dash app :dancer:

2 Likes

great additions! thanks @RenaudLN

Does this update allow you to authenticate with Azure B2C? What if multiple users login simultaneously, how is that managed?

how do you access the username in the flask session?

@RenaudLN - Was just looking through the latest release changes for this and was wondering whether the group-based permission check is all that secure? I’m probably missing something, but could the end-user not just change the session[ā€œgroupsā€] key to ā€œadminā€ if they wanted to, or does that somehow invalidate access token?

Edit: I guess looking into it a bit more, Flask sessions are tamper-proof because they’re signed by the Flask server’s secret key, so the above should be moot.

@dash-beginner, yes and no.

It is easy to pull the info from the cookie, and if you have a non-secure key, the cookies themselves can be crafted, albeit the person needs to know the key.

By the ā€œkeyā€ are you referring to the access token that’s stored in the cookie from the OIDC handshake or the secret key that’s used to sign the cookie?

This is the key I am referring to:

This key is used to craft the cookie that is stored on the client.


To this point, I often times will see people generate random keys because its secure. It is, but if you have multiple backends, then these keys will never match and cause headaches.

Even in one instance, every time your server reboots you have to log in again…

2 Likes

You should use the flask option secure session cookie so that you can’t decrypt it even if you have the secret key. I added a parameter in OIDCAuth to automatically set this.

See this article for more detail about securing your session Cookie Security for Flask Applications - miguelgrinberg.com

1 Like

Awesome work! I’m wondering how to change the redirect_url? I couldn’t find a specific example in the documentation.

Glad it helps :slight_smile: you can change the redirect URI with the callback_route argument. Note that it needs to have a <idp> route placeholder in there. The default value is "/oidc/<idp>/callback"

Thanks I tried this but it didn’t affect the redirect uri sent by Dash.

auth = OIDCAuth(app, secret_key=secret_key)
auth.register_provider(
    "idp",
    token_endpoint_auth_method="client_secret_post",
    client_id=client_id,
    client_secret=client_secret,
    server_metadata_url=server_metadata_url,
    callback_route="/oidc/<idp>/something_else",
)

The redirect uri is still http://localhost:8050/oidc/idp/callback
Sorry if its very obvious!

Callback_route is defined on OIDCAuth, not on register_provider :slight_smile:

1 Like

It works like a charm!

The addition of OIDC is really awesome! Thank you for your work on this.

Is it possible to add an authorization hook somewhere in the process? I have OIDC authentication set up successfully with Google as the IdP, but now I’d like to control authorization based on membership in a specific Google Group within our org. That would involve calling a Google API to check group membership with the user’s access token before returning the page.

Hello @mkm,

Welcome the community!

Check out my PR here and see if this is something that you are interested in?

1 Like

Yes, this looks perfect for what I’m trying to do! Looks like I could just pass my lookup function to the groups parameter in check_groups.

Yeah, I think that would work. :grin:

Thank you for the hint, @jinnyzor

I just started using the dash_auth a few min ago, I had followed instructions available on Authentication | Dash for Python Documentation | Plotly and a very simple dash app, running on localhost.

However, after every chart update my console was literally spammed with a red ā€œWARNING:root:Session is not available. Have you set a secret key?ā€

A Google search sent me to

And then, while reading your reply, I realized how stupid I was, as the place where I had to put this secret key was actually in the

dash_auth.BasicAuth(
    app, 
    VALID_USERNAME_PASSWORD_PAIRS, 
    secret_key="somestring"
)

Thanks. Writting this reply here as it might help others

2 Likes