如何通过Prefect CLI连接Keycloak认证的Prefect API?
问题背景
我在GKE集群上部署了Prefect Server,地址为https://prefect.my-site.com/,由于Prefect无内置认证,用Keycloak实现安全登录,访问Prefect会重定向到Keycloak认证后返回。但使用Prefect CLI部署flows时,设置PREFECT_API_URL=https://prefect.my-site.com/api后触发Keycloak认证拦截,报错:
prefect.exceptions.PrefectHTTPStatusError: Client error '415 Unsupported Media Type' for URL 'https://keycloak.my-site.io/auth/realms/master/protocol/openid-connect/auth?client_id=prefect-server&redirect_uri=https%3A%2F%2Fprefect.my-site.io%2Foauth%2Fcallback&response_type=code&scope=openid+email+profile&state=XXX'
Response: {'error': 'RESTEASY003065: Cannot consume content type'}
尝试通过Keycloak CLI先认证再使用Prefect CLI,无效。
解决方案
1. 创建Keycloak专用客户端(客户端凭证模式)
这是最适合CLI工具的无交互认证方式:
- 在Keycloak控制台中,为Prefect CLI新建一个客户端:
- 访问类型选择
confidential - 启用服务账户启用选项
- 配置客户端权限,确保能访问Prefect Server的API资源
- 访问类型选择
- 获取该客户端的
Client ID和Client Secret,执行以下命令获取访问令牌:curl -X POST https://keycloak.my-site.io/auth/realms/master/protocol/openid-connect/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=YOUR_CLI_CLIENT_ID&client_secret=YOUR_CLI_CLIENT_SECRET" - 提取返回结果中的
access_token,设置Prefect环境变量:export PREFECT_API_KEY="Bearer $ACCESS_TOKEN" export PREFECT_API_URL=https://prefect.my-site.com/api
之后即可正常使用Prefect CLI执行部署等操作。
2. 启用Keycloak密码模式(适合信任环境)
如果允许使用用户名密码直接认证,可开启Direct Access Grants:
- 在现有
prefect-serverKeycloak客户端设置中,开启Direct Access Grants Enabled选项 - 用用户凭证获取令牌:
curl -X POST https://keycloak.my-site.io/auth/realms/master/protocol/openid-connect/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password&client_id=prefect-server&username=YOUR_USERNAME&password=YOUR_PASSWORD&scope=openid" - 同样设置
PREFECT_API_KEY为Bearer加令牌值,配合PREFECT_API_URL使用CLI。
3. 排查请求头匹配问题
415错误本质是请求Content-Type不匹配,可检查:
- Prefect Server的反向代理(如Nginx/Traefik)配置,确保在转发认证请求时,没有错误修改Content-Type
- 确认Keycloak的认证端点只接受
application/x-www-form-urlencoded格式的请求,而Prefect CLI通过代理转发时没有发送JSON格式请求到认证端点
内容的提问来源于stack exchange,提问作者Noa Be

