Adding SSO on streamlit app

I am trying to integrate SSO on streamlit app.
Packages -: google.oauth2, id_token ,google_auth_oauthlib.flow , Flow
how can we fetch token maintaining the session state (using gcp oauth as provider
)

1 Like

To integrate Single Sign-On (SSO) with Google Cloud Platform (GCP) OAuth as the provider in your Streamlit app and fetch a token while maintaining the session state, you can follow these steps:

  1. Install the necessary packages: Ensure that you have the required packages installed. You mentioned google.oauth2, id_token, google_auth_oauthlib.flow, and Flow. Make sure you have them installed in your environment.

  2. Import the required modules: Import the necessary modules from the installed packages into your Streamlit app:

import streamlit as st
from google.oauth2 import id_token
from google_auth_oauthlib.flow import Flow
  1. Configure the OAuth credentials: Create the OAuth client credentials for your application in the Google Cloud Console. Obtain the client ID and client secret, and store them securely. You can use Streamlit Secrets to manage and retrieve these credentials securely in your app.

  2. Define the OAuth flow: Set up the OAuth flow in your Streamlit app, including the necessary scopes and redirect URL. Here’s an example:

# Set the client ID and client secret
client_id = st.secrets["client_id"]
client_secret = st.secrets["client_secret"]

# Define the scopes required for your app
scopes = ['openid', 'email', 'profile']

# Define the redirect URL after successful authentication
redirect_uri = 'http://localhost:8501/'

# Create the OAuth flow instance
flow = Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=scopes,
    redirect_uri=redirect_uri
)

Make sure to update "client_id", "client_secret", and the redirect URI with the appropriate values.

  1. Implement the authentication flow: In your Streamlit app, create a login button or a specific route where the user can initiate the authentication flow. Here’s an example:
if 'credentials' not in st.session_state:
    st.session_state.credentials = None

if st.button('Login'):
    authorization_url, state = flow.authorization_url(prompt='consent')

    # Store the state in session state
    st.session_state.state = state

    # Redirect the user to the authorization URL
    st.redirect(authorization_url)
  1. Handle the callback route: Set up a route or callback to handle the authentication callback from Google. Here’s an example:
if 'code' in st.session_state and 'state' in st.session_state:
    flow.fetch_token(authorization_response=st.session_state.code)

    # Verify the state to prevent CSRF attacks
    assert st.session_state.state == st.session_state.token_response.get('state')

    # Store the credentials in session state
    st.session_state.credentials = flow.credentials
    st.write('Successfully authenticated!')

Make sure to update the appropriate code to handle the authentication callback route.

  1. Access the token: Once the user is authenticated and the credentials are stored in the session state, you can access the token for API calls. Here’s an example:
if st.session_state.credentials:
    token = st.session_state.credentials.token
    # Use the token for API calls or other purposes
    st.write('Access Token:', token)

Remember to handle any necessary error cases, edge cases, and secure token handling based on your specific requirements.

By following these steps, you should be able to integrate SSO with GCP OAuth as the provider in your Streamlit app and fetch a token while maintaining the session state.

3 Likes

Hi there. I am attempting to do a similar thing using Microsoft MSAL for python. Is there any way to follow a similar procedure to have a single sign on based authentication? I have already created something that did work using the device flow method of authentication but that requires a new page to open and can be tedious to have users enter the code and even deal with MFA. I would prefer if they could simply press one button and sign in if they are already signed into the same Active Directory elsewhere. I also need this to persist across pages but I think ive already got a system that should work and maintain states between pages.

i am also looking for multiple page solution and also a solution for when we are redirected from one streamlit app to another using URL from first app it should check the SSO token before redirecting , because i have multiple apps in one app structure.

I’ve been trying to use your solution, however, am receiving “Error 400: redirect_uri_mismatch” as an error when trying to authenticate. I’ve triple checked that the redirect_uri in my script and GCP are the same, so I’m not sure why I’m getting this error.

Right now I have the redirect_uri set to the url of my app. Is this correct?

Did anyone got the proper solution to this? Adding SSO in multipage streamlit app