使用 Amazon API Gateway 整合您的身分供應商 - AWS Transfer Family

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

使用 Amazon API Gateway 整合您的身分供應商

本主題說明如何使用 AWS Lambda 函數來支援 API Gateway 方法。如果您需要 RESTful API 來整合身分識別提供者,或者想要使用其功能來進行地理封鎖或速率限制 AWS WAF 要求,請使用此選項。

使用 API Gateway 整合身分提供者的限制

  • 此設定不支援自訂網域。

  • 此設定不支援私有 API Gateway URL。

如果您需要其中一種,您可以在沒有 API Gateway 的情況下使用 Lambda 做為身分識別提供者。如需詳細資訊,請參閱 用 AWS Lambda 於整合您的身分識別提供者

使用 API Gateway 方法進行驗證

您可以建立 API Gateway 方法,用作「Transfer Family」的身分識別提供者。這種方法為您提供了一種高度安全的方式來創建和提供 API。使用 API Gateway,您可以建立 HTTPS 端點,以便以更高的安全性傳輸所有內送 API 呼叫。如需 API Gateway 服務的詳細資訊,請參閱 API Gateway 開發人員指南

API Gateway 提供了一種名為的授權方法AWS_IAM,該方法可為您提供與內部 AWS 使用的 AWS Identity and Access Management (IAM)相同的身份驗證。如果您使用啟用驗證AWS_IAM,則只有具有呼叫 API 明確權限的呼叫者才能連線到該 API 的 API Gateway 方法。

若要使用您的 API Gateway 方法做為 Transfer Family 的自訂身分提供者,請為您的 API Gateway 方法啟用 IAM。在此過程中,您提供具有許可的 IAM 角色,以便 Transfer Family 使用您的閘道。

注意

若要提高安全性,您可以設定 Web 應用程式防火牆。 AWS WAF 這是一種網頁應用程式防火牆,可讓您監控轉寄至 Amazon API Gateway 的 HTTP 和 HTTPS 請求。如需詳細資訊,請參閱 新增 Web 應用程式防火牆

