

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# SMART on FHIR 支持 AWS HealthLake
<a name="reference-smart-on-fhir"></a>

支持 FHIR HealthLake 的数据存储上的可替代医疗应用程序和可重复使用技术 (SMART) 允许在符合 FHIR 的应用程序上访问 SMART。 HealthLake 通过使用第三方授权服务器对请求进行身份验证和授权来访问数据。因此，您不是通过管理用户凭证 AWS Identity and Access Management，而是使用符合 FHIR 标准的授权服务器上的 SMART。

**注意**  
HealthLake 在 FHIR 版本 1.0 和 2.0 上支持 SMART。要了解有关这些框架的更多信息，请参阅 *FHIR R4* 文档中的 [SMART App Laun](https://www.hl7.org/fhir/smart-app-launch/) ch。  
HealthLake 数据存储支持以下 SMART on FHIR 请求的身份验证和授权框架：  
**OpenID (authN)**：用于对个人或客户应用程序进行身份验证，即他们声称的身份（或什么）。
**OAuth 2.0 (AuthZ)**：用于授权经过身份验证的请求可以读取或写入 HealthLake 数据存储中的哪些 FHIR 资源。这是由授权服务器中设置的范围定义的。

您可以使用 AWS CLI 或 AWS SDKs创建 SMART on 启用 FHIR 的数据存储。有关更多信息，请参阅 [创建 HealthLake 数据存储](managing-data-stores-create.md)。

**Topics**
+ [在 FHIR 上使用 SMART 入门](reference-smart-on-fhir-getting-started.md)
+ [HealthLake FHIR 上的 SMART 的身份验证要求](reference-smart-on-fhir-authentication.md)
+ [支持的 FHIR OAuth 2.0 瞄准镜上的 SMART HealthLake](reference-smart-on-fhir-oauth-scopes.md)
+ [使用令牌验证 AWS Lambda](reference-smart-on-fhir-token-validation.md)
+ [在启用 SMART on FHIR 的数据存储中使用细粒度授权 HealthLake](reference-smart-on-fhir-fine-grained-authorization.md)
+ [正在获取 SMART on FHIR 发现文档](reference-smart-on-fhir-discovery-document.md)
+ [在支持 Smart 的数据存储上发出 FHIR REST HealthLake API 请求](reference-smart-on-fhir-request-example.md)

# 在 FHIR 上使用 SMART 入门
<a name="reference-smart-on-fhir-getting-started"></a>

以下主题介绍如何开始使用 SMART on FHIR 授权。 AWS HealthLake它们包括必须在 AWS 账户中预置的资源、在 FHIR 上启用 SMART HealthLake 的数据存储的创建，以及一个 SMART on FHIR 客户端应用程序如何与授权服务器和数据存储交互的示例。 HealthLake 

**Topics**
+ [在 FHIR 上为 SMART 设置资源](#smart-on-fhir-resources)
+ [FHIR 上的 SMART 的客户端应用程序工作流程](#smart-on-fhir-client-app-workflow)

## 在 FHIR 上为 SMART 设置资源
<a name="smart-on-fhir-resources"></a>

以下步骤定义了如何处理 SMART on FHIR 请求 HealthLake 以及成功处理请求所需的资源。以下元素在工作流程中协同工作，以提出 SMART on FHIR 请求：
+ **最终用户**：通常，患者或临床医生使用第三方 SMART on FHIR 应用程序访问数据存储中的HealthLake 数据。
+ **SMART on FHIR 应用程序（称为客户端应用程序）**：想要访问在数据存储中HealthLake 找到的数据的应用程序。
+ **授权服务器**：符合 OpenID Connect 标准的服务器，能够对用户进行身份验证并颁发访问令牌。
+ ** HealthLake 数据存储**：支持 SMART on FHIR HealthLake 的数据存储，它使用 Lambda 函数来响应提供不记名令牌的 FHIR REST 请求。

要使这些元素协同工作，必须创建以下资源。

**注意**  
我们建议在设置授权服务器、在其上定义必要的[范围](reference-smart-on-fhir-oauth-scopes.md)并创建处理[令牌](reference-smart-on-fhir-token-validation.md)自省的 AWS Lambda 函数之后，在启用 FHIR HealthLake 的数据存储上创建 SMART。

**1. 设置授权服务器端点**  
要使用 SMART on FHIR 框架，您需要设置一个第三方授权服务器，该服务器可以验证在数据存储上发出的 FHIR REST 请求。有关更多信息，请参阅 [HealthLake FHIR 上的 SMART 的身份验证要求](reference-smart-on-fhir-authentication.md)。

**2. 在授权服务器上定义范围以控制 HealthLake 数据存储访问级别**  
SMART on FHIR 框架使用 OAuth 作用域来确定经过身份验证的请求可以访问哪些 FHIR 资源以及访问的范围。定义作用域是一种针对最低权限进行设计的方法。有关更多信息，请参阅 [支持的 FHIR OAuth 2.0 瞄准镜上的 SMART HealthLake](reference-smart-on-fhir-oauth-scopes.md)。

**3. 设置一个能够执行令牌内省的 AWS Lambda 函数**  
客户端应用程序在启用 SMART on FHIR 的数据存储上发送的 FHIR REST 请求包含 JSON Web 令牌 (JWT)。有关更多信息，请参阅[解码 JWT](reference-smart-on-fhir-token-validation.md)。

**4. 在启用 FHIR 时创建 SMART HealthLake 数据存储**  
要在 FHIR 上创建 SMART HealthLake 数据存储，您需要提供一个。`IdentityProviderConfiguration`有关更多信息，请参阅 [创建 HealthLake 数据存储](managing-data-stores-create.md)。

## FHIR 上的 SMART 的客户端应用程序工作流程
<a name="smart-on-fhir-client-app-workflow"></a>

以下部分说明了如何在 SMART on FHIR 的上下文中启动客户端应用程序并在 HealthLake 数据存储上成功发出 FHIR REST 请求。

**1. 使用客户端应用程序向众所周知的统一资源标识符`GET`发出请求**  
启用 SMART 的客户端应用程序必须`GET`请求查找 HealthLake 数据存储的授权端点。这是通过众所周知的统一资源标识符 (URI) 请求完成的。有关更多信息，请参阅 [正在获取 SMART on FHIR 发现文档](reference-smart-on-fhir-discovery-document.md)。

**2. 请求访问权限和范围**  
客户端应用程序使用授权服务器的授权端点，以便用户可以登录。此过程对用户进行身份验证。作用域用于定义客户端应用程序可以访问 HealthLake 数据存储中的哪些 FHIR 资源。有关更多信息，请参阅 [支持的 FHIR OAuth 2.0 瞄准镜上的 SMART HealthLake](reference-smart-on-fhir-oauth-scopes.md)。

**3. 访问令牌**  
现在，用户已通过身份验证，客户端应用程序将收到来自授权服务器的 JWT 访问令牌。此令牌是在客户端应用程序向发送 FHIR REST 请求时提供的。 HealthLake有关更多信息，请参阅 [令牌验证](reference-smart-on-fhir-token-validation.md)。

**4. 在启用 HealthLake FHIR 的数据存储上在 SMART 上发出 FHIR REST API 请求**  
现在，客户端应用程序可以使用授权服务器提供的访问令牌向 HealthLake 数据存储端点发送 FHIR REST API 请求。有关更多信息，请参阅 [在支持 Smart 的数据存储上发出 FHIR REST HealthLake API 请求](reference-smart-on-fhir-request-example.md)。

**5. 验证 JWT 访问令牌**  
要验证在 FHIR REST 请求中发送的访问令牌，请使用 Lambda 函数。有关更多信息，请参阅 [使用令牌验证 AWS Lambda](reference-smart-on-fhir-token-validation.md)。

# HealthLake FHIR 上的 SMART 的身份验证要求
<a name="reference-smart-on-fhir-authentication"></a>

要访问支持 FHIR 的 SMART on HealthLake 数据存储中的 FHIR 资源，客户端应用程序必须由 OAuth 兼容 2.0 的授权服务器授权，并在 FHIR REST API 请求中出示OAuth 持有者令牌。要查找授权服务器的端点，请通过`Well-Known`统一资源标识符使用 SM HealthLake ART on FHIR 发现文档。要了解有关此过程的更多信息，请参阅[正在获取 SMART on FHIR 发现文档](reference-smart-on-fhir-discovery-document.md)。

在 FHIR HealthLake 数据存储上创建 SMART 时，必须在`CreateFHIRDatastore`请求的`metadata`元素中定义授权服务器的端点和令牌端点。要了解有关定义`metadata`元素的更多信息，请参阅[创建 HealthLake 数据存储](managing-data-stores-create.md)。

使用授权服务器端点，客户端应用程序将使用授权服务对用户进行身份验证。授权和身份验证后，授权服务会生成 JSON Web 令牌 (JWT) 并传递给客户端应用程序。此令牌包含允许客户端应用程序使用的 FHIR 资源范围，这反过来又限制了用户能够访问的数据。或者，如果提供了启动范围，则响应中将包含这些详细信息。要了解有关支持的 SMART on FHIR 示波器的更多信息 HealthLake，请参阅[支持的 FHIR OAuth 2.0 瞄准镜上的 SMART HealthLake](reference-smart-on-fhir-oauth-scopes.md)。

使用授权服务器授予的 JWT，客户端应用程序对启用 FHIR 的 SMART 数据存储进行 FHIR REST API 调用 HealthLake 。要验证和解码 JWT，您需要创建一个 Lambda 函数。 HealthLake 在收到 FHIR REST API 请求时代表你调用此 Lambda 函数。要查看起始 Lambda 函数的示例，请参阅。[使用令牌验证 AWS Lambda](reference-smart-on-fhir-token-validation.md)

## 创建启用 FHIR 的 SMART HealthLake 数据存储所需的授权服务器元素
<a name="datastore-auth-server"></a>

在`CreateFHIRDatastore`请求中，您需要提供授权端点和令牌端点作为`IdentityProviderConfiguration`对象中`metadata`元素的一部分。授权端点和令牌端点都是必需的。要查看`CreateFHIRDatastore`请求中如何指定这一点的示例，请参阅[创建 HealthLake 数据存储](managing-data-stores-create.md)。

## 在启用 HealthLake FHIR 的数据存储上的 SMART 上完成 FHIR REST API 请求所需的声明
<a name="server-response"></a>

您的 AWS Lambda 函数必须包含以下声明才能成为启用 SMART on FHIR HealthLake 的数据存储上的有效 FHIR REST API 请求。
+ `nbf`:[（Not Before）索赔](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) — “nbf”（不是之前）索赔指明了在此之前不得接受 JWT 进行处理的时间。“nbf” 索赔的处理要求当前索赔 date/time 必须高于或等于 “nbf” 索赔中 date/time 列出的前值。我们提供的示例 Lambda 函数`iat`从服务器响应转换为。`nbf`
+ `exp`:[（到期时间）索赔](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) — “exp”（到期时间）索赔确定了过期时间，在此时间或之后，JWT 不得被接受处理。
+ `isAuthorized`: 布尔值设置为`True`。表示请求已在授权服务器上获得授权。
+ `aud`:[（受众）声明](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) — “aud”（受众）声明用于标识智威汤逊所针对的收件人。这必须是启用 SMART on FHIR HealthLake 的数据存储端点。
+ `scope`：这必须是至少一个与 FHIR 资源相关的范围。此范围是在您的授权服务器上定义的。要了解有关接受的 FHIR 资源相关范围的更多信息 HealthLake，请参阅[SMART 对 FHIR 的资源范围适用于 HealthLake](reference-smart-on-fhir-oauth-scopes.md#smart-on-fhir-scopes-rest)。

# 支持的 FHIR OAuth 2.0 瞄准镜上的 SMART HealthLake
<a name="reference-smart-on-fhir-oauth-scopes"></a>

HealthLake 使用 OAuth 2.0 作为授权协议。在授权服务器上使用此协议可以定义客户端应用程序有权访问的 FHIR 资源 HealthLake 的数据存储权限（创建、读取、更新、删除和搜索）。

SMART on FHIR 框架定义了一组可以向授权服务器请求的范围。例如，仅允许患者查看实验室结果或查看其联系方式的客户端应用程序应仅被*授权*申请`read`示波器。

**注意**  
HealthLake 为 FHIR V1 和 V2 上的 SMART 提供支持，如下所述。创建数据存储时，FH [https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html#HealthLake-Type-IdentityProviderConfiguration-AuthorizationStrategy](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html#HealthLake-Type-IdentityProviderConfiguration-AuthorizationStrategy)IR 上的 SMART 设置为以下三个值之一：  
`SMART_ON_FHIR_V1`— Support 在 FHIR V1 上仅支持 SMART，其中包括`read`（读取/搜索）和`write`（）权限。create/update/delete
`SMART_ON_FHIR`— Support 在 FHIR V1 和 V2 上同时支持 SMART，其中包括`create`、、`read``update``delete`、和权限。`search`
`AWS_AUTH`— 默认 AWS HealthLake 授权策略；与 FHIR 上的 SMART 无关。

## 独立发布范围
<a name="smart-on-fhir-scopes-launch"></a>

HealthLake 支持独立启动模式范围`launch/patient`。

在独立启动模式下，客户端应用程序请求访问患者的临床数据，因为客户端应用程序不知道用户和患者。因此，客户端应用程序的授权请求明确要求返回患者范围。成功进行身份验证后，授权服务器会发出包含所请求的启动患者范围的访问令牌。所需的患者环境与访问令牌一起在授权服务器的响应中提供。


**支持的启动模式范围**  

| Scope | 说明 | 
| --- | --- | 
| `launch/patient` |  OAuth 2.0 授权请求中的一个参数，要求在授权响应中返回患者数据。 | 

## SMART 对 FHIR 的资源范围适用于 HealthLake
<a name="smart-on-fhir-scopes-rest"></a>

HealthLake 在 FHIR 资源范围上定义了三个级别的 SMART。
+ `patient`范围允许访问有关单个患者的特定数据。
+ `user`作用域授予对用户可以访问的特定数据的访问权限。
+ `system`作用域授予对在 HealthLake 数据存储中找到的所有 FHIR 资源的访问权限。

以下各节列出了在 FHIR V1 上使用 SMART 或在 FHIR V2 上使用 SMART 构建 FHIR 资源范围的语法。

**注意**  
SMART on FHIR 授权策略是在创建数据存储时设置的。有关更多信息，请参阅《AWS HealthLake API Reference》**中的 [https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html#HealthLake-Type-IdentityProviderConfiguration-AuthorizationStrategy](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html#HealthLake-Type-IdentityProviderConfiguration-AuthorizationStrategy)。

### 支持 FHIR V1 瞄准镜的 SMART HealthLake
<a name="reference-smart-on-fhir-v1"></a>

在 FHIR V1 上使用 SMART 时，构建 FHIR 资源范围的通用语法如下。 HealthLake 要查看以下示例中的整个 URL 路径，请滚动到 “**复制**” 按钮。

```
('patient' | 'user' | 'system') '/' (fhir-resource | '*') '.' ('read' | 'write' | '*')
```


**SMART on FHIR v1 支持的授权范围**  

| 作用域语法 | 示例：作用域 | 结果 | 
| --- | --- | --- | 
| `patient/(fhir-resource \| '*').('read' \| 'write' \| '*')` | patient/AllergyIntolerance.\$1 | 患者客户端应用程序具有对所有记录的过敏症的实例级读/写访问权限。 | 
| `user/(fhir-resource \| '*').('read' \| 'write' \| '*')` | user/Observation.read | 用户客户端应用程序具有对所有记录的观察结果的实例级 read/write 访问权限。 | 
| system/('read' \$1 'write' \$1 \$1) | system/\$1.\$1 | 系统客户端应用程序 read/write 可以访问所有 FHIR 资源数据。 | 

### 支持 FHIR V2 瞄准镜的 SMART HealthLake
<a name="reference-smart-on-fhir-v2"></a>

在 FHIR V2 上使用 SMART 时，构建 FHIR 资源范围的通用语法如下。 HealthLake 要查看以下示例中的整个 URL 路径，请滚动到 “**复制**” 按钮。

```
('patient' | 'user' | 'system') '/' (fhir-resource | '*') '.' ('c' | 'r' | 'u' | 'd' | 's')
```

**注意**  
要在 FHIR V2 上使用 SMART，必须[https://hl7.org/fhir/smart-app-launch/STU2/conformance.html#permissions](https://hl7.org/fhir/smart-app-launch/STU2/conformance.html#permissions)将值传递到元数据`capabilities`字符串中，该字符串是[https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html)数据类型的成员。  
HealthLake 支持精细作用域。有关更多信息，请参阅《*FHIR 美国核心实施*指南》中[支持的粒度范围](https://hl7.org/fhir/us/core/scopes.html#the-following-granular-scopes-shall-be-supported)。


**SMART on FHIR V2 支持的授权范围**  

| 作用域语法 | 示例 V1 作用域 | 结果 | 
| --- | --- | --- | 
| `patient/Observation.rs` | user/Observation.read | 允许读取和搜索当前患者的Observation资源。 | 
| `system/*.cruds` | system/\$1.\$1 | 系统客户端应用程序create/read/update/delete/search可以完全访问所有 FHIR 资源数据。 | 

# 使用令牌验证 AWS Lambda
<a name="reference-smart-on-fhir-token-validation"></a>

创建启用 FHIR 的 HealthLake SMART 数据存储时，必须在请求中`CreateFHIRDatastore`提供 AWS Lambda 该函数的 ARN。Lambda 函数的 ARN 是使用参数在`IdentityProviderConfiguration`对象中指定的。`IdpLambdaArn`

在创建 SMART on 启用 FHIR 的数据存储之前，必须创建 Lambda 函数。一旦创建了数据存储，就无法更改 Lambda ARN。要查看您在创建数据存储时指定的 Lambda ARN，请使用 API 操作。`DescribeFHIRDatastore`

**要在启用了 SMART on FHIR 的数据存储上成功发出 FHIR REST 请求，您的 Lambda 函数必须执行以下操作：**
+ 在不到 1 秒的时间内向 HealthLake 数据存储端点返回响应。
+ 对客户端应用程序发送的 REST API 请求的授权标头中提供的访问令牌进行解码。
+ 分配一个具有足够权限来执行 FHIR REST API 请求的 IAM 服务角色。
+ 完成 FHIR REST API 请求需要以下声明。要了解更多信息，请参阅[所需声明](reference-smart-on-fhir-authentication.md#server-response)。
  + `nbf`
  + `exp`
  + `isAuthorized`
  + `aud`
  + `scope`

使用 Lambda 时，除了您的 Lambda 函数外，您还需要创建执行角色和基于资源的策略。Lambda 函数的执行角色是一个 IAM 角色，它向函数授予访问运行时所需的 AWS 服务和资源的权限。您提供的基于资源的策略必须 HealthLake 允许代表您调用您的函数。

本主题中的各节描述了来自客户端应用程序的示例请求和解码后的响应、创建 Lamb AWS da 函数所需的步骤以及如何创建可以假设的基于资源的策略 HealthLake 。
+ [第 1 部分：创建 Lambda 函数](#smart-on-fhir-lambda-create)
+ [第 2 部分：创建 AWS Lambda 函数使用的 HealthLake 服务角色](#smart-on-fhir-lambda-service-role)
+ [第 3 部分：更新 Lambda 函数的执行角色](#smart-on-fhir-lambda-service-role-execution-role)
+ [第 4 部分：向您的 Lambda 函数添加资源策略](#smart-on-fhir-lambda-invoke-healthlake)
+ [第 5 部分：为您的 Lambda 函数配置并发性](#smart-on-fhir-lambda-function-scaling)

## 创建 AWS Lambda 函数
<a name="smart-on-fhir-lambda-create"></a>

本主题中创建的 Lambda 函数在 HealthLake 收到对启用 FHIR 的 SMART 数据存储的请求时触发。来自客户端应用程序的请求包含一个 REST API 调用和一个包含访问令牌的授权标头。

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/
Authorization: Bearer i8hweunweunweofiwweoijewiwe
```

本主题中的示例 Lambda 函数 AWS Secrets Manager 用于掩盖与授权服务器相关的证书。我们强烈建议不要直接在 Lambda 函数中提供授权服务器登录详细信息。

**Example 验证包含授权持有者令牌的 FHIR REST 请求**  
示例 Lambda 函数向您展示了如何验证在启用 FHIR 的数据存储上发送到 SMART 的 FHIR REST 请求。要查看有关如何实现此 Lambda 函数的 step-by-steps说明，请参阅。[使用创建 Lambda 函数 AWS 管理控制台](#create-lambda-console)  
如果 FHIR REST API 请求不包含有效的数据存储终端节点、访问令牌和 REST 操作，则 Lambda 函数将失败。要了解有关所需授权服务器元素的更多信息，请参阅[所需声明](reference-smart-on-fhir-authentication.md#server-response)。  

```
import base64
import boto3
import logging
import json
import os
from urllib import request, parse

logger = logging.getLogger()
logger.setLevel(logging.INFO)

## Uses Secrets manager to gain access to the access key ID and secret access key for the authorization server
client = boto3.client('secretsmanager', region_name="region-of-datastore")
response = client.get_secret_value(SecretId='name-specified-by-customer-in-secretsmanager')
secret = json.loads(response['SecretString'])
client_id = secret['client_id']
client_secret = secret['client_secret']


unencoded_auth = f'{client_id}:{client_secret}'
headers = {
  'Authorization': f'Basic {base64.b64encode(unencoded_auth.encode()).decode()}',
  'Content-Type': 'application/x-www-form-urlencoded'
}

auth_endpoint = os.environ['auth-server-base-url'] # Base URL of the Authorization server
user_role_arn = os.environ['iam-role-arn'] # The IAM role client application will use to complete the HTTP request on the datastore

def lambda_handler(event, context):
    if 'datastoreEndpoint' not in event or 'operationName' not in event or 'bearerToken' not in event:
    return {}

    datastore_endpoint = event['datastoreEndpoint']
    operation_name = event['operationName']
    bearer_token = event['bearerToken']
    logger.info('Datastore Endpoint [{}], Operation Name: [{}]'.format(datastore_endpoint, operation_name))

    ## To validate the token
    auth_response = auth_with_provider(bearer_token)
    logger.info('Auth response: [{}]'.format(auth_response))
    auth_payload = json.loads(auth_response)
    ## Required parameters needed to be sent to the datastore endpoint for the HTTP request to go through
    auth_payload["isAuthorized"] = bool(auth_payload["active"])
    auth_payload["nbf"] = auth_payload["iat"]
    return {"authPayload": auth_payload, "iamRoleARN": user_role_arn}

## access the server
def auth_with_provider(token):
    data = {'token': token, 'token_type_hint': 'access_token'}
    req = request.Request(url=auth_endpoint + '/v1/introspect', data=parse.urlencode(data).encode(), headers=headers)
    with request.urlopen(req) as resp:
    return resp.read().decode()
```

### 使用创建 Lambda 函数 AWS 管理控制台
<a name="create-lambda-console"></a>

以下过程假设您已经创建了在支持 SMART on FHIR 的数据存储上处理 FHIR REST API 请求时要 HealthLake 代入的服务角色。如果您尚未创建服务角色，则仍然可以创建 Lambda 函数。在 Lambda 函数起作用之前，您必须添加服务角色的 ARN。要了解有关创建服务角色并在 Lambda 函数中指定该角色的更多信息，请参阅 [创建用于解码 JWT 的 AWS Lambda 函数的 HealthLake 服务角色](#smart-on-fhir-lambda-service-role)

**创建 Lambda 函数 ()AWS 管理控制台**

1. 打开 Lamba 控制台的 [Functions page](https://console.aws.amazon.com/lambda/home/functions)（函数页面）。

1. 选择**创建函数**。

1. 选择**从头开始编写**。

1. 在**基本信息**下输入**函数名称**。在**运行时**下，选择基于 python 的运行时。

1. 在 **Execution Role**（执行角色）中，选择 **Create a new role with basic Lambda permissions**（创建具有基本 Lambda 权限的新角色）。

   Lambda 创建了一个[执行角色，该角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)向该函数授予将日志上传到亚马逊的权限。 CloudWatchLambda 函数在您调用函数时担任执行角色，并使用执行角色为 SDK 创建证书。 AWS 

1. 选择**代码**选项卡，然后添加示例 Lambda 函数。

   如果您尚未为 Lambda 函数创建要使用的服务角色，则需要先创建该角色，然后示例 Lambda 函数才能运行。要了解有关为 Lambda 函数创建服务角色的更多信息，请参阅。[创建用于解码 JWT 的 AWS Lambda 函数的 HealthLake 服务角色](#smart-on-fhir-lambda-service-role)

   ```
   import base64
   import boto3
   import logging
   import json
   import os
   from urllib import request, parse
   
   logger = logging.getLogger()
   logger.setLevel(logging.INFO)
   
   ## Uses Secrets manager to gain access to the access key ID and secret access key for the authorization server
   client = boto3.client('secretsmanager', region_name="region-of-datastore")
   response = client.get_secret_value(SecretId='name-specified-by-customer-in-secretsmanager')
   secret = json.loads(response['SecretString'])
   client_id = secret['client_id']
   client_secret = secret['client_secret']
   
   
   unencoded_auth = f'{client_id}:{client_secret}'
   headers = {
     'Authorization': f'Basic {base64.b64encode(unencoded_auth.encode()).decode()}',
     'Content-Type': 'application/x-www-form-urlencoded'
   }
   
   auth_endpoint = os.environ['auth-server-base-url'] # Base URL of the Authorization server
   user_role_arn = os.environ['iam-role-arn'] # The IAM role client application will use to complete the HTTP request on the datastore
   
   def lambda_handler(event, context):
       if 'datastoreEndpoint' not in event or 'operationName' not in event or 'bearerToken' not in event:
       return {}
   
       datastore_endpoint = event['datastoreEndpoint']
       operation_name = event['operationName']
       bearer_token = event['bearerToken']
       logger.info('Datastore Endpoint [{}], Operation Name: [{}]'.format(datastore_endpoint, operation_name))
   
       ## To validate the token
       auth_response = auth_with_provider(bearer_token)
       logger.info('Auth response: [{}]'.format(auth_response))
       auth_payload = json.loads(auth_response)
       ## Required parameters needed to be sent to the datastore endpoint for the HTTP request to go through
       auth_payload["isAuthorized"] = bool(auth_payload["active"])
       auth_payload["nbf"] = auth_payload["iat"]
       return {"authPayload": auth_payload, "iamRoleARN": user_role_arn}
   
   ## Access the server
   def auth_with_provider(token):
       data = {'token': token, 'token_type_hint': 'access_token'}
       req = request.Request(url=auth_endpoint + '/v1/introspect', data=parse.urlencode(data).encode(), headers=headers)
       with request.urlopen(req) as resp:
       return resp.read().decode()
   ```

### 修改 Lambda 函数的执行角色
<a name="modify-lambda-execution-role"></a>

创建 Lambda 函数后，您需要更新执行角色以包含调用 Secrets Manager 所需的权限。在 Secrets Manager 中，你创建的每个密钥都有一个 ARN。要应用最低权限，执行角色只能访问 Lambda 函数执行所需的资源。

您可以通过在 IAM 控制台中搜索或在 Lambda 控制台中选择**配置**来修改 Lambda 函数的执行角色。要了解有关管理 Lambda 函数执行角色的更多信息，请参阅。[Lambda 执行角色](#smart-on-fhir-lambda-service-role-execution-role)

**Example 授予访问权限的 Lambda 函数执行角色 `GetSecretValue`**  
将 IAM 操作`GetSecretValue`添加到执行角色可授予示例 Lambda 函数运行所需的权限。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:secret-name-DKodTA"
        }
    ]
}
```

此时，您已经创建了一个 Lambda 函数，该函数可用于验证在 FHIR 启用了 FHIR 的数据存储上发送到您的 SMART 的 FHIR REST 请求中提供的访问令牌。

## 创建用于解码 JWT 的 AWS Lambda 函数的 HealthLake 服务角色
<a name="smart-on-fhir-lambda-service-role"></a>

**角色：IAM 管理员**  
可以添加或删除 IAM 策略并创建新 IAM 身份的用户。  

**服务角色**  
 服务角色是由一项服务担任、代表您执行操作的 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)。IAM 管理员可以在 IAM 中创建、修改和删除服务角色。有关更多信息，请参阅《IAM 用户指南》**中的[创建向 AWS 服务委派权限的角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

解码 JSON 网络令牌 (JWT) 后，Lambda 还需要返回 IAM 角色 ARN 的授权。此角色必须具有执行 REST API 请求所需的权限，否则将因权限不足而失败。

使用 IAM 设置自定义策略时，最好授予所需的最低权限。要了解更多信息，请参阅 *IAM 用户*指南中的[应用最低权限权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)。

创建要在授权 Lambda 函数中指定的 HealthLake 服务角色需要两个步骤。
+ 首先，您需要创建 IAM 策略。该策略必须指定对您在授权服务器中为其提供作用域的 FHIR 资源的访问权限。
+ 其次，您需要创建服务角色。创建角色时，您可以指定信任关系并附加您在第一步中创建的策略。信任关系指定 HealthLake 为服务主体。您需要在此步骤中指定 HealthLake 数据存储 ARN 和 AWS 账户 ID。

### 创建新的 IAM 策略
<a name="lambda-service-role-part-1"></a>

您在授权服务器中定义的范围决定了经过身份验证的用户在 HealthLake 数据存储中可以访问哪些 FHIR 资源。

您创建的 IAM 策略可以根据您定义的范围进行定制。

可以在 IAM 策略声明的`Action`元素中定义以下操作。您可以为表`Action`中的每一个定义一个`Resource types`。数据存储是唯一可以在 HealthLake IAM 权限策略声明的`Resource`元素中定义的受支持的资源类型。

单个 FHIR 资源不是您可以在 IAM 权限策略中定义为元素的资源。


**操作定义为 HealthLake**  

| 操作 | 描述 | 访问级别 | 资源类型（必填） | 
| --- | --- | --- | --- | 
| CreateResource | 向创建资源授予权限 | 写入 | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 
| DeleteResource | 授予删除资源的权限 | 写入 | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 
| ReadResource | 授予读取资源的权限 | 读取 | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 
| SearchWithGet | 授予使用 GET 方法搜索资源的权限 | 读取 | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 
| SearchWithPost | 授予使用 POST 方法搜索资源的权限 | 读取 | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 
| 开始 FHIRExport JobWithPost | 授予使用 GET 开始 FHIR 导出任务的权限 | 写入 | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 
| UpdateResource | 授予更新资源的权限 | 写入  | 数据存储 ARN：arn: aws: healthlake::: datastore/fhir/ your-region 111122223333 your-datastore-id | 

要开始使用，你可以使用`AmazonHealthLakeFullAccess`。该策略将允许对数据存储中找到的所有 FHIR 资源进行读取、写入、搜索和导出。要授予对数据存储的只读权限，请使用`AmazonHealthLakeReadOnlyAccess`。

要了解有关使用、或 IAM 创建自定义策略的更多信息 AWS 管理控制台 AWS CLI SDKs，请参阅 IA [M 用户指南中的创建](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) *IAM* 策略。

### 为 HealthLake (IAM 控制台) 创建服务角色
<a name="lambda-service-role-part-2"></a>

使用此过程创建服务角色。创建服务时，还需要指定 IAM 策略。

**为 HealthLake （IAM 控制台）创建服务角色**

1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在 IAM 控制台的导航窗格中，选择**角色**。

1. 然后，选择**创建角色**。

1. 在**选择信任实体**页面上，选择**自定义信任策略**。

1. 接下来，在 “**自定义信任策略**” 下更新示例策略，如下所示。**your-account-id**替换为您的账号，然后添加要在导入或导出任务中使用的数据存储的 ARN。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "sts:AssumeRole",
               "Principal": {
                   "Service": "healthlake.amazonaws.com"
               },
               "Condition": {
                   "StringEquals": {
                       "aws:SourceAccount": "123456789012"
                   },
                   "ArnEquals": {
                       "aws:SourceArn": "arn:aws:healthlake:us-east-1:123456789012:datastore/fhir/your-datastore-id"
                   }
               }
           }
       ]
   }
   ```

------

1. 然后选择**下一步**。

1. 在**添加权限**页面上，选择您希望 HealthLake 服务采用的策略。要查找您的策略，请在**权限策略**下进行搜索。

1. 然后，选择**附加策略**。

1. 然后在 “**名称、查看和创建**” 页面的 “**角色名称**” 下输入名称。

1. （可选）然后在**描述**下，为您的角色添加简短描述。

1. 如果可能，输入有助于识别该角色的作用的角色名称或角色名称后缀。角色名称在您的 AWS 账户内必须是唯一的。它们不按大小写区分。例如，您无法同时创建名为 **PRODROLE** 和 **prodrole** 的角色。由于多个单位可能引用该角色，角色创建完毕后无法编辑角色名称。

1. 查看角色详细信息，然后选择**创建角色**。

要了解如何在示例 Lambda 函数中指定角色 ARN，请参阅。[创建 AWS Lambda 函数](#smart-on-fhir-lambda-create)

## Lambda 执行角色
<a name="smart-on-fhir-lambda-service-role-execution-role"></a>

Lambda 函数的执行角色是一个 IAM 角色，它向该函数授予访问 AWS 服务和资源的权限。此页面提供有关如何创建、查看和管理 Lambda 函数执行角色的信息。

默认情况下，当您使用创建新的 Lambda 函数时，Lambda 会创建具有最低权限的执行角色。 AWS 管理控制台要管理在执行角色中授予的权限，请参阅 *Lambda 开发人员*[指南中的在 IAM 控制台中创建执行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html#permissions-executionrole-console)。

本主题中提供的示例 Lambda 函数使用 Secrets Manager 来掩盖授权服务器的证书。

与您创建的任何 IAM 角色一样，遵循最低权限最佳实践非常重要。在开发阶段，您有时可能会授予超出所需权限的权限。在生产环境中发布函数之前，最佳实践是调整策略，使其仅包含所需权限。有关更多信息，请参阅 *IAM 用户*[指南中的应用最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)。

## HealthLake 允许触发你的 Lambda 函数
<a name="smart-on-fhir-lambda-invoke-healthlake"></a>

因此， HealthLake 可以代表您调用 Lambda 函数，您必须执行以下操作：
+ 您需要将设置为`IdpLambdaArn`等于您要在请求中调用的 Lambda 函数的 ARN。 HealthLake `CreateFHIRDatastore`
+ 您需要一个基于资源的策略， HealthLake 允许您代表您调用 Lambda 函数。

在启用 SMART on FHIR 的数据存储上 HealthLake 收到 FHIR REST API 请求时，它需要权限才能代表您调用创建数据存储时指定的 Lambda 函数。要授予 HealthLake 访问权限，您将使用基于资源的策略。*要详细了解如何为 Lambda 函数创建基于资源的策略，[请参阅开发者指南中的允许 AWS 服务调用 Lambda](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke) 函数。AWS Lambda *

## 为您的 Lambda 函数配置并发性
<a name="smart-on-fhir-lambda-function-scaling"></a>

**重要**  
HealthLake 要求您的 Lambda 函数的最大运行时间必须小于一秒（1000 毫秒）。  
如果您的 Lambda 函数超过了运行时间限制，则会出现异常。TimeOut

为避免出现此异常，我们建议配置预配置的并发性。通过在调用增加之前分配预置并发，您可以确保所有请求都由延迟较低的初始化实例来提供。*要了解有关配置预配置并发的更多信息，请参阅 Lambda 开发人员指南[中的配置预配置](https://docs.aws.amazon.com/ambda/latest/dg/provisioned-concurrency.html)并发*

要查看您的 Lambda 函数当前的平均运行时间，请使用 Lambda 控制台上您的 Lambda 函数的 “**监控**” 页面。默认情况下，Lambda 控制台提供**持续时间**图表，显示您的函数代码处理事件所花费的平均时间、最小时间和最大时间。*要了解有关监控 Lambda 函数的更多信息，请参阅 Lambda 开发[人员指南中的 Lambda 控制台中的监控函数](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions-access-metrics.html#monitoring-console-graph-types)。*

*如果您已经为 Lambda 函数配置了并发并想要对其进行监控，请参阅 Lambda 开发者指南中的[监控并发](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-concurrency.html)性。*

# 在启用 SMART on FHIR 的数据存储中使用细粒度授权 HealthLake
<a name="reference-smart-on-fhir-fine-grained-authorization"></a>

仅凭@@ [作用域](reference-smart-on-fhir-oauth-scopes.md#smart-on-fhir-scopes-rest)并不能为你提供必要的具体信息，说明请求者有权在数据存储中访问哪些数据。在授予对启用 FHIR 的 SMART 数据存储的访问权限时，使用细粒度授权可以提高特异性。 HealthLake 要使用细粒度授权，请在`FineGrainedAuthorizationEnabled`请求的`IdentityProviderConfiguration`参数`True`中设置等于。`CreateFHIRDatastore`

如果您启用了细粒度授权，则您的授权服务器会返回一个`fhirUser`范围`id_token`以及访问令牌。这允许客户端应用程序检索有关用户的信息。客户端应用程序应将`fhirUser`声明视为代表当前用户的 FHIR 资源的 URI。这可以是 `Patient`、`Practitioner` 或 `RelatedPerson`。授权服务器的响应还包括一个`user/`范围，该范围定义了用户可以访问哪些数据。这使用为与 FHIR 资源特定作用域相关的作用域定义的语法：

```
user/(fhir-resource | '*').('read' | 'write' | '*')
```

以下是如何使用细粒度授权来进一步指定与数据访问相关的 FHIR 资源类型的示例。
+ 何时`fhirUser`是`Practitioner`，细粒度的授权决定了用户可以访问的患者集合。只有患者以`fhirUser`全科医生的`fhirUser`身份提及的患者才允许进入。

  ```
  Patient.generalPractitioner : [{Reference(Practitioner)}]
  ```
+ 何时`fhirUser`为`Patient`或，请求中提`RelatedPerson`及的患者与请求中提及的患者不同`fhirUser`，细粒度的授权决定了所请求患`fhirUser`者的访问权限。如果请求的`Patient`资源中指定了关系，则允许访问。

  ```
  Patient.link.other : {Reference(Patient|RelatedPerson)}
  ```

# 正在获取 SMART on FHIR 发现文档
<a name="reference-smart-on-fhir-discovery-document"></a>

SMART 定义了一个发现文档，允许客户端了解授权端点 URLs 和 HealthLake 数据存储支持的功能。此信息可帮助客户端将授权请求定向到正确的端点，并构造 HealthLake数据存储支持的授权请求。

要使客户端应用程序成功发出 FHIR REST 请求 HealthLake，它必须收集 HealthLake 数据存储所定义的授权要求。此请求*不需要*持有者令牌（授权）即可成功。

**请求 HealthLake 数据存储的发现文档**  


1. 收集 HealthLake `region`和`datastoreId`价值。有关更多信息，请参阅 [获取数据存储属性](managing-data-stores-describe.md)。

1. 使用收集到的 HealthLake`region`和值为请求构造一个 URL `datastoreId`。附加`/.well-known/smart-configuration`到 URL 的端点。要查看以下示例中的整个 URL 路径，请滚动到 “**复制**” 按钮。

   ```
   https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/.well-known/smart-configuration
   ```

1. 使用[AWS 签名版本 4 `GET` 签名](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html)协议发送请求。要查看整个示例，请滚动到 “复**制**” 按钮。

------
#### [ curl ]

   ```
   curl --request GET \
     'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/.well-known/smart-configuration \
     --aws-sigv4 'aws:amz:region:healthlake' \
     --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
     --header "x-amz-security-token:$AWS_SESSION_TOKEN" \
     --header 'Accept: application/json'
   ```

------

    HealthLake 数据存储的 Discovery Document 以 JSON blob 的形式返回`token_endpoint`，您可以在其中找到`authorization_endpoint`和，以及数据存储的规格和已定义的功能。

   ```
   {
       "authorization_endpoint": "https://oidc.example.com/authorize",
       "token_endpoint": "https://oidc.example.com/oauth/token",
       "capabilities": [
           "launch-ehr",
           "client-public"
       ]
   }
   ```

   `authorization_endpoint`和都是启动客户端应用程序所必需的。`token_endpoint`
   + **授权端点**-授权客户端应用程序或用户所需的 URL。
   + **令牌端**点-客户端应用程序用来与之通信的授权服务器的端点。

# 在支持 Smart 的数据存储上发出 FHIR REST HealthLake API 请求
<a name="reference-smart-on-fhir-request-example"></a>

你可以在支持 FHIR 的数据存储上的 SMART 上发出 FH HealthLake IR REST API 请求。以下示例显示了来自客户端应用程序的请求，授权标头中包含 JWT，以及 Lambda 应如何解码响应。在客户端应用程序请求获得授权和身份验证后，它必须收到来自授权服务器的持有者令牌。在支持 FHIR 的 SMART 数据存储上发送 FH HealthLake IR REST API 请求时，请在授权标头中使用不记名令牌。

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Patient/[ID]
Authorization: Bearer auth-server-provided-bearer-token
```

由于在授权标头中找到了不记名令牌且未检测到 AWS IAM 身份，因此会 HealthLake 调用在创建启用 SMART on FHIR 的数据存储时指定的 Lambda 函数。 HealthLake 当您的 Lambda 函数成功解码令牌后，将向发送以下示例响应。 HealthLake

```
{
  "authPayload": {
    "iss": "https://authorization-server-endpoint/oauth2/token", # The issuer identifier of the authorization server
    "aud": "https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/", # Required, data store endpoint
    "iat": 1677115637,  # Identifies the time at which the token was issued
    "nbf": 1677115637,  # Required, the earliest time the JWT would be valid
    "exp": 1997877061,  # Required, the time at which the JWT is no longer valid
    "isAuthorized": "true",  # Required, boolean indicating the request has been authorized
    "uid": "100101",  # Unique identifier returned by the auth server
    "scope": "system/*.*" # Required, the scope of the request
  },
  "iamRoleARN": "iam-role-arn" #Required, IAM role to complete the request
}
```