驗證及授權

本節說明與 Fleet Engine 整合的驗證和授權概念。

您可以透過 Google Cloud 控制台,設定 Last Mile Fleet Solution 提供的功能。Fleet Engine SDK 需要使用由適當服務帳戶簽署的 JSON Web Token (JWT)。

總覽

針對 Fleet Engine 進行驗證及授權的客戶後端應使用標準應用程式預設憑證機制。

Fleet Engine 也會接收來自低信任環境 (例如智慧型手機和瀏覽器) 的呼叫。為保護服務帳戶密鑰僅適用於受信任的環境,客戶的後端應產生已簽署的 JSON Web Token (JWT),其中包含 Fleet Engine 專屬的額外憑證附加資訊,然後這些憑證就會發出到手機等不受信任的環境。

驗證設計原則

Fleet Engine 的驗證流程包含下列設計原則。

  • IAM 角色定義適用於主體的資源權限組合。舉例來說,Admin 角色可透過應用程式預設憑證執行所有操作,而「不受信任的驅動程式*」角色只能更新車輛位置,而只能使用 JWT 進行驗證及授權。

  • 針對不受信任的環境,JWT 憑證附加資訊進一步限制呼叫端可在呼叫端運作的實體。例如特定任務或運送車輛。

  • 在低信任環境中執行的程式碼必須先在受信任環境中執行的程式碼中,呼叫發出 JWT。

  • Fleet Engine 會對資源的 API 呼叫執行下列安全檢查:

    1. 呼叫主體具備資源動作的適當權限 (透過角色指派)。

    2. 針對非管理員角色,要求中傳遞的 JWT 憑證附加資訊提供了資源的必要權限。

驗證流程

以下序列圖表展示了這些驗證流程的詳細資料。

  1. 機群管理員會建立服務帳戶。

  2. 機群管理員會將特定的 IAM 角色指派給服務帳戶。

  3. 機群管理員使用服務帳戶和應用程式預設憑證來設定後端。

  4. 用戶端應用程式向客戶後端要求 JWT。要求者可以是駕駛應用程式、消費者應用程式或監控應用程式。

  5. 客戶後端為個別服務帳戶簽署並發出 JWT。用戶端應用程式收到 JWT。

  6. 用戶端應用程式會使用 JWT 連線至 Fleet Engine,以讀取或修改資料,視設定階段中獲派的 IAM 角色而定。

驗證序列圖表

Cloud 專案設定

如要設定 Cloud 專案,請先建立專案,再建立服務帳戶。

如要建立 Google Cloud 專案,請按照下列步驟操作:

  1. 使用 Google Cloud 控制台建立 Google Cloud 專案。
  2. 透過 API 和服務資訊主頁,啟用 Local Rides 和 Deliveries API。

服務帳戶和 IAM 角色

服務帳戶是一種特殊的帳戶,由應用程式使用,而非使用者。一般而言,服務帳戶可用來建立 JWT,這些 JWT 會根據角色授予不同的權限組合。為降低濫用的可能性,您可以建立多個服務帳戶,每個帳戶只具備最低所需的角色組合 ()。

Last Mile Fleet Solution 會使用下列角色:

角色說明
Fleet Engine Delivery 信任的駕駛使用者

roles/fleetengine.deliveryTrustedDriver
可授予建立及更新外送車輛和工作的權限,包括更新交車地點、工作狀態或結果。具備這個角色的服務帳戶所衍生的權杖,通常用於外送司機的行動裝置或後端伺服器。
不受信任的 Fleet Engine Delivery 駕駛員使用者

roles/fleetengine.deliveryUntrustedDriver
授予更新送貨車輛位置的權限。具備這個角色的服務帳戶所挖掘的權杖,通常用於外送司機的行動裝置。
Fleet Engine Delivery 一般使用者

roles/fleetengine.deliveryConsumer
可授予使用追蹤 ID 搜尋工作的權限,以及讀取但不更新工作資訊的權限。具備這個角色的服務帳戶所挖掘的權杖,通常用於傳送消費者的網路瀏覽器。
Fleet Engine Delivery 管理員

roles/fleetengine.deliveryAdmin
可授予傳遞資源的讀取及寫入權限,具備這個角色的主體不需要使用 JWT,應改用應用程式預設憑證。系統會忽略自訂 JWT 憑證附加資訊。這個角色應僅限受信任的環境 (客戶後端) 使用。
Fleet Engine Delivery 超級使用者 **(已淘汰)**