使用您的 API Gateway 方法透過 Transfer Family 進行自訂驗證
  1. 建立 AWS CloudFormation 堆疊。若要執行此作業:

    注意

    堆疊範本已更新為使用 Base64 編碼密碼:如需詳細資訊,請參閱。AWS CloudFormation 模板的改進

    1. 開啟主 AWS CloudFormation 控台,網址為 https://console.aws.amazon.com/cloudformation

    2. 請遵循《使用指南》中的 「選取 AWS CloudFormation 堆疊範本」中,從現有範本部署堆疊AWS CloudFormation 指示。

    3. 使用下列其中一個基本範本建立 AWS Lambda支援的 API Gateway 方法,以在 Transfer Family 中做為自訂身分識別提供者使用。

      • 基本堆疊範本

        根據預設,您的 API Gateway 方法會用作自訂身分識別提供者,以使用硬式編碼的 SSH (安全殼層) 金鑰或密碼來驗證單一伺服器中的單一使用者。部署之後,您可以修改 Lambda 函數程式碼來執行不同的動作。

      • AWS Secrets Manager 堆疊範本

        根據預設,您的 API Gateway 方法會針對該格式的 Secrets Manager 中的項目進行驗證。aws/transfer/server-id/username此外,密碼必須保留傳回至「Transfer Family」之所有使用者性質的鍵值對。部署之後,您可以修改 Lambda 函數程式碼來執行不同的動作。如需詳細資訊,請參閱部落格文章啟用密碼驗證以便 AWS Transfer Family 使用 AWS Secrets Manager

      • 奧克塔堆疊範本

        您的 API Gateway 方法與 Okta 整合,做為 Transfer Family 中的自訂身分提供者。如需詳細資訊,請參閱使用 Okta 做為身分識別提供者的部落格文章。 AWS Transfer Family

    部署其中一個堆疊是將自訂身分識別提供者整合至「Transfer Family」工作流程的最簡單方法。每個堆疊都會使用 Lambda 函數,根據 API Gateway 來支援您的 API 方法。然後,您可以在「Transfer Family」中使用 API 方法做為自訂身分提供者。根據預設,Lambda 函數會驗證使用的密碼呼叫myuser的單一使用者。MySuperSecretPassword部署之後,您可以編輯這些認證或更新 Lambda 函數程式碼以執行不同動作。

    重要

    建議您編輯預設的使用者和密碼認證。

    部署堆疊之後,您可以在 CloudFormation 主控台的 [輸出] 索引標籤上檢視堆疊的詳細資料。這些詳細資料包括堆疊的 Amazon 資源名稱 (ARN)、堆疊建立的 IAM 角色的 ARN,以及新閘道的 URL。

    注意

    如果您使用自訂身分識別提供者選項為使用者啟用密碼式身份驗證,並且啟用 API Gateway 提供的請求和回應記錄,則 API Gateway 會將使用者的密碼記錄到 Amazon 日誌中。 CloudWatch 我們不建議您在生產環境中使用此日誌。如需詳細資訊,請參閱 CloudWatch API Gateway 開發人員指南中的「在 API Gateway 中設定 API 記錄」。

  2. 檢查伺服器的 API Gateway 方法設定。若要執行此作業:

    1. 在以下網址開啟 API Gateway 主控台:https://console.aws.amazon.com/apigateway/

    2. 選擇範本產生的「移轉自訂身分識別提供者」基本 AWS CloudFormation 範本 API。您可能需要選取您的區域才能查看閘道。

    3. 在 [資] 窗格中,選擇 [GET]。下列螢幕擷取畫面顯示正確的方法設定。

      API 配置詳細信息,顯示請求路徑的方法配置參數以及 URL 查詢字符串的方法配置參數。

    此時,您的 API 閘道已準備就緒,可供部署。

  3. 針對「動作」,選擇「部署 API」。針對「部署」階段,選擇 prod,然後選擇「部署」。

    成功部署 API Gateway 方法之後,請在「階段」>「階段詳細資料中檢視其效能,如下列螢幕擷取畫面所示。

    注意

    複製顯示在畫面頂端的呼叫 URL 位址。您可能需要它來進行下一步。

    反白顯示叫用 URL 的階段詳細資料。
  4. 開啟主 AWS Transfer Family 控台,網址為 https://console.aws.amazon.com/transfer/

  5. 當您建立堆疊時,應該已為您建立 Transfer Family。如果沒有,請使用以下步驟設定您的伺服器。

    1. 選擇建立伺服器以開啟 [建立伺服器] 頁面。對於 [選擇身分提供者],選擇 [自訂],然後選取 [使用 Amazon API Gateway 連線到您的身分提供者],如下列螢幕擷取畫面所示。

      已選取「自訂身分識別提供者」的身分識別提供者畫面,並選擇用於連線至身分識別提供者的 API Gateway。
    2. 提供 Amazon API Gateway URL 文字方塊中,貼上您在此程序步驟 3 中建立之 API Gateway 端點的叫用 URL 位址。

    3. 針對角色,選擇 AWS CloudFormation 範本建立的 IAM 角色。此角色允許 Transfer Family 叫用您的 API 閘道方法。

      呼叫角色包含您在步驟 1 中建立的堆疊選取的堆疊名稱。 AWS CloudFormation 它具有以下格式:CloudFormation-stack-name-TransferIdentityProviderRole-ABC123DEF456GHI

    4. 填入其餘的方塊,然後選擇 [建立伺服器]。如需建立伺服器的剩餘步驟的詳細資訊,請參閱設定 SFTP、FTPS 或 FTP 伺服器端點

實作您的 API Gateway 方法

若要為 Transfer Family 建立自訂身分識別提供者,您的 API Gateway 方法必須實作資源路徑為的單一方法/servers/serverId/users/username/configserverIdusername值來自 REST 風格的資源路徑。此外,在方法要求中新增sourceIpprotocol做為 URL 查詢字串參數,如下圖所示。

顯示GET方法詳細資訊的 API Gateway 的「資源」畫面。
注意

使用者名稱必須至少為 3 個字元,最多 100 個字元。您可以在使用者名稱中使用下列字元:a—z、A-Z、0—9、底線 (_)、連字號 (-)、句號 (.) 和 at 符號 (@)。不過,使用者名稱不能以連字號 (-)、句點 (.) 或 @符號開頭。

如果「Transfer Family」嘗試為您的使用者進行密碼驗證,則服務會提供Password:標頭欄位。如果沒有Password:標頭,Transfer Family 會嘗試使用公開金鑰驗證來驗證您的使用者。

