简而言之: SMART App Launch (SMART on FHIR) 是 HL7 的一项规范,用于说明 应用程序 如何代表用户获得对 FHIR 服务器 的授权访问。它基于 OAuth 2.0 和 OpenID Connect,并包含 FHIR 特定的约定:一个位于 .well-known/smart-configuration 的 发现文档;两种 启动 模式(EHR 启动,EHR 在当前患者的上下文中打开应用程序;以及 独立启动,用户打开应用程序并选择患者);采用 FHIR 感知语法的 范围(patient/Observation.rs 表示读取和搜索当前患者的 Observation);在令牌中返回的 启动上下文(患者、就诊);以及用于系统间访问的 后端服务,并使用签名的 JWT 客户端身份验证。SMART v2(2021 年起)强制要求使用 PKCE,增加了精细的范围和非对称客户端身份验证,并且是国家项目要求的版本。
第一步:发现
SMART App Launch 的发现始于应用获取 FHIR 服务器的 .well-known/smart-configuration 文档,该文档列出了授权和令牌端点、支持的功能(EHR 启动、独立启动、公共和机密客户端、OpenID Connect、患者和用户权限)、支持的范围、PKCE 代码挑战方法和授权类型,以便应用知道将用户发送到何处。
GET https://fhir.example-hospital.org/.well-known/smart-configuration
{
"issuer": "https://auth.example-hospital.org",
"authorization_endpoint": "https://auth.example-hospital.org/authorize",
"token_endpoint": "https://auth.example-hospital.org/token",
"introspection_endpoint": "https://auth.example-hospital.org/introspect",
"capabilities": ["launch-ehr", "launch-standalone", "client-public", "client-confidential-asymmetric", "sso-openid-connect", "context-ehr-patient", "context-standalone-patient", "permission-patient", "permission-user", "permission-v2", "permission-offline"],
"scopes_supported": ["openid", "fhirUser", "launch", "launch/patient", "patient/*.rs", "user/*.rs", "offline_access"],
"code_challenge_methods_supported": ["S256"],
"grant_types_supported": ["authorization_code", "client_credentials"]
}
应用程序了解将用户发送到何处以及服务器支持哪些功能。
第二步:启动
SMART App Launch 有两种启动模式。在 EHR 启动模式下,临床医生在 EHR 内部打开应用,EHR 会传递一个 iss 参数(FHIR 服务器)和一个不透明的启动令牌,该令牌编码了当前患者和就诊信息。在独立启动模式下,用户直接打开应用,授权服务器会要求他们选择或确认患者。
EHR 启动。 临床医生在 EHR 中点击应用程序;EHR 会打开应用程序的启动 URL,并附带两个参数:iss(FHIR 服务器)和 launch(一个不透明的令牌,其中编码了当前患者和就诊信息)。应用程序必须在授权请求中以 launch 范围回显 launch。
独立启动。 用户直接打开应用程序;应用程序知道 FHIR 服务器(已选择或配置)并使用 launch/patient 请求上下文;授权服务器会要求用户选择或确认患者。
第三步:带 PKCE 的授权码
SMART 授权步骤是带有 PKCE 的 OAuth 2.0 授权码流程:应用将用户发送到授权端点,并附带其范围、FHIR 服务器的 aud 和一个代码挑战;用户进行身份验证并批准;应用使用返回的代码和代码验证器交换访问令牌,该令牌与启动上下文一起到达。
GET https://auth.example-hospital.org/authorize?
response_type=code&client_id=my-app&redirect_uri=https://app.example.org/cb
&scope=openid%20fhirUser%20launch%20patient/Observation.rs%20patient/Condition.rs%20offline_access
&state=af0ifjsldkj&aud=https://fhir.example-hospital.org
&launch=xyz123&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256
用户进行身份验证(通过医院的身份提供商)并批准范围;服务器会返回一个 code 进行重定向;应用程序会进行交换:
POST https://auth.example-hospital.org/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=...&redirect_uri=https://app.example.org/cb&client_id=my-app&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid fhirUser launch patient/Observation.rs patient/Condition.rs offline_access",
"refresh_token": "a8c3...",
"id_token": "eyJhbGciOi...",
"patient": "Patient/123",
"encounter": "Encounter/456",
"fhirUser": "Practitioner/42",
"need_patient_banner": true,
"smart_style_url": "https://ehr.example.org/styles/smart.json"
}
启动上下文(patient、encounter、fhirUser)与令牌一起返回。公共客户端(移动和浏览器应用程序)使用 PKCE,不使用客户端密钥;机密客户端使用密钥进行身份验证,或者最好使用非对称方法下的 签名 JWT(private_key_jwt)。
范围
SMART on FHIR v2 的范围使用 context/resource.permissions 的语法,其中 context 是 patient、user 或 system,permissions 结合了 c、r、u、d 和 s,分别代表创建、读取、更新、删除和搜索,例如 patient/Observation.rs。粒度范围会添加过滤器,openid 和 fhirUser 提供用户身份,launch 范围请求上下文,offline_access 请求刷新令牌。
SMART v2 语法:<context>/<resource>.<permissions>,其中 context 是 patient(当前患者)、user(用户可能看到的任何内容)或 system(后端),permissions 是 c 创建、r 读取、u 更新、d 删除、s 搜索中的任何一个,按此顺序排列:patient/Observation.rs、user/Patient.rs、system/*.cruds。精细范围 添加了过滤器:patient/Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|vital-signs。openid fhirUser 提供 ID 令牌和用户的 FHIR 身份;launch、launch/patient、launch/encounter 请求上下文;offline_access 用于用户不在时使用的刷新令牌,online_access 仅在会话期间有效。v1 语法(patient/Observation.read)仍被许多服务器接受。
后端服务
对于在没有用户的情况下运行的系统(例如夜间导出、集成引擎),SMART 后端服务 使用 client_credentials,并带有签名的 JWT 断言(客户端的公钥发布在 JWKS URL 上)和 system/ 范围。没有用户,没有启动上下文,需要严格注册。
安全运行
安全运行 SMART App Launch 意味着注册精确的重定向 URI,绝不使用隐式流程,安全地存储和轮换刷新令牌,验证 ID 令牌的 state 和 aud,在每次 API 调用时验证令牌,在数据层强制执行范围和患者上下文,以确保一个患者的令牌绝不会读取另一个患者的数据,并记录每次访问。
注册精确的重定向 URI;切勿使用隐式流程;安全地存储刷新令牌并定期轮换;验证 state;检查 ID 令牌的 aud;在每次 API 调用时验证令牌(内省或 JWT 验证),并在数据层强制执行范围 和 患者上下文,因为针对 Patient/123 的令牌绝不能读取 Patient/124;记录每次访问(安全和身份:地图)。SMART 还定义了 患者访问品牌,这是一种应用程序向用户显示其可以连接的组织的方式,并与 SMART Health Links 互操作,以实现患者发起的共享。
何处需要
美国的患者访问规则要求认证的 EHR 支持 SMART App Launch 和后端服务;欧洲的国家项目采用它来进行应用程序访问(荷兰的 MedMij 使用 OAuth 2.0 和等效约定);IPS 和许多实施指南都假定它。请参阅 TEFCA 和 国家电子健康记录。
在 Anpheros 中
Anpheros Platform 使用 OAuth 2.0 和 PKCE 来支持应用程序,并使用签名的 JWT 客户端身份验证来支持后端,其范围源自患者的同意,并在每次请求时强制执行患者上下文。开发者网站记录了 身份验证 和 SMART on FHIR 后端模式 以便在此基础上进行构建。
相关页面
- 健康应用程序中的安全和身份:地图
- 患者同意平台
- SMART Health Links 详解
- CDS Hooks 详解
- FHIR 搜索详解
- SMART on FHIR 后端(开发者网站)
- 身份验证(开发者网站)
来源
- HL7 SMART App Launch (STU 2.2)
- HL7 SMART App Launch: 范围和启动上下文
- HL7 SMART App Launch: 后端服务
- IETF RFC 7636: PKCE
- IETF RFC 6749: OAuth 2.0
- OpenID Connect Core 1.0
常见问题
SMART on FHIR 和 OAuth 2.0 是同一回事吗?
它是 OAuth 2.0 和 OpenID Connect,并增加了 FHIR 特定的功能:发现、启动上下文、范围语法和后端服务。任何 OAuth 库都可以工作;SMART 约定才是使应用程序在不同 FHIR 服务器之间可移植的关键。
服务器端应用程序需要 PKCE 吗?
在 SMART v2 中,是的,对于所有使用授权码流程的客户端。机密客户端在此基础上增加了客户端身份验证(密钥或签名 JWT)。
patient/ 和 user/ 范围之间有什么区别?
patient/ 将访问限制在启动上下文中的单个患者;user/ 则授予已认证用户可以查看的任何内容,跨越不同患者。面向患者的应用程序使用 patient/;临床医生应用程序通常使用 user/ 并结合上下文。
SMART 应用程序可以写入记录吗?
如果其范围被授予创建或更新权限(c、u),并且服务器允许。许多部署只授予患者应用程序读取和搜索权限,并将写入操作通过特定的资源(如 QuestionnaireResponse)进行路由。
在沙盒中免费试用
5 分钟完成第一次 FHIR 调用. 一个内置患者授权的 HL7 FHIR R4 API:先在沙盒中试用,然后连接您自己的应用或诊所系统。
免费 · 30 位合成患者 · 无需信用卡