roles/fleetengine.deliverySuperUser
授予所有配送車輛和工作 API 的權限。具備這個角色的服務帳戶所壓縮的權杖,通常用於後端伺服器。
Fleet Engine Delivery 機群讀取者

roles/fleetengine.deliveryFleetReader
可授予讀取運輸車輛和工作的權限,以及使用追蹤 ID 搜尋工作的權限。具備這個角色的服務帳戶所挖掘的權杖,通常用於運送機群營運商的網路瀏覽器。

如果機構為推送司機提供由企業 IT 管理的裝置,可以充分運用 Fleet Engine「Trusted Driver User」角色提供的彈性,並選擇在行動應用程式中整合部分或所有 Fleet Engine 互動。

支援「自備裝置」政策的機構應選擇確保「Fleet Engine 不受信任駕駛使用者」角色的安全性,並且只仰賴行動應用程式將車輛位置更新傳送至 Fleet Engine。所有其他互動應來自客戶的後端伺服器。

驅動程式和消費者 SDK 是根據這些標準角色建構而成。不過,您可以建立自訂角色,將任意一組權限封裝在一起。驅動程式和消費者 SDK 會在缺少必要權限時顯示錯誤訊息。因此,我們強烈建議使用上述的標準角色組合,而不要使用自訂角色。

建立服務帳戶

您可以使用 Google Cloud 控制台中的「IAM & Admin > Service Accounts」分頁建立服務帳戶。從「角色」下拉式清單中選取「機群引擎」,並將一個角色指派給服務帳戶。最佳做法是指出與每個角色相關聯的帳戶。例如,為服務帳戶取個有意義的名稱。

為了方便起見,如果您需要為不受信任的用戶端建立 JWT,將使用者新增至「服務帳戶權杖建立者」角色,即可讓他們利用 gcloud 指令列工具壓縮憑證。

gcloud projects add-iam-policy-binding project-id \
       --member=user:my-user@example.com \
       --role=roles/iam.serviceAccountTokenCreator

其中 my-user@example.com 是用於透過 gcloud (gcloud auth list --format='value(account)') 驗證的電子郵件。

Fleet Engine 驗證程式庫

在不受信任的環境中,Fleet Engine 會使用 JWT 限制 Fleet Engine API 的存取權。GitHub 上提供 Fleet Engine 驗證程式庫,可簡化 Fleet Engine JWT 的建構及安全簽署程序。

這個程式庫的優點如下:

  • 簡化 Fleet Engine 權杖的建立程序。
  • 提供除了使用憑證檔案 (例如模擬服務帳戶) 外的權杖簽署機制。

建立用於授權的 JSON Web Token (JWT)

不使用 Fleet Engine 驗證程式庫時,您必須在程式碼集中直接製作 JWT。這需要您深入瞭解 JWT,以及 JWT 與 Fleet Engine 之間的關係。因此,我們強烈建議您善用 Fleet Engine 驗證程式庫。

在 Fleet Engine 中,JWT 提供短期驗證,確保裝置只能修改已獲得授權的車輛或工作。JWT 包含標頭和憑證附加資訊部分,標頭區段包含要使用的私密金鑰 (從服務帳戶取得) 和加密演算法等資訊。憑證附加資訊區段包含憑證的建立時間、權杖存留時間、憑證領取存取權的服務,以及用於縮小存取範圍的其他授權資訊,例如外送車輛 ID。

JWT 標頭區段包含下列欄位:

欄位說明
alg 要使用的演算法。「RS256」。
typ 權杖的類型。「JWT」。
kid 服務帳戶的私密金鑰 ID。您可以在服務帳戶 JSON 檔案的「private_key_id」欄位中找到這個值。請務必使用具備正確層級權限的服務帳戶金鑰。

JWT 憑證附加資訊區段包含下列欄位:

欄位說明
iss 您服務帳戶的電子郵件地址。
sub 您服務帳戶的電子郵件地址。
aud 您服務帳戶的 SERVICE_NAME,在本例中為 https://fleetengine.googleapis.com/
iat 建立權杖時的時間戳記,指定自世界標準時間 1970 年 1 月 1 日 00:00:00 起經過的秒數。請等待 10 分鐘的偏差。如果時間戳記過於在過去或未來的時間,伺服器可能會回報錯誤。
exp 權杖效期的時間戳記,指定自世界標準時間 1970 年 1 月 1 日 00:00:00 起經過的秒數。如果時間戳記超過未來一小時,要求就會失敗。
authorization 視用途而定,可以包含「deliveryvehicleid」、「trackingid」、「taskid」或「taskids」。

