How to run a custom callback function in Flask-oidc

548 Views Asked by At

I have an app build in flask with keycloak for auth. It has a custom oidc callback that was once running perfectly however it will not run the custom callback function anymore. The login still works fine.

I have now gone back to basics running the below sample code with a few modifications. The code works perfectly however again the custom callback function is not being executed.

I specify the decorator @oidc.custom_callback and set OVERWRITE_REDIRECT_URI but even in this sample code the custom callback is not being executed.

Can anyone help? I'm pulling my hair out.

import json
import logging

from flask import Flask, g
from flask_oidc import OpenIDConnect
import requests
from dotenv import load_dotenv
load_dotenv()

logging.basicConfig(level=logging.DEBUG)

FQDN = "https://example.com"

app = Flask(__name__)
app.config.update({
    'SECRET_KEY': 'SomethingNotEntirelySecret',
    'TESTING': True,
    'DEBUG': True,
    'OIDC_CLIENT_SECRETS': 'client_secrets.json',
    'OIDC_ID_TOKEN_COOKIE_SECURE': False,
    'OIDC_REQUIRE_VERIFIED_EMAIL': False,
    'OIDC_USER_INFO_ENABLED': True,
    'OIDC_OPENID_REALM': 'REALM',
    'OIDC_SCOPES': ['openid', 'email', 'profile'],
    'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post',
    'OVERWRITE_REDIRECT_URI': f'{FQDN}/oidc_callback',
    'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post',
    'OIDC_CLOCK_SKEW': 560
})

oidc = OpenIDConnect(app)

@app.route('/oidc_callback')
@oidc.custom_callback
def callback(data):
    print("Calling back! --------------------------------------------------------")
    return 'Hello. You submitted'

@app.route('/')
def hello_world():
    if oidc.user_loggedin:
        return ('Hello, %s, <a href="/private">See private</a> '
                '<a href="/logout">Log out</a>') % \
            oidc.user_getfield('preferred_username')
    else:
        return 'Welcome anonymous, <a href="/private">Log in</a>'


@app.route('/private')
@oidc.require_login
def hello_me():
    """Example for protected endpoint that extracts private information from the OpenID Connect id_token.
       Uses the accompanied access_token to access a backend service.
    """

    info = oidc.user_getinfo(['preferred_username', 'email', 'sub'])

    username = info.get('preferred_username')
    email = info.get('email')
    user_id = info.get('sub')

    if user_id in oidc.credentials_store:
        try:
            from oauth2client.client import OAuth2Credentials
            access_token = OAuth2Credentials.from_json(oidc.credentials_store[user_id]).access_token
            print('access_token=<%s>' % access_token)
            headers = {'Authorization': 'Bearer %s' % (access_token)}
            # YOLO
            greeting = requests.get('https://thatfansite.com:8443/greeting', headers=headers).text
        except:
            print("Could not access greeting-service")
            greeting = "Hello %s" % username
    

    return ("""%s your email is %s and your user_id is %s!
               <ul>
                 <li><a href="/">Home</a></li>
                 <li><a href="//thatfansite.com:8443/auth/realms/tfs/account?referrer=flask-app&referrer_uri=http://localhost/private&">Account</a></li>
                </ul>""" %
            (greeting, email, user_id))


@app.route('/api', methods=['POST'])
@oidc.accept_token(require_token=True, scopes_required=['openid'])
def hello_api():
    """OAuth 2.0 protected API endpoint accessible via AccessToken"""

    return json.dumps({'hello': 'Welcome %s' % g.oidc_token_info['sub']})


@app.route('/logout')
def logout():
    """Performs local logout by removing the session cookie."""

    oidc.logout()
    return 'Hi, you have been logged out! <a href="/">Return</a>'


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8080)

Here is my client_secrets.json

{
    "web": {
        "issuer": "https://example.com/auth/realms/REALM",
        "auth_uri": "https://example.com/auth/realms/REALM/protocol/openid-connect/auth",
            "ssl-required": "none",
            "realm": "REALM",
        "client_id": "CLIENT",
        "client_secret": "SKEY",
            "resource": "CLIENT",
        "redirect_uris": [
            "https://example.com/*"
        ],
        "userinfo_uri": "https://example.com/auth/realms/REALM/protocol/openid-connect/userinfo",
        "token_uri": "https://example.com/auth/realms/REALM/protocol/openid-connect/token",
        "token_introspection_uri": "https://example.com/auth/realms/REALM/protocol/openid-connect/token/introspect"
    }
}

0

There are 0 best solutions below