當您使用身分識別提供者來驗證和授權使用者時,除了驗證其認證之外,您還可以根據使用者所使用的用戶端 IP 位址來允許或拒絕存取要求。您可以使用此功能來確保存放在 S3 儲存貯體或 Amazon EFS 檔案系統中的資料只能透過受支援的協定存取,只能從您指定為受信任的 IP 地址存取。若要啟用此功能,您必須sourceIp在查詢字串中加入。

如果您為伺服器啟用了多個通訊協定,並且想要透過多個通訊協定使用相同的使用者名稱提供存取權,只要您的身分識別提供者中設定了每個通訊協定特定的認證,就可以這麼做。若要啟用此功能,您必須在 RESTful 資源路徑中包含該protocol值。

您的 API Gateway 方法應始終返回 HTTP 狀態碼200。任何其他 HTTP 狀態碼表示存取 API 時發生錯誤。

Amazon S3 範例回應

範例回應本文是 Amazon S3 的下列格式的 JSON 文件。

{ "Role": "IAM role with configured S3 permissions", "PublicKeys": [ "ssh-rsa public-key1", "ssh-rsa public-key2" ], "Policy": "STS Assume role session policy", "HomeDirectory": "/bucketName/path/to/home/directory" }
注意

原則會以字串形式逸出 JSON。例如:

"Policy": "{ \"Version\": \"2012-10-17\", \"Statement\": [ {\"Condition\": {\"StringLike\": {\"s3:prefix\": [\"user/*\", \"user/\"]}}, \"Resource\": \"arn:aws:s3:::bucket\", \"Action\": \"s3:ListBucket\", \"Effect\": \"Allow\", \"Sid\": \"ListHomeDir\"}, {\"Resource\": \"arn:aws:s3:::*\", \"Action\": [\"s3:PutObject\", \"s3:GetObject\", \"s3:DeleteObjectVersion\", \"s3:DeleteObject\", \"s3:GetObjectVersion\", \"s3:GetObjectACL\", \"s3:PutObjectACL\"], \"Effect\": \"Allow\", \"Sid\": \"HomeDirObjectAccess\"}] }"

下列範例回應顯示使用者具有邏輯主目錄類型。

{ "Role": "arn:aws:iam::123456789012:role/transfer-access-role-s3", "HomeDirectoryType":"LOGICAL", "HomeDirectoryDetails":"[{\"Entry\":\"/\",\"Target\":\"/MY-HOME-BUCKET\"}]", "PublicKeys":[""] }
Amazon EFS 範例回應

範例回應本文是適用於 Amazon EFS 的下列格式的 JSON 文件。

{ "Role": "IAM role with configured EFS permissions", "PublicKeys": [ "ssh-rsa public-key1", "ssh-rsa public-key2" ], "PosixProfile": { "Uid": "POSIX user ID", "Gid": "POSIX group ID", "SecondaryGids": [Optional list of secondary Group IDs], }, "HomeDirectory": "/fs-id/path/to/home/directory" }

Role欄位顯示驗證成功。在進行密碼身份驗證時(當您提供Password:標題時),您不需要提供 SSH 公鑰。如果用戶無法通過身份驗證,例如,如果密碼不正確,則您的方法應返回沒有Role設置的響應。這種響應的一個例子是一個空的 JSON 對象。

下列範例回應顯示具有邏輯主目錄類型的使用者。

{ "Role": "arn:aws:iam::123456789012:role/transfer-access-role-efs", "HomeDirectoryType": "LOGICAL", "HomeDirectoryDetails":"[{\"Entry\":\"/\",\"Target\":\"/faa1a123\"}]", "PublicKeys":[""], "PosixProfile":{"Uid":65534,"Gid":65534} }

您可以在 Lambda 函數中以 JSON 格式包含使用者政策。如需有關在 Transfer Family 中設定使用者原則的詳細資訊,請參閱管理存取控制

默認 Lambda 數

若要實作不同的驗證策略,請編輯閘道使用的 Lambda 函數。為了協助您滿足應用程式的需求,您可以在 Node.js 中使用下列 Lambda 函數範例。如需有關 Lambda 的詳細資訊,請參閱AWS Lambda 開發人員指南使用 Node.js 建置 Lambda 函數