建立 JWT 權杖就像簽署權杖一樣。如需建立及簽署 JWT 的操作說明和程式碼範例,請參閱沒有 OAuth 的服務帳戶授權。接著您可以將最小化權杖附加至 gRPC 呼叫或其他用於存取 Fleet Engine 的方法。

JWT 憑證附加資訊

Last Mile Fleet Solution 使用私人索賠。使用私人憑證可確保只有授權用戶端可以存取自己的資料。舉例來說,當後端針對交付司機的行動裝置核發 JSON Web Token 時,該權杖應包含 deliveryvehicleid 憑證附加資訊,且該憑證的值為該驅動程式的配送車輛 ID。然後,視駕駛角色而定,權杖僅會針對特定提交車輛 ID 啟用存取功能,不會啟用任何其他車輛 ID 的存取權。

Last Mile Fleet Solution 使用以下私人索賠:

  • deliveryvehicleid - 呼叫個別交付車輛的 API 時使用。
  • taskid - 在呼叫每個任務的 API 時使用。
  • taskids - 在呼叫 BatchCreateTasksAPI 時使用。此憑證附加資訊必須採用陣列格式,且陣列應包含完成要求所需的所有工作 ID。請勿加入 delivervehicleidtrackingidtaskid 憑證附加資訊。
  • trackingid - 在呼叫 GetTaskTrackingInfoAPI 時使用。聲明必須與要求中的追蹤 ID 相符。請勿加入 delivervehicleidtaskidtaskids 憑證附加資訊。

當您從後端伺服器呼叫 API 時,該權杖也必須包含適當的憑證附加資訊,但您可以針對 deliveryvehicleidtaskidtrackingid 憑證附加資訊使用星號 (「*」) 的特殊值。星號 (「*」) 也可以用於 taskids 憑證附加資訊,但必須是陣列中唯一的元素。

如果您想直接建立並簽署 JSON 做為符記不動詞,而不使用 OAuth 2.0 存取權杖,請參閱身分開發人員說明文件中沒有 OAuth 的服務帳戶授權一節的說明。

將權杖附加至 gRPC 呼叫的機制,取決於發出呼叫時所用的語言和架構。指定 HTTP 呼叫權杖的機制,是加入含有不記名權杖的授權標頭,該標頭值為符記,如個別運送追蹤機群效能用途的授權附註所述。

以下範例顯示後端伺服器處理每項工作的權杖:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "taskid": "*"
       }
    }

以下範例顯示從後端伺服器批次建立工作的作業符記:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "taskids": ["*"]
       }
    }

以下範例顯示後端伺服器針對每件遞送車輛的作業權杖:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "deliveryvehicleid": "*"
       }
    }

以下範例顯示使用者客戶的權杖:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_delivery_consumer_service_account"
    }
    .
    {
      "iss": "consumer@yourgcpproject.iam.gserviceaccount.com",
      "sub": "consumer@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "trackingid": "shipment_12345"
       }
    }

以下範例顯示驅動程式應用程式的權杖:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_delivery_driver_service_account"
    }
    .
    {
      "iss": "driver@yourgcpproject.iam.gserviceaccount.com",
      "sub": "driver@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "deliveryvehicleid": "driver_12345"
       }
    }
  • 針對標頭中的 kid 欄位,指定服務帳戶的私密金鑰 ID。您可以在服務帳戶 JSON 檔案的 private_key_id 欄位中找到這個值。
  • isssub 欄位指定服務帳戶的電子郵件地址。 您可以在服務帳戶 JSON 檔案的 client_email 欄位中找到這個值。
  • 針對 aud 欄位,指定 https://SERVICE_NAME/
  • 針對 iat 欄位,指定權杖建立時的時間戳記,自世界標準時間 1970 年 1 月 1 日 00:00:00 起經過的秒數。請等待 10 分鐘的偏差。如果時間戳記過於久遠或未來,伺服器可能會回報錯誤。
  • 針對 exp 欄位,指定憑證到期時間的時間戳記,從世界標準時間 1970 年 1 月 1 日 00:00:00 開始計算,以秒為單位。建議值為 iat + 3600。

簽署要傳遞至行動裝置或使用者的權杖時,請務必使用傳送驅動程式或消費者角色的憑證檔案。否則,行動裝置或使用者能夠修改或查看他們不應存取的資訊。