Need help with OneLogin auth integration

Summary

I’m trying to enable authentication to my app via OneLogin. I have my client_id, client_secret, etc and can programmatically get a token, but in the app It never progresses beyond showing the login screen. I realize this is ugly, and incomplete - but I’ve tried several things and this is just what I have at the moment.

Steps to reproduce

Code snippet:

import streamlit as st
import requests
from urllib.parse import urlparse, parse_qs, quote

authorization_base_url = 'https://mydomain.onelogin.com/oidc/2/auth'
token_url = 'https://mydomain.onelogin.com/oidc/2/token'
scope = 'openid email name groups profile'
client_id = 'my_redacted_client_id'
client_secret = 'my_redacted_client_secret'
redirect_uri = 'https://myapp.mydomain.com'

class LoginHandler:
    def __init__(self, client_id, client_secret, redirect_uri, scope):
        self.client_id = client_id
        self.client_secret = client_secret
        self.redirect_uri = redirect_uri
        self.scope = scope

    def get_authorization_url(self):
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'scope': self.scope,
        }
        auth_url = f"{authorization_base_url}?{'&'.join([f'{k}={quote(str(v))}' for k, v in params.items()])}"
        return auth_url

    def authenticate_user(self, code):
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        data = {
            'grant_type': 'authorization_code',
            'code': code,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'redirect_uri': self.redirect_uri,
            'scope': self.scope,
        }
        response = requests.post(token_url, headers=headers, data=data, verify=False)
        st.write(response.json())  # Add this line to print out the response
        if response.status_code == 200:
            return response.json()
        else:
            return None


handler = LoginHandler(client_id, client_secret, redirect_uri, scope)

st.write('Click below to log in')
if st.button('Login'):
    auth_url = handler.get_authorization_url()
    st.write('Opening authentication URL:', auth_url)
    st.experimental_set_query_params(request_uri=auth_url)
    st.stop()

if 'request_uri' in st.experimental_get_query_params():
    parsed_url = urlparse(st.experimental_get_query_params()['request_uri'][0])
    query_params = parse_qs(parsed_url.query)
    if 'code' in query_params:
        code = query_params['code'][0]
        st.write('Received code:', code)
        tokens = handler.authenticate_user(code)
        st.write('Response:', tokens)
        if tokens:
            st.write('Authentication successful!')
            st.write(tokens)
        else:
            st.write('Authentication failed.')
    else:
        st.write('Authentication failed: Code not found in query parameters.')

If applicable, please provide the steps we should take to reproduce the error or specified behavior.

Expected behavior:

User clicks ‘login’ and is authenticated and the app is run

Actual behavior:

The page just reloads in a new tab, with login displayed

Debug info

  • Streamlit version: 1.9.2
  • Python version: 3.10.6
  • OS version: Ubuntu 22.04 LTS
  • Browser version: Chrome 112.0.5615.137

Additional information

The app is behind nginx where I’m terminating SSL and forwarding to myapp:8501

When I load this app, I’m presented with a ‘login’ button. When that button is clicked, the generated AUTH URL is displayed. When that link is clicked, a new browser window opens (with the address containing the returned ‘code’ from OneLogin) but the page just has the login button again instead of either the authentication success/fail message.

Ideally, I’d like a button that, when clicked, sends all the correct queries to OneLogin, gets the token/auth’s my user and then displays the actual app. Any help greatly appreciated.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.