Search code examples
flaskkeycloakopenid-connect

Writing a SIMPLE flask page using Keycloak OIDC


I have had a lot of trouble finding a concise example for what I need.

I have a working Keycloak server at https://auth.mycompany.com. (not the real company name, of course) I have a flask server at http://testapp.mycompany.com.

All I need to do is have a simple page with a login flow that connects to my Keycloak server. As it turns out, all the Keycloak extensions are abandoned and poorly documented. There is flask_oidc, pyoidc, etc. However, the documentation I can find online is really not great. I have looked through a lot of github repos and struggled through a lot of thickly-accented youtube videos, but have yet to find an example of a Flask (Django also acceptable) app that simply and concisely implements an OIDC login flow. I even tried ChatGPT and it gave me several examples, none of which worked. I understand the OAuth2.0 and OIDC standards, and have read their source documents, but I have utterly failed at finding a boilerplate implementation of these things to start my hands-on-keyboard work.

Can someone please, please show me a very minimal example of an extremely basic Flask or Django app that would connect to my Keycloak server. I will gladly continue researching on my own to build upon it, but I can't seem to get it started.

I tried googling until I reached the edge of madness. I have tried numerous repos which literally did not function. I was told fictions by ChatGPT.


Solution

  • The structure folder is here. In your keycloak server, you must create a client connect to have client_id and client_secret_key

    In server/constants/KeyCloakConstants.py

    KEYCLOAK_SERVER_URL = os.getenv(
        "KEYCLOAK_SERVER_URL", "http://keycloak/auth/"
    )
    KEYCLOAK_REALM_NAME = os.getenv("KEYCLOAK_REALM_NAME", "user-dev")
    # client
    KEYCLOAK_CLIENT_ID = os.getenv("KEYCLOAK_CLIENT_ID", "client-service")
    KEYCLOAK_CLIENT_SECRET_KEY = os.getenv(
        "KEYCLOAK_CLIENT_SECRET_KEY", "jGlenvHtelkBtSS6zsi72prZQeoAmPxy"
    )
    

    In server/extension.py

    from server.constants import KeyCloakConstants as kcl
    from keycloak import KeycloakOpenID
    
    keycloak_client = KeycloakOpenID(
        server_url=kcl.KEYCLOAK_SERVER_URL,
        realm_name=kcl.KEYCLOAK_REALM_NAME,
        client_id=kcl.KEYCLOAK_CLIENT_ID,
        client_secret_key=kcl.KEYCLOAK_CLIENT_SECRET_KEY,
    )
    

    In server/services/KeycloakService.py

    from server.extensions import keycloak_client
    
    class KeycloakClientService:
        @classmethod
        def login_user(cls, data):
            token = keycloak_client.token(
                username=data.get("username"),
                password=data.get("password"),
            )
            return token
    

    In server/controllers/AuthController.py

    from flask import jsonify
    from server.services.KeycloakService import KeycloakClientService
    
    auth_api = Blueprint("auth_api", __name__)
    
    @auth_api.route("/login", methods=["POST"])
    def login_user():
        """
        `param`
            :body:
                username: String
                password: String
        `return`
            :body: access_token, expires_in, token_type
        """
        data = request.json
        token = KeycloakClientService.login_user(data)
        return jsonify(output)
    

    Here is only the sample for using keycloak in flask. In your server, You need more to handle all case such as when error request from keycloak, incorrect user