{"id":20631722,"url":"https://github.com/manojkrgupta/python_fastapi_keycloak","last_synced_at":"2026-05-06T13:04:23.754Z","repository":{"id":254807584,"uuid":"847544462","full_name":"manojkrgupta/python_fastapi_keycloak","owner":"manojkrgupta","description":"An experiment with FastAPI and Keycloak integration","archived":false,"fork":false,"pushed_at":"2024-08-26T07:14:10.000Z","size":171,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-17T07:11:07.203Z","etag":null,"topics":["api","fastapi","iam","iam-policy","iam-role","keycloak","oauth2","python","swagger"],"latest_commit_sha":null,"homepage":"https://www.linkedin.com/in/manojkumar-gupta-87a04b15/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/manojkrgupta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-26T04:24:44.000Z","updated_at":"2024-11-25T04:40:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"0051aa5c-86e7-40fd-9ea8-d5c1f49e078a","html_url":"https://github.com/manojkrgupta/python_fastapi_keycloak","commit_stats":null,"previous_names":["manojkrgupta/python_fastapi_keycloak"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manojkrgupta%2Fpython_fastapi_keycloak","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manojkrgupta%2Fpython_fastapi_keycloak/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manojkrgupta%2Fpython_fastapi_keycloak/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manojkrgupta%2Fpython_fastapi_keycloak/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manojkrgupta","download_url":"https://codeload.github.com/manojkrgupta/python_fastapi_keycloak/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242619114,"owners_count":20159001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","fastapi","iam","iam-policy","iam-role","keycloak","oauth2","python","swagger"],"created_at":"2024-11-16T14:13:23.361Z","updated_at":"2026-05-06T13:04:18.711Z","avatar_url":"https://github.com/manojkrgupta.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Install dependencies\n```\npython3 -m pip install -r requirements.txt\n```\n\n### Start environment\n```text\n]$ cd etc/\n]$ mkdir postgres_data\n]$ mkdir keycloak_data\n]$ sudo docker login\n]$ sudo docker compose -f docker-compose.yml up\n```\n\n### Create keycloak realm, client, user, client scope if not already created.\n* Create Realm  : yahoo_realm\n* Create Client : yahoo_client\n  * Client Type=OpenID Connect\n  * Client Authentication Enabled, \n  * OAuth2.0 Enabled\n  * Root Login : http://127.0.0.1:8096/ \n  * Valid Redirect URIs: http://127.0.0.1:8096/docs/oauth2-redirect\n* Create User : yahoo_user\n  * Credentials -\u003e Set Password\n* Create Client scope : 'yahoo_client_scope' \n  * Within the settings of the 'yahoo_client_scope' goto Mappers tab\n    * Click \"Configure a new mapper\"\n    * Choose \"Audience\", Give a name = yahoo_audience\n      * Name: yahoo-audience\n      * Choose Mapper type: Audience\n      * Included Client Audience: yahoo_client\n      * Add to access token: on\n  * Within the Scopes tab in yahoo_client settings -- Click on \"Add client scope\" -\u003e choose \"yahoo_client_scope\" to assigned default client scopes\n\n### Configurge Application to connect to keycloak\n* Configuration File - bin/config.py\n* Sample Configuration :\n```text\nkeycloak_conf = keycloak_configuration(\n    url=\"http://127.0.0.1:8095/\",\n    realm=\"yahoo_realm\",\n    client_id=\"yahoo_client\",\n    client_secret=\"\u003c\u003cGet this from Keycloak -\u003e yahoo_realm -\u003e Clients -\u003e yahoo_client -\u003e Credentials -\u003e Client Secret\u003e\u003e\",\n    auth_url=\"http://127.0.0.1:8095/realms/yahoo_realm/protocol/openid-connect/auth\",\n    token_url=\"http://127.0.0.1:8095/realms/yahoo_realm/protocol/openid-connect/token\",\n    cert_url = \"http://127.0.0.1:8095/realms/yahoo_realm/protocol/openid-connect/certs\",\n)\n```\n\n### Start Application (Webserver, FastAPI, Uvicorn)\n```text\n]$ cd bin\n]$ uvicorn main:app --reload --log-level debug --port 8096 --host 127.0.0.1\n```\n\n### URLs\n* Keycloak            : http://127.0.0.1:8095/   (admin/admin)\n* Application Home    : http://127.0.0.1:8096/\n* Application Swagger : http://127.0.0.1:8096/docs\n* Public Area         : http://127.0.0.1:8096/\n* Private Area        : http://127.0.0.1:8096/safe_house\n\n### Simple Test\n* Go to Swagger URL http://127.0.0.1:8096/docs\n* Click on Authorize Lock Image (top right)\n* ![](images/authorization_0.png)\n* This will redirect you to keycloak page\n* * ![](images/authorization_1.png)\n* Enter Client ID : yahoo_client\n* Enter Client Secret : `\u003c\u003cGet this from Keycloak -\u003e yahoo_realm -\u003e Clients -\u003e yahoo_client -\u003e Credentials -\u003e Client Secret\u003e\u003e`\n* Upon authentication of client (Once the platform/app is authenticated), keycloak redirects to ask for User ID and Password\n* ![](images/authorization_2.png)\n* Once success, you will see a page like\n* ![](images/authorization_3.png)\n\n\n### Tests using command line\n* Accessing Public Area\n```text\n]$  curl -X 'GET'   'http://127.0.0.1:8096/'  \n{\"message\":\"Hello World\"}\n]$ \n```\n* Accessing Private Area -- without authentication\n```text\n]$  curl -X 'GET' 'http://127.0.0.1:8096/safe_house'\n{\"detail\":\"Not authenticated\"}\n]$ \n```\n* Accessing Private Area -- without authentication\n```text\n]$  curl -X 'GET' 'http://127.0.0.1:8096/safe_house'\n{\"detail\":\"Not authenticated\"}\n]$ \n```\n* Accessing Private Area -- After authentication, and copying the Tokens from Swagger\n```text\n]$ curl -X 'GET' \\\n'http://127.0.0.1:8096/safe_house' \\\n-H 'accept: application/json' \\\n-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIyQUlfTHFGSHNybW9hZDR6dlgtVkpOUFVlQ2x3ZlpIV0ZvNVh1cmVIUk9VIn0.eyJleHAiOjE3MjQ2NTU1NjIsImlhdCI6MTcyNDY1NTI2MiwiYXV0aF90aW1lIjoxNzI0NjU1MjYyLCJqdGkiOiI5MDdmNDY4NS1lZDY2LTQ2NjktYjgxZS0yZDlkNzZjN2M3ZDQiLCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwOTUvcmVhbG1zL3lhaG9vX3JlYWxtIiwiYXVkIjpbInlhaG9vX2NsaWVudCIsImFjY291bnQiXSwic3ViIjoiZjM5OTg4YWQtZWUzMC00YzhiLWEwMjYtMWRlNWRlZTIxZjNhIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoieWFob29fY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6ImNkYmVjMDM2LTFlNDMtNDAyMi1iZTRjLWE0YTUwN2Y0ZjZiMyIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDk2Il0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy15YWhvb19yZWFsbSJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCB5YWhvb19jbGllbnRfc2NvcGUiLCJzaWQiOiJjZGJlYzAzNi0xZTQzLTQwMjItYmU0Yy1hNGE1MDdmNGY2YjMiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InlhaG9vX3VzZXIifQ.CiQUtsVPnArieH0MbYh18MkEqRBl42zpqlTThr2c74KZTLu2EFqzzR-DfKpSZ6tu3yvaH-g6R5pnBQkxUJ9C1gjGlnFYJCLWi64zhrl2HjwigDjiRM9xnSF1_Gt0UiZ5QV2mEc5rwoUveog170o4MEogDsAs49onSEPBHyQzUhTfVDs_ge8_INRfiFmDCsMtRLXy0tF-tl331aLkcui-blz5JlPBXIsl0yAyNWYDG-ZHYy0ahZNfZrPSjZhQChWo3YI_l7ZbfO3CE16HnxX4LZ1cp7clm7_73BlH5CKVLt5CkiIX3kLvF8utO3--slvpXD68hpDe8DvuHCBz1dTmTQ'\n{\"message\":\"Hello yahoo_user!!\"}\n```\n* Accessing Private Area -- with incorrect keys\n```text\n]$ curl -X 'GET'   'http://127.0.0.1:8096/safe_house'   -H 'accept: application/json'   -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIyQUlfTHFGSHNybW9hZDR6dlgtVkpOUFVlQ2x3ZlpIV0ZvNVh1cmVIUk9VIn0.eyJleHAiOjE3MjQ2NTU1NjIsImlhdCI6MTcyNDY1NTI2MiwiYXV0aF90aW1lIjoxNzI0NjU1MjYyLCJqdGkiOiI5MDdmNDY4NS1lZDY2LTQ2NjktYjgxZS0yZDlkNzZjN2M3ZDQiLCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwOTUvcmVhbG1zL3lhaG9vX3JlYWxtIiwiYXVkIjpbInlhaG9vX2NsaWVudCIsImFjY291bnQiXSwic3ViIjoiZjM5OTg4YWQtZWUzMC00YzhiLWEwMjYtMWRlNWRlZTIxZjNhIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoieWFob29fY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6ImNkYmVjMDM2LTFlNDMtNDAyMi1iZTRjLWE0YTUwN2Y0ZjZiMyIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDk2Il0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy15YWhvb19yZWFsbSJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCB5YWhvb19jbGllbnRfc2NvcGUiLCJzaWQiOiJjZGJlYzAzNi0xZTQzLTQwMjItYmU0Yy1hNGE1MDdmNGY2YjMiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InlhaG9vX3VzZXIifQ.CiQUtsVPnArieH0MbYh18MkEqRBl42zpqlTThr2c74KZTLu2EFqzzR-DfKpSZ6tu3yvaH-g6R5pnBQkxUJ9C1gjGlnFYJCLWi64zhrl2HjwigDjiRM9xnSF1_Gt0UiZ5QV2mEc5rwoUveog170o4MEogDsAs49onSEPBHyQzUhTfVDs_ge8_INRfiFmDCsMtRLXy0tF-tl331aLkcui-blz5JlPBXIsl0yAyNWYDG-ZHYy0ahZNfZrPSjZhQChWo3YI_l7ZbfO3CE16HnxX4LZ1cp7clm7_73BlH5CKVLt5CkiIX3kaaaaaLvF8utO3--slvpXD68hpDe8DvuHCBz1dTmTQ'\n{\"detail\":\"failed to authenticate : Signature verification failed\"}\n]$\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanojkrgupta%2Fpython_fastapi_keycloak","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanojkrgupta%2Fpython_fastapi_keycloak","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanojkrgupta%2Fpython_fastapi_keycloak/lists"}