项目:嵌入式PostMessage+kubectl网关示例
构建、运行和访问嵌入式侦听器页面的快速说明。
先决条件
- Python 3.8+
- Git(可选)
- Windows/macOS/Linux命令行
安装(建议在虚拟环境中安装)
python -m venv .venv
.venv\Scripts\activate # Windows
# or: source .venv/bin/activate # macOS / Linux
pip install --upgrade pip
pip install fastapi uvicorn aiohttp markdown2 jinja2运行应用程序(开发)
uvicorn main:app --reload --host 0.0.0.0 --port 8000打开嵌入式页面
- 在浏览器中,访问:http://localhost:8000/embedded
- 该页面旨在加载到iframe中;它从父窗口监听postMessage。
示例postMessage(来自父帧)
- 假设你有一个指向嵌入式页面的iframe元素:
- 从父窗口的JavaScript控制台,您可以发送JSON有效负载(根据需要替换值):
const payload = {
"fhirPatient": "patient-123",
"patientFirstName": "Jane",
"patientLastName": "Doe",
"encounterUniqueId": "enc-456",
"userName": "jdoe",
"userFullName": "Jane Doe",
"userFirstName": "Jane",
"userLastName": "Doe",
"encounterDate": "2025-11-01T10:00:00Z",
"parentFrameUrl": "https://your-parent.example",
"gatewayUrl": "https://wic-sandbox.dev.app-nonprod.mcp.org",
"sdJwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"emr": "ExampleEMR"
};
const iframe = document.getElementById('embeddedFrame');
iframe.contentWindow.postMessage(JSON.stringify(payload), '*');备注
- 嵌入式页面将:
- 使用患者或用户名字段显示“欢迎,{firstName}{lastName}”。 - 显示接收到的有效载荷。 - 对以下对象执行异步kubectl GET {gatewayUrl}/Patient/{fhirPatient} 使用 Authorization: Bearer {sdJwt} (如果提供)并显示返回的JSON。
- 如果您的网关为患者资源使用了不同的路径,请更新
static/embedded.js因此。 - 该应用程序在中包含了内容安全策略的头变量
main.py.THis是梅奥诊所平台部署的当前CSP。如果您的环境需要其他来源,请更新那里的CSP列表。 - 对于生产,请确保postMessage来源检查的安全,不要使用
'*'在发布敏感数据时,使用targetOrigin。
使用梅奥内省终点验证sd jwt
- 在生产环境中,您不应该隐式信任提供给您的sd jwt。特别是如果您使用用户名在软件中提供SSO功能。令牌必须在首次收到自检端点时进行验证。不要仅仅依赖令牌作为有效性的证明。
- Python验证脚本示例可在
validate_sd_jwt.py. - 替换
MAYO_PROVIDED_SECRET_TOKEN您的技术服务团队成员向您提供的秘密。 - 脚本向发送POST请求
https://catswebapi.mcp.org/api/v1/token/introspect其中sd-jwt为形式编码体。
Python验证示例
import http.client
conn = http.client.HTTPSConnection("catswebapi.mcp.org")
payload = "token=REPLACE_WITH_YOUR_SD_JWT"
headers = {
'Content-Type': "application/x-www-form-urlencoded",
'Authorization': "Bearer REPLACE_WITH_YOUR_SECRET_TOKEN"
}
conn.request("POST", "/api/v1/token/introspect", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))故障排除
- 如果Contoso调用失败,请检查浏览器控制台是否存在CORS/网络错误,并确保网关接受sdJwt标头。
- 在嵌入到另一个域(CSP和网络/防火墙)时,确保可以从父帧源访问应用程序。
