You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI对接Redhat SSO(Keycloak) OIDC授权码模式遇问题求助

FastAPI 与 Keycloak(Redhat SSO)授权码模式认证问题解决方案

问题描述

使用fastapi_third_party_auth库实现FastAPI与Keycloak的OIDC认证时,隐式授权模式可正常运行,但切换到authorization_code模式后出现以下问题:

  1. 首次报错:Missing parameter: code_challenge_method
  2. 尝试禁用PKCE后,新报错:{"error":"invalid_request","error_description":"Missing parameter: username"}

原代码如下:

import uvicorn
from fastapi import Depends
from fastapi import FastAPI
from fastapi import Security
from fastapi import status
from fastapi.middleware.cors import CORSMiddleware
from starlette.responses import RedirectResponse

from fastapi_third_party_auth import Auth
from fastapi_third_party_auth import KeycloakIDToken


auth = Auth(
  openid_connect_url="https://XXXXX/auth/realms/Sandbox/.well-known/openid-configuration",
  issuer="https://XXXX/auth/realms/Sandbox",  # optional, verification only
  client_id="devops-tool",  # optional, verification only
  #scopes=["email", "openid"],  # optional, verification only
  #grant_types=[GrantType.IMPLICIT],  # optional, docs only
  grant_types=["authorization_code"],
  #grant_types=["client_credentials"]
  #idtoken_model=KeycloakIDToken,  # optional, verification only
)


app = FastAPI(
    title="Example",
    version="dev",
    dependencies=[Depends(auth)],
)

# CORS errors instead of seeing internal exceptions
# https://stackoverflow.com/questions/63606055/why-do-i-get-cors-error-reason-cors-request-did-not-succeed
#cors = CORSMiddleware(
#    app=app,
#    allow_origins=["*"],
#    allow_credentials=True,
#    allow_methods=["*"],
#    allow_headers=["*"],
#)


@app.get("/", status_code=status.HTTP_303_SEE_OTHER)
def redirect_to_docs():
    return RedirectResponse(url="/docs")


@app.get("/protected")
def protected(id_token: KeycloakIDToken = Security(auth.required)):
    return dict(message=f"You are {id_token}")

解决方案

1. 解决Missing parameter: code_challenge_method错误

该错误源于PKCE(Proof Key for Code Exchange)的强制要求,尤其是当Keycloak客户端为**公共类型(Public)**时,PKCE是授权码模式的必需项,不能禁用。处理步骤:

  • 升级fastapi_third_party_auth库:确保使用最新版本,旧版本可能不支持自动生成PKCE参数(code_challenge和code_challenge_method)。
  • 确认Keycloak客户端配置:
    1. 登录Keycloak管理控制台,进入目标客户端devops-tool的Settings标签页。
    2. 将Access Type设置为public(若为后端服务可设为confidential,但需额外配置客户端密钥)。
    3. 确保Standard Flow Enabled(授权码流)处于开启状态。

2. 解决Missing parameter: username错误

该错误说明请求未走标准授权码流程(跳转登录页→获取授权码→换取令牌),而是直接向令牌端点发送请求。处理步骤:

  • 移除全局认证依赖:将FastApp初始化时的dependencies=[Depends(auth)]删除,避免在回调路由和文档路由触发认证拦截,导致流程异常。
  • 配置回调地址:在Auth实例中添加redirect_uri参数,并确保该地址已加入Keycloak客户端的Valid Redirect URIs列表:
    auth = Auth(
        openid_connect_url="https://XXXXX/auth/realms/Sandbox/.well-known/openid-configuration",
        issuer="https://XXXX/auth/realms/Sandbox",
        client_id="devops-tool",
        grant_types=["authorization_code"],
        redirect_uri="http://localhost:8000/auth/callback",  # 根据实际部署地址调整
    )
    
  • 验证Keycloak客户端的重定向URI:在Keycloak客户端Settings标签页的Valid Redirect URIs中添加上述redirect_uri(支持通配符,如http://localhost:8000/*)。
  • (可选)若为Confidential客户端:需在Auth配置中添加client_secret参数,该密钥可从Keycloak客户端的Credentials标签页获取。

修改后的完整代码示例

import uvicorn
from fastapi import FastAPI
from fastapi import Security
from fastapi import status
from starlette.responses import RedirectResponse

from fastapi_third_party_auth import Auth
from fastapi_third_party_auth import KeycloakIDToken


auth = Auth(
    openid_connect_url="https://XXXXX/auth/realms/Sandbox/.well-known/openid-configuration",
    issuer="https://XXXX/auth/realms/Sandbox",
    client_id="devops-tool",
    grant_types=["authorization_code"],
    redirect_uri="http://localhost:8000/auth/callback",  # 调整为实际地址
)


app = FastAPI(
    title="Example",
    version="dev",
    # 移除全局认证依赖
)


@app.get("/", status_code=status.HTTP_303_SEE_OTHER)
def redirect_to_docs():
    return RedirectResponse(url="/docs")


@app.get("/protected")
def protected(id_token: KeycloakIDToken = Security(auth.required)):
    return dict(message=f"You are {id_token}")


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

测试流程

  1. 启动FastAPI服务,访问http://localhost:8000/protected。
  2. 页面会自动跳转到Keycloak的登录界面,输入合法账号密码后完成登录。
  3. 登录成功后会自动跳转回/protected,并返回包含ID Token的响应。

内容的提问来源于stack exchange,提问作者ruben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:27:14