下列範例 Lambda 函數會取得您的使用者名稱、密碼 (如果您正在執行密碼驗證)、伺服器 ID、通訊協定和用戶端 IP 位址。您可以使用這些輸入的組合來查詢您的身份提供者,並確定是否應該接受登錄。

注意

如果您為伺服器啟用了多個通訊協定,並且想要透過多個通訊協定使用相同的使用者名稱提供存取權,只要您的身分識別提供者中設定了通訊協定特定的認證,就可以這麼做。

對於檔案傳輸通訊協定 (FTP),我們建議維護與安全殼層 (SSH) 檔案傳輸通訊協定 (SFTP) 和透過 SSL (FTPS) 的檔案傳輸通訊協定分開的憑證。我們建議您保留個別的 FTP 認證,因為 FTP 與 SFTP 和 FTPS 不同,FTP 會以純文字傳輸認證。藉由將 FTP 認證與 SFTP 或 FTPS 隔離,如果 FTP 認證是共用或公開的,您使用 SFTP 或 FTPS 的工作負載將保持安全。

此示例函數返回角色和邏輯主目錄的詳細信息,以及公鑰(如果它執行公鑰身份驗證)。

當您建立服務管理的使用者時,您可以設定其主目錄 (邏輯或實體)。同樣地,我們需要 Lambda 函數結果來傳達所需的使用者實體或邏輯目錄結構。您設定的參數取決於HomeDirectoryType欄位的值。

  • HomeDirectoryType設定為 PATHHomeDirectory 欄位必須是絕對的 Amazon S3 儲存貯體前綴或 Amazon EFS 絕對路徑,讓您的使用者可以看到。

  • HomeDirectoryType設定為 LOGICAL要設定HomeDirectory欄位。相反地,我們會設定一個HomeDirectoryDetails欄位,提供所需的「項目/目標」對應,類似於服務管理使用者HomeDirectoryDetails參數中描述的值。

中列出了範例函數範例 Lambda 函數

可搭配使用的 Lambda 函數 AWS Secrets Manager

若要用 AWS Secrets Manager 作身分識別提供者,您可以使用範例 AWS CloudFormation 範本中的 Lambda 函數。Lambda 函數會使用您的認證查詢 Secrets Manager 服務,如果成功,則會傳回指定的密碼。如需 Secrets Manager 的詳細資訊,請參閱 AWS Secrets Manager 使用者指南

若要下載使用此 Lambda 函數的 AWS CloudFormation 範例範本,請前往提供的 Amazon S3 儲存貯體 AWS Transfer Family

AWS CloudFormation 模板的改進

已對已發佈的 CloudFormation範本進行了改進 API Gateway 介面。範本現在會在 API Gateway 中使用 Base64 編碼的密碼。您現有的部署在沒有此增強功能的情況下繼續運作,但不允許使用基本 US-ASCII 字元集以外的字元的密碼。

範本中啟用此功能的變更如下:

  • GetUserConfigRequest AWS::ApiGateway::Method源必須有這個RequestTemplates代碼(斜體行是更新的行)

    RequestTemplates: application/json: | { "username": "$util.urlDecode($input.params('username'))", "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")", "protocol": "$input.params('protocol')", "serverId": "$input.params('serverId')", "sourceIp": "$input.params('sourceIp')" }
  • GetUserConfig資源必須變更才能使用標PasswordBase64題 (斜體的行是更新後的行):RequestParameters

    RequestParameters: method.request.header.PasswordBase64: false method.request.querystring.protocol: false method.request.querystring.sourceIp: false
若要檢查堆疊的範本是否為最新的範本
  1. 開啟主 AWS CloudFormation 控台,網址為 https://console.aws.amazon.com/cloudformation

  2. 從堆疊清單中選擇您的堆疊。

  3. 從詳細資料面板中,選擇「範本」標籤。

  4. 查找以下內容:

    • 搜索RequestTemplates,並確保你有這一行:

      "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
    • 搜索RequestParameters,並確保你有這一行:

      method.request.header.PasswordBase64: false

如果沒有看到更新的行,請編輯堆疊。有關如何更新 AWS CloudFormation 堆疊的詳細資訊,請參閱《使用者指南》中的AWS CloudFormation〈修改堆疊範本