

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 的 FHIR 上的 SMART 支援 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 應用程式啟動](https://www.hl7.org/fhir/smart-app-launch/)。  
HealthLake 資料存放區支援下列 FHIR 請求上的 SMART 身分驗證和授權架構：  
**OpenID (AuthN)**：驗證人員或用戶端應用程式是他們聲稱是誰 （或什麼）。
**OAuth 2.0 (AuthZ)**：用於授權 HealthLake 資料存放區中的哪些 FHIR 資源，已驗證的請求可以讀取或寫入。這是由授權伺服器中設定的範圍所定義。

您可以使用 AWS CLI AWS SDKs 在啟用 FHIR 的資料存放區上建立 SMART。如需詳細資訊，請參閱[建立 HealthLake 資料存放區](managing-data-stores-create.md)。

**Topics**
+ [FHIR 上的 SMART 入門](reference-smart-on-fhir-getting-started.md)
+ [FHIR 上 SMART 的 HealthLake 身分驗證要求](reference-smart-on-fhir-authentication.md)
+ [HealthLake 支援的 FHIR OAuth 2.0 範圍上的 SMART](reference-smart-on-fhir-oauth-scopes.md)
+ [使用 驗證字符 AWS Lambda](reference-smart-on-fhir-token-validation.md)
+ [在啟用 FHIR 的 HealthLake 資料存放區上搭配 SMART 使用精細授權](reference-smart-on-fhir-fine-grained-authorization.md)
+ [在 FHIR 探索文件上擷取 SMART](reference-smart-on-fhir-discovery-document.md)
+ [在已啟用 SMART 功能的 HealthLake 資料存放區上提出 FHIR REST API 請求](reference-smart-on-fhir-request-example.md)

# FHIR 上的 SMART 入門
<a name="reference-smart-on-fhir-getting-started"></a>

下列主題說明如何開始使用 AWS HealthLake 的 FHIR 授權上的 SMART。其中包括您必須在 AWS 帳戶中佈建的資源、在啟用 FHIR 的 HealthLake 資料存放區上建立 SMART，以及 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>

下列步驟定義 HealthLake 如何處理 FHIR 請求上的 SMART，以及成功所需的資源。下列元素在工作流程中一起運作，以在 FHIR 上建立 SMART 請求：
+ **最終使用者**：通常，病患或臨床醫生在 FHIR 上使用第三方 SMART 來存取 HealthLake 資料存放區中的資料。
+ **FHIR 上的 SMART 應用程式 （稱為用戶端應用程式）**：想要存取 HealthLake 資料存放區中找到之資料的應用程式。
+ **授權伺服器**：符合 OpenID Connect 標準的伺服器，能夠驗證使用者並發出存取權杖。
+ **HealthLake 資料存放**區：啟用 FHIR 的 SMART HealthLake存放區，使用 Lambda 函數回應提供承載字符的 FHIR REST 請求。

若要讓這些元素一起運作，您必須建立下列資源。

**注意**  
我們建議您在設定授權伺服器、定義必要的[範圍](reference-smart-on-fhir-oauth-scopes.md)，並建立 AWS Lambda 函數來處理[權杖](reference-smart-on-fhir-token-validation.md)自我檢查之後，在啟用 FHIR 的 HealthLake 資料存放區上建立您的 SMART。

**1. 設定授權伺服器端點**  
若要在 FHIR 架構上使用 SMART，您需要設定第三方授權伺服器，以驗證對資料存放區提出的 FHIR REST 請求。如需詳細資訊，請參閱[FHIR 上 SMART 的 HealthLake 身分驗證要求](reference-smart-on-fhir-authentication.md)。

**2. 在授權伺服器上定義範圍，以控制 HealthLake 資料存放區存取層級**  
FHIR 上的 SMART 架構使用 OAuth 範圍來判斷已驗證請求可存取的 FHIR 資源，以及存取程度。定義範圍是針對最低權限進行設計的一種方式。如需詳細資訊，請參閱[HealthLake 支援的 FHIR OAuth 2.0 範圍上的 SMART](reference-smart-on-fhir-oauth-scopes.md)。

**3. 設定能夠執行權杖自我檢查的 AWS Lambda 函數**  
用戶端應用程式在啟用 FHIR 的 SMART 資料存放區上傳送的 FHIR REST 請求包含 JSON Web Token (JWT)。如需詳細資訊，請參閱[解碼 JWT](reference-smart-on-fhir-token-validation.md)。

**4. 在啟用 FHIR 的 HealthLake 資料存放區上建立 SMART**  
若要在 FHIR HealthLake 資料存放區上建立 SMART，您需要提供 `IdentityProviderConfiguration`。如需詳細資訊，請參閱[建立 HealthLake 資料存放區](managing-data-stores-create.md)。

## FHIR 上適用於 SMART 的用戶端應用程式工作流程
<a name="smart-on-fhir-client-app-workflow"></a>

下一節說明如何在 FHIR 上的 SMART 內容中啟動用戶端應用程式，並在 HealthLake 資料存放區上提出成功的 FHIR REST 請求。

**1. 使用用戶端應用程式向 Well-Known Uniform Resource Identifier 提出`GET`請求**  
已啟用 SMART 的用戶端應用程式必須提出`GET`請求，以尋找 HealthLake 資料存放區的授權端點。這是透過 Well-Known Uniform Resource Identifier (URI) 請求來完成的。如需詳細資訊，請參閱[在 FHIR 探索文件上擷取 SMART](reference-smart-on-fhir-discovery-document.md)。

**2. 請求存取和範圍**  
用戶端應用程式使用授權伺服器的授權端點，讓使用者可以登入。此程序會驗證使用者。範圍用於定義用戶端應用程式可在 HealthLake 資料存放區中存取的 FHIR 資源。如需詳細資訊，請參閱[HealthLake 支援的 FHIR OAuth 2.0 範圍上的 SMART](reference-smart-on-fhir-oauth-scopes.md)。

**3. 存取權杖**  
現在使用者已通過身分驗證，用戶端應用程式會從授權伺服器收到 JWT 存取字符。當用戶端應用程式傳送 FHIR REST 請求給 HealthLake 時，會提供此字符。如需詳細資訊，請參閱[字符驗證](reference-smart-on-fhir-token-validation.md)。

**4. 在啟用 FHIR 的 HealthLake 資料存放區上對 SMART 提出 FHIR REST API 請求**  
用戶端應用程式現在可以使用授權伺服器提供的存取權杖，將 FHIR REST API 請求傳送至 HealthLake 資料存放區端點。如需詳細資訊，請參閱[在已啟用 SMART 功能的 HealthLake 資料存放區上提出 FHIR REST API 請求](reference-smart-on-fhir-request-example.md)。

**5. 驗證 JWT 存取權杖**  
若要驗證 FHIR REST 請求中傳送的存取權杖，請使用 Lambda 函數。如需詳細資訊，請參閱[使用 驗證字符 AWS Lambda](reference-smart-on-fhir-token-validation.md)。

# FHIR 上 SMART 的 HealthLake 身分驗證要求
<a name="reference-smart-on-fhir-authentication"></a>

若要存取啟用 FHIR 之 HealthLake 資料存放區上的 SMART 中的 FHIR 資源，用戶端應用程式必須由 OAuth 2.0 相容授權伺服器授權，並在 FHIR REST API 請求中呈現 OAuth Bearer 權杖。若要尋找授權伺服器的端點，請透過`Well-Known`統一資源識別符在 FHIR 探索文件上使用 HealthLake SMART。若要進一步了解此程序，請參閱[在 FHIR 探索文件上擷取 SMART](reference-smart-on-fhir-discovery-document.md)。

在 FHIR HealthLake 資料存放區上建立 SMART 時，您必須在`CreateFHIRDatastore`請求的 `metadata`元素中定義授權伺服器的端點和字符端點。若要進一步了解如何定義 `metadata`元素，請參閱 [建立 HealthLake 資料存放區](managing-data-stores-create.md)。

使用授權伺服器端點，用戶端應用程式將使用授權服務驗證使用者。一旦授權和驗證，授權服務會產生 JSON Web Token (JWT)，並傳遞給用戶端應用程式。此字符包含允許用戶端應用程式使用的 FHIR 資源範圍，進而限制使用者可存取的資料。或者，如果提供了啟動範圍，則回應將包含這些詳細資訊。若要進一步了解 HealthLake 支援的 FHIR 範圍上的 SMART，請參閱 [HealthLake 支援的 FHIR OAuth 2.0 範圍上的 SMART](reference-smart-on-fhir-oauth-scopes.md)。

使用授權伺服器授予的 JWT，用戶端應用程式會對啟用 FHIR 的 HealthLake 資料存放區上的 SMART 進行 FHIR REST API 呼叫。若要驗證和解碼 JWT，您需要建立 Lambda 函數。HealthLake 會在收到 FHIR REST API 請求時代表您叫用此 Lambda 函數。若要查看入門 Lambda 函數範例，請參閱 [使用 驗證字符 AWS Lambda](reference-smart-on-fhir-token-validation.md)。

## 在啟用 FHIR 的 HealthLake 資料存放區上建立 SMART 所需的授權伺服器元素
<a name="datastore-auth-server"></a>

在`CreateFHIRDatastore`請求中，您需要提供授權端點和字符端點，做為 `IdentityProviderConfiguration` 物件中 `metadata`元素的一部分。授權端點和字符端點都是必要的。若要查看如何在`CreateFHIRDatastore`請求中指定範例，請參閱 [建立 HealthLake 資料存放區](managing-data-stores-create.md)。

## 在啟用 FHIR 的 HealthLake 資料存放區上完成 SMART 上的 FHIR REST API 請求所需的宣告
<a name="server-response"></a>

您的 AWS Lambda 函數必須包含下列宣告，才能在啟用 FHIR 的 HealthLake 資料存放區上成為 SMART 上的有效 FHIR REST API 請求。
+ `nbf`：[（非之前） 宣告](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) — "nbf" （非之前） 宣告會識別不得接受 JWT 處理的時間。處理 "nbf" 宣告時，目前日期/時間必須晚於或等於 "nbf" 宣告中列出的不早於日期/時間。我們提供的 Lambda 函數範例`iat`會從伺服器回應轉換為 `nbf`。
+ `exp`：[（過期時間） 宣告](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) —「過期」（過期時間） 宣告會識別 JWT 當天或之後不得接受處理的過期時間。
+ `isAuthorized`：布林值設定為 `True`。指出請求已在授權伺服器上獲得授權。
+ `aud`：[（對象） 宣告](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) — "aud" （對象） 宣告可識別 JWT 的收件人。這必須是啟用 FHIR 的 HealthLake 資料存放區端點上的 SMART。
+ `scope`：這必須至少是一個 FHIR 資源相關範圍。此範圍在您的授權伺服器上定義。若要進一步了解 HealthLake 接受的 FHIR 資源相關範圍，請參閱 [HealthLake 的 FHIR 資源範圍上的 SMART](reference-smart-on-fhir-oauth-scopes.md#smart-on-fhir-scopes-rest)。

# HealthLake 支援的 FHIR OAuth 2.0 範圍上的 SMART
<a name="reference-smart-on-fhir-oauth-scopes"></a>

HealthLake 使用 OAuth 2.0 做為授權通訊協定。在授權伺服器上使用此通訊協定可讓您為用戶端應用程式可存取的 FHIR 資源定義 HealthLake 資料存放區許可 （建立、讀取、更新、刪除和搜尋）。

FHIR 上的 SMART 架構定義一組可以從授權伺服器請求的範圍。例如，僅設計為允許患者檢視其實驗室結果或檢視其聯絡詳細資訊的用戶端應用程式，應僅*獲授權*請求`read`範圍。

**注意**  
HealthLake 支援 FHIR V1 和 V2 上的 SMART，如下所述。建立資料存放區時，SMART on FHIR [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)設定為下列三個值之一：  
`SMART_ON_FHIR_V1` – 僅支援 FHIR V1 上的 SMART，其中包含 `read`（讀取/搜尋） 和 `write`(create/update/delete許可。
`SMART_ON_FHIR` – 支援 FHIR V1 和 V2 上的 SMART，其中包括 `create`、`read`、`delete`、 `update`和 `search`許可。
`AWS_AUTH` – 預設的 AWS HealthLake 授權策略；與 FHIR 上的 SMART 無關。

## 獨立啟動範圍
<a name="smart-on-fhir-scopes-launch"></a>

HealthLake 支援獨立啟動模式範圍 `launch/patient`。

在獨立啟動模式中，用戶端應用程式會請求存取病患的臨床資料，因為用戶端應用程式不知道使用者和病患。因此，用戶端應用程式的授權請求會明確請求傳回病患範圍。身分驗證成功後，授權伺服器會發出存取字符，其中包含請求的啟動病患範圍。所需的患者內容會在授權伺服器的回應中與存取字符一起提供。


**支援的啟動模式範圍**  

| Scope (範圍) | Description | 
| --- | --- | 
| `launch/patient` | OAuth 2.0 授權請求中的參數，請求在授權回應中傳回該病患資料。 | 

## HealthLake 的 FHIR 資源範圍上的 SMART
<a name="smart-on-fhir-scopes-rest"></a>

HealthLake 在 FHIR 資源範圍上定義三個層級的 SMART。
+ `patient` 範圍會授予單一病患特定資料的存取權。
+ `user` 範圍會授予使用者可存取的特定資料的存取權。
+ `system` 範圍會授予 HealthLake 資料存放區中所有 FHIR 資源的存取權。

下列各節列出使用 FHIR V1 上的 SMART 或 FHIR V2 上的 SMART 建構 FHIR 資源範圍的語法。

**注意**  
建立資料存放區時，會設定 FHIR 上的 SMART 授權策略。如需詳細資訊，請參閱 *AWS HealthLake API 參考*[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)中的 。

### HealthLake 支援的 FHIR V1 範圍上的 SMART
<a name="reference-smart-on-fhir-v1"></a>

在 FHIR V1 上使用 SMART 時，用於建構 HealthLake 的 FHIR 資源範圍的一般語法如下。若要在下列範例中檢視整個 URL 路徑，請捲動至**複製**按鈕。

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


**FHIR v1 支援的授權範圍上的 SMART**  

| 範圍語法 | 範例範圍 | 結果 | 
| --- | --- | --- | 
| `patient/(fhir-resource \| '*').('read' \| 'write' \| '*')` | patient/AllergyIntolerance.\$1 | 病患用戶端應用程式具有所有記錄的區分的執行個體層級讀取/寫入存取權。 | 
| `user/(fhir-resource \| '*').('read' \| 'write' \| '*')` | user/Observation.read | 使用者用戶端應用程式具有所有記錄觀察的執行個體層級讀取/寫入存取權。 | 
| system/('read' \$1 'write' \$1 \$1) | system/\$1.\$1 | 系統用戶端應用程式具有所有 FHIR 資源資料的讀取/寫入存取權。 | 

### HealthLake 支援的 FHIR V2 範圍上的 SMART
<a name="reference-smart-on-fhir-v2"></a>

在 FHIR V2 上使用 SMART 時，用於建構 HealthLake 的 FHIR 資源範圍的一般語法如下。若要在下列範例中檢視整個 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 US Core 實作指南*中[支援的精細範圍](https://hl7.org/fhir/us/core/scopes.html#the-following-granular-scopes-shall-be-supported)。


**FHIR V2 支援的授權範圍上的 SMART**  

| 範圍語法 | 範例 V1 範圍 | 結果 | 
| --- | --- | --- | 
| `patient/Observation.rs` | user/Observation.read | 讀取和搜尋目前病患Observation資源的許可。 | 
| `system/*.cruds` | system/\$1.\$1 | 系統用戶端應用程式具有所有 FHIR 資源資料的完整create/read/update/刪除/搜尋存取權。 | 

# 使用 驗證字符 AWS Lambda
<a name="reference-smart-on-fhir-token-validation"></a>

當您在啟用 FHIR 的資料存放區上建立 HealthLake SMART 時，您必須在`CreateFHIRDatastore`請求中提供 AWS Lambda 函數的 ARN。Lambda 函數的 ARN 是使用 `IdpLambdaArn` 參數在 `IdentityProviderConfiguration` 物件中指定。

您必須先建立 Lambda 函數，才能建立啟用 FHIR 的 SMART 資料存放區。建立資料存放區後，就無法變更 Lambda ARN。若要查看您在建立資料存放區時指定的 Lambda ARN，請使用 `DescribeFHIRDatastore` API 動作。

**若要讓 FHIR REST 請求在啟用 FHIR 的資料存放區上在 SMART 上成功，您的 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 代表您叫用您的函數。

本主題中的各節說明來自用戶端應用程式和解碼回應的範例請求、建立 AWS Lambda 函數所需的步驟，以及如何建立 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>

下列程序假設您已在啟用 FHIR 的 SMART 資料存放區上處理 FHIR REST API 請求時，建立希望 HealthLake 擔任的服務角色。如果您尚未建立服務角色，您仍然可以建立 Lambda 函數。您必須先新增服務角色的 ARN，Lambda 函數才能運作。若要進一步了解如何建立服務角色並在 Lambda 函數中指定該角色，請參閱 [建立 HealthLake 服務角色以用於用來解碼 JWT 的 AWS Lambda 函數](#smart-on-fhir-lambda-service-role)

**建立 Lambda 函數 (AWS 管理主控台)**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home/functions)。

1. 選擇**建立函數**。

1. 選取**從頭開始撰寫**。

1. 在**基本資訊**下，輸入**函數名稱**。在**執行時間**下，選擇以 Python 為基礎的執行時間。

1. **執行角色** 請選擇 **建立具備基本 Lambda 許可的新角色** 。

   Lambda 會建立函數和[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)，此角色會授予函數將日誌上傳至 Amazon CloudWatch 的許可。Lambda 函數會在您叫用函數時擔任執行角色，並使用執行角色來建立 AWS SDK 的登入資料。

1. 選擇**程式碼**索引標籤，然後新增範例 Lambda 函數。

   如果您尚未為 Lambda 函數建立要使用的服務角色，則必須先建立該角色，範例 Lambda 函數才能運作。若要進一步了解如何為 Lambda 函數建立服務角色，請參閱 [建立 HealthLake 服務角色以用於用來解碼 JWT 的 AWS Lambda 函數](#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 函數執行角色，請參閱 [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 REST 請求的一部分提供的存取字符，該請求會傳送到啟用 FHIR 的 SMART 資料存放區。

## 建立 HealthLake 服務角色以用於用來解碼 JWT 的 AWS Lambda 函數
<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 Web Token (JWT) 解碼後，Lambda 需要授權，才能傳回 IAM 角色 ARN。此角色必須具有執行 REST API 請求的必要許可，否則會因為許可不足而失敗。

使用 IAM 設定自訂政策時，最好授予所需的最低許可。若要進一步了解，請參閱《*IAM 使用者指南*》中的[套用最低權限許可](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)。

建立 HealthLake 服務角色以在授權 Lambda 函數中指定 需要兩個步驟。
+ 首先，您需要建立 IAM 政策。此政策必須指定您在授權伺服器中提供 範圍的 FHIR 資源存取權。
+ 其次，您需要建立 服務角色。當您建立角色時，您可以指定信任關係，並連接您在步驟 1 中建立的政策。信任關係會將 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：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 
| DeleteResource | 准許刪除資源 | 寫入 | 資料存放區 ARN：arn：aws：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 
| ReadResource | 准許讀取資源 | 讀取 | 資料存放區 ARN：arn：aws：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 
| SearchWithGet | 准許使用 GET 方法搜尋資源 | 讀取 | 資料存放區 ARN：arn：aws：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 
| SearchWithPost | 准許使用 POST 方法搜尋資源 | 讀取 | 資料存放區 ARN：arn：aws：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 
| StartFHIRExportJobWithPost | 准許使用 GET 開始 FHIR 匯出任務 | 寫入 | 資料存放區 ARN：arn：aws：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 
| UpdateResource | 准許更新資源 | 寫入  | 資料存放區 ARN：arn：aws：healthlakeyour-region：111122223333：datastore/fhir/your-datastore-id | 

若要開始使用，您可以使用 `AmazonHealthLakeFullAccess`。此政策會授予資料存放區中所有 FHIR 資源的讀取、寫入、搜尋和匯出。若要授予資料存放區的唯讀許可，請使用 `AmazonHealthLakeReadOnlyAccess`。

若要進一步了解如何使用 AWS 管理主控台 AWS CLI或 IAM SDKs建立自訂政策，請參閱《[IAM 使用者指南》中的建立](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 管理主控台 並開啟位於 https：//[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 的 IAM 主控台。

1. 在 IAM 主控台的導覽窗格中，選擇**角色**。

1. 然後，選擇 **Create role** (建立角色)。

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 函數的執行角色是授予函數存取 AWS 服務和資源的許可的 IAM 角色。本頁提供有關如何建立、檢視和管理 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`等於您希望 HealthLake 在`CreateFHIRDatastore`請求中調用之 Lambda 函數的 ARN。
+ 您需要以資源為基礎的政策，允許 HealthLake 代表您叫用 Lambda 函數。

當 HealthLake 在啟用 FHIR 的 SMART 資料存放區上收到 FHIR REST API 請求時，它需要許可來代表您調用資料存放區建立時指定的 Lambda 函數。若要授予 HealthLake 存取權，您將使用以資源為基礎的政策。若要進一步了解如何為 Lambda 函數建立資源型政策，請參閱《 *AWS Lambda 開發人員指南*》中的[允許 AWS 服務呼叫 Lambda 函數](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke)。

## 為您的 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)。

# 在啟用 FHIR 的 HealthLake 資料存放區上搭配 SMART 使用精細授權
<a name="reference-smart-on-fhir-fine-grained-authorization"></a>

僅[範圍](reference-smart-on-fhir-oauth-scopes.md#smart-on-fhir-scopes-rest)不會為您提供請求者有權在資料存放區中存取哪些資料的必要具體性。在啟用 FHIR 的 HealthLake 資料存放區上授予 SMART 存取權時，使用精細授權可實現更高層級的特異性。若要使用精細授權，請在`CreateFHIRDatastore`請求的 `IdentityProviderConfiguration` 參數`True`中將 設定為`FineGrainedAuthorizationEnabled`等於 。

如果您啟用精細授權，您的授權伺服器會傳回 中的`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)}
  ```

# 在 FHIR 探索文件上擷取 SMART
<a name="reference-smart-on-fhir-discovery-document"></a>

SMART 定義探索文件，可讓用戶端了解 HealthLake 資料存放區支援的授權端點 URLs和功能。此資訊可協助用戶端將授權請求導向正確的端點，並建構 HealthLake 資料存放區支援的授權請求。

若要讓用戶端應用程式成功向 HealthLake 提出 FHIR REST 請求，必須收集 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. 使用 `GET` 搭配 [AWS Signature 第 4 版](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 資料存放區的探索文件會傳回為 JSON blob，您可以在其中找到 `authorization_endpoint`和 `token_endpoint`，以及資料存放區的規格和定義功能。

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

   `token_endpoint` 需要 `authorization_endpoint`和 才能啟動用戶端應用程式。
   + **授權端點** — 授權用戶端應用程式或使用者所需的 URL。
   + **權杖端點** — 用戶端應用程式用來與之通訊的授權伺服器端點。

# 在已啟用 SMART 功能的 HealthLake 資料存放區上提出 FHIR REST API 請求
<a name="reference-smart-on-fhir-request-example"></a>

您可以在啟用 FHIR 的 HealthLake 資料存放區上的 SMART 上提出 FHIR REST API 請求。下列範例顯示來自用戶端應用程式的請求，其中包含授權標頭中的 JWT，以及 Lambda 應如何解碼回應。用戶端應用程式請求經過授權和驗證後，必須從授權伺服器收到承載字符。在啟用 FHIR 的 HealthLake 資料存放區上傳送 SMART 上的 FHIR REST API 請求時，請使用授權標頭中的承載字符。

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

因為在授權標頭中找到承載字符，且未偵測到 IAM AWS 身分，所以 HealthLake 會叫用在建立啟用 SMART on FHIR 的 HealthLake 資料存放區時指定的 Lambda 函數。當您的 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
}
```