Dash Authorization Package.
Project description
Dash Authorization and Login
Docs: https://dash.plotly.com/authentication
License: MIT
For local testing, create a virtualenv, install the dev requirements, and run individual tests or test classes:
python -m venv venv
. venv/bin/activate
pip install -r dev-requirements.txt
python -k ba001
Note that Python 3.8 or greater is required.
Usage
Basic Authentication
To add basic authentication, add the following to your Dash app:
from dash import Dash
from dash_auth import BasicAuth
app = Dash(__name__)
USER_PWD = {
"username": "password",
"user2": "useSomethingMoreSecurePlease",
}
BasicAuth(app, USER_PWD)
One can also use an authorization python function instead of a dictionary/list of usernames and passwords:
from dash import Dash
from dash_auth import BasicAuth
def authorization_function(username, password):
if (username == "hello") and (password == "world"):
return True
else:
return False
app = Dash(__name__)
BasicAuth(app, auth_func = authorization_function)
Public routes
You can whitelist routes from authentication with the add_public_routes
utility function,
or by passing a public_routes
argument to the Auth constructor.
The public routes should follow Flask's route syntax.
from dash import Dash
from dash_auth import BasicAuth, add_public_routes
app = Dash(__name__)
USER_PWD = {
"username": "password",
"user2": "useSomethingMoreSecurePlease",
}
BasicAuth(app, USER_PWD, public_routes=["/"])
add_public_routes(app, public_routes=["/user/<user_id>/public"])
NOTE: If you are using server-side callbacks on your public routes, you should also use dash_auth's new public_callback
rather than the default Dash callback.
Below is an example of a public route and callbacks on a multi-page Dash app using Dash's pages API:
app.py
from dash import Dash, html, dcc, page_container
from dash_auth import BasicAuth
app = Dash(__name__, use_pages=True, suppress_callback_exceptions=True)
USER_PWD = {
"username": "password",
"user2": "useSomethingMoreSecurePlease",
}
BasicAuth(app, USER_PWD, public_routes=["/", "/user/<user_id>/public"])
app.layout = html.Div(
[
html.Div(
[
dcc.Link("Home", href="/"),
dcc.Link("John Doe", href="/user/john_doe/public"),
],
style={"display": "flex", "gap": "1rem", "background": "lightgray", "padding": "0.5rem 1rem"},
),
page_container,
],
style={"display": "flex", "flexDirection": "column"},
)
if __name__ == "__main__":
app.run_server(debug=True)
pages/home.py
from dash import Input, Output, html, register_page
from dash_auth import public_callback
register_page(__name__, "/")
layout = [
html.H1("Home Page"),
html.Button("Click me", id="home-button"),
html.Div(id="home-contents"),
]
# Note the use of public callback here rather than the default Dash callback
@public_callback(
Output("home-contents", "children"),
Input("home-button", "n_clicks"),
)
def home(n_clicks):
if not n_clicks:
return "You haven't clicked the button."
return "You clicked the button {} times".format(n_clicks)
pages/public_user.py
from dash import html, dcc, register_page
register_page(__name__, path_template="/user/<user_id>/public")
def layout(user_id: str):
return [
html.H1(f"User {user_id} (public)"),
dcc.Link("Authenticated user content", href=f"/user/{user_id}/private"),
]
pages/private_user.py
from dash import html, register_page
register_page(__name__, path_template="/user/<user_id>/private")
def layout(user_id: str):
return [
html.H1(f"User {user_id} (authenticated only)"),
html.Div("Members-only information"),
]
OIDC Authentication
To add authentication with OpenID Connect, you will first need to set up an OpenID Connect provider (IDP). This typically requires creating
- An application in your IDP
- Defining the redirect URI for your application, for testing locally you can use http://localhost:8050/oidc/callback
- A client ID and secret for the application
Once you have set up your IDP, you can add it to your Dash app as follows:
from dash import Dash
from dash_auth import OIDCAuth
app = Dash(__name__)
auth = OIDCAuth(app, secret_key="aStaticSecretKey!")
auth.register_provider(
"idp",
token_endpoint_auth_method="client_secret_post",
# Replace the below values with your own
# NOTE: Do not hardcode your client secret!
client_id="<my-client-id>",
client_secret="<my-client-secret>",
server_metadata_url="<my-idp-.well-known-configuration>",
)
Once this is done, connecting to your app will automatically redirect to the IDP login page.
Multiple OIDC Providers
For multiple OIDC providers, you can use register_provider
to add new ones after the OIDCAuth has been instantiated.
from dash import Dash, html
from dash_auth import OIDCAuth
from flask import request, redirect, url_for
app = Dash(__name__)
app.layout = html.Div([
html.Div("Hello world!"),
html.A("Logout", href="/oidc/logout"),
])
auth = OIDCAuth(
app,
secret_key="aStaticSecretKey!",
# Set the route at which the user will select the IDP they wish to login with
idp_selection_route="/login",
)
auth.register_provider(
"IDP 1",
token_endpoint_auth_method="client_secret_post",
client_id="<my-client-id>",
client_secret="<my-client-secret>",
server_metadata_url="<my-idp-.well-known-configuration>",
)
auth.register_provider(
"IDP 2",
token_endpoint_auth_method="client_secret_post",
client_id="<my-client-id2>",
client_secret="<my-client-secret2>",
server_metadata_url="<my-idp2-.well-known-configuration>",
)
@app.server.route("/login", methods=["GET", "POST"])
def login_handler():
if request.method == "POST":
idp = request.form.get("idp")
else:
idp = request.args.get("idp")
if idp is not None:
return redirect(url_for("oidc_login", idp=idp))
return """<div>
<form>
<div>How do you wish to sign in:</div>
<select name="idp">
<option value="IDP 1">IDP 1</option>
<option value="IDP 2">IDP 2</option>
</select>
<input type="submit" value="Login">
</form>
</div>"""
if __name__ == "__main__":
app.run_server(debug=True)
User-group-based permissions
dash_auth
provides a convenient way to secure parts of your app based on user groups.
The following utilities are defined:
list_groups
: Returns the groups of the current user, or None if the user is not authenticated.check_groups
: Checks the current user groups against the provided list of groups. Available group checks areone_of
,all_of
andnone_of
. The function returns None if the user is not authenticated.protected
: A function decorator that modifies the output if the user is unauthenticated or missing group permission.protected_callback
: A callback that only runs if the user is authenticated and with the right group permissions.
NOTE: user info is stored in the session so make sure you define a secret_key on the Flask server to use this feature.
If you wish to use this feature with BasicAuth, you will need to define the groups for individual basicauth users:
from dash_auth import BasicAuth
app = Dash(__name__)
USER_PWD = {
"username": "password",
"user2": "useSomethingMoreSecurePlease",
}
BasicAuth(
app,
USER_PWD,
user_groups={"user1": ["group1", "group2"], "user2": ["group2"]},
secret_key="Test!",
)
# You can also use a function to get user groups
def check_user(username, password):
if username == "user1" and password == "password":
return True
if username == "user2" and password == "useSomethingMoreSecurePlease":
return True
return False
def get_user_groups(user):
if user == "user1":
return ["group1", "group2"]
elif user == "user2":
return ["group2"]
return []
BasicAuth(
app,
auth_func=check_user,
user_groups=get_user_groups,
secret_key="Test!",
)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file dash_auth-2.3.0.tar.gz
.
File metadata
- Download URL: dash_auth-2.3.0.tar.gz
- Upload date:
- Size: 17.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.12.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 72df43248c15e121f8d5d710981e880deb2df546b564f2951a10ca50d7d92f6d |
|
MD5 | a549c2880434b9539e7d42c0823d5cda |
|
BLAKE2b-256 | 8b8a27c2bfb5f9fa97acedce529f859fab4ad2bae805d3a7f2b87c251ff8a6ee |
File details
Details for the file dash_auth-2.3.0-py3-none-any.whl
.
File metadata
- Download URL: dash_auth-2.3.0-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.12.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2fa72d4ee128b4f9cf0c958157a986ffcd0b93d43b54d64e3cef5976ab7e0abe |
|
MD5 | 0f246d08c51fe10999df7dd79953b396 |
|
BLAKE2b-256 | 1942d636affcd8074f7f48156a99d8854e5be951d8601dcb4178231c92c988d1 |