附註:

使用 OCI 函數和 OCI 佇列授權使用者功能,但不對核准者顯示管理權限

簡介

更新使用者功能是許多企業的重要需求,尤其是授權使用者權限敏感時 (例如主控台功能或 API 金鑰)。不過,在 Oracle Cloud Infrastructure (OCI) 文件中,只有管理員群組中的使用者能夠授權使用者功能,即使有明確允許的 Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) 原則也一樣。如需詳細資訊, 請參閱管理使用者.

本教學課程示範一個解決方案,說明使用者不在 OCI IAM 網域的管理員群組中,但仍需要使用 OCI Connector Hub 新發行的功能來整合 OCI Queue 和 OCI Functions,以授權使用者功能。

解決方案構架

SolutionArchitecture.png 圖解描述

目標

作業 1:建立從 OCI 佇列到 OCI 函數的訊息通道

解決方案的重要部分是將使用者能力從核准者需要核准要求的權限中變更,以解除所需的權限。

  1. 建立內送要求的 OCI 佇列。如需詳細資訊,請參閱建立佇列

  2. 建立用於授權使用者的 OCI 函數。如需詳細資訊,請參閱建立函數

  3. 透過 OCI 連線器中心設定 OCI 佇列與 OCI 函數整合。確定在建立 OCI 佇列時指定來源,而且目標應為 OCI 函數。我們將在本教學課程中將選擇性工作留白。如需詳細資訊,請參閱宣布提供 OCI 佇列作為 OCI Connector Hub 中的來源

作業 2:設定 OCI IAM 原則和動態群組

將核准者的角色分割至 OCI 佇列以接受要求,而 OCI 函數則執行要求之後,我們需要設定嚴格的 OCI IAM 原則,以確定未濫用權限。由於我們建置此解決方案以支援堅持使用根區間進行實作的客戶,因此將示範 OCI IAM 部分根區間的所有組態。

  1. 僅允許核准者將佇列訊息推送至目標 OCI 佇列。

    Allow group 'testApprover' to use queues in tenancy
    

    新增此原則後,我們允許 testApprover 群組中的使用者使用此佇列來接收主控台存取要求。我們只能指定佇列推播資源類型的權限,以對群組設定更多限制,如以下範例所示。

    use queue-push in compartment <compartment> where target.queue.id = '<queue_ocid>'
    
  2. 指定下列比對規則,將動態群組設定為包括 OCI 函數。

    ALL{resource.type='fnfunc',resource.id='ocid.fnfunc.oc1.....'}
    

    接著,系統會授權此動態群組使用 Oracle Identity Cloud Service 角色來管理網域中的使用者。

  3. 設定動態群組 Oracle Identity Cloud Service 角色。

    IDCS 網域角色

    DomainRole.png 圖解描述

  4. 將 OCI 函數設定為只能由 OCI 佇列呼叫。下列範例只會將呼叫來源限制在佇列中,我們實際上可能會透過在資源上使用標記使它更嚴格。如需詳細資訊,請參閱使用標記管理存取權

    Allow service faas to use functions-family in tenancy where request.principal.type='queues'
    

作業 3:撰寫 OCI 函數代碼

我們需要撰寫一段 Python 程式碼,讓 OCI Functions 能夠實際執行從 OCI Queue 提出的要求。

  1. OCI Queue 訊息將傳送至 data 物件中的函數。

    def handler(ctx, data: bytes = None) -> response.Response:
        try:
        # Parse the message from the OCI Queue
            if data:
            message = json.loads(data.getvalue().decode('utf-8'))
            else:
            message = "no useremail received"
    
  2. 使用資源主體進行認證。

    注意:下列程式碼可能無法在 IDE 中運作。

    identity = IdentityClient({}, signer=oci.auth.signers.get_resource_principals_signer(), region=region)
    
  3. 轉換傳送至使用者 Oracle Cloud ID (OCID) 的使用者電子郵件。

    def get_user_ocid_by_email(identity_client,email,tenancy_id):
        # List all users in the tenancy
        users = oci.pagination.list_call_get_all_results(identity_client.list_users,tenancy_id).data
    
        # Find the user with the matching email address
        for user in users:
            if user.email.lower() == email.lower():
                return user.id
    
        return None
    
  4. 使用 IdentityClient 函數以資源主體更新使用者功能。

    # Get the user by email address
    user_ocid = get_user_ocid_by_email(identity,user_email,tenancy)
    
    # Update user capabilities (example: enable API keys)
    update_details = oci.identity.models.UpdateUserCapabilitiesDetails(
        can_use_api_keys=True,
        can_use_auth_tokens=True,
        can_use_console_password=True,
        can_use_customer_secret_keys=True,
        can_use_db_credentials=True,
        can_use_o_auth2_client_credentials=True,
        can_use_smtp_credentials=True
    )
    
    # Update the user
    identity.update_user_capabilities(user_ocid, update_details)
    
  5. 將函數程式碼部署到剛建立的 OCI 函數中。如需部署 OCI 函數的詳細步驟,請參閱 OCI 函數的組態注意事項

作業 4:測試變更

傳送訊息至目標佇列以測試變更。我們可能會使用 OCI 主控台或使用任何 SDK,包括 OCI Cloud Shell。

傳送郵件

send-message.png 圖解描述

檢查

examine.png 圖解描述

疑難排解

設定讓 OCI 函數使用 OCIR

如果您使用 OCIR 作為 OCI 函數的儲存區域,有幾個問題可能會阻擋您,而且目前找不到解決方法並不容易,因為目前沒有明確指南可明確證明以避免此類問題。

  1. 設定 OCIR 儲存區域和 OCI 函數的特定區間作為函數相關資訊環境。依照預設,即使您依照主控台的指示頁面執行 Cloud Shell 命令,OCIR 儲存區域的相關資訊環境仍指向根區間。

    fn update context oracle.compartment-id ocid1.tenancy.oc1.....
    

    注意:此部分與 oracle.compartment-id 一樣具有誤導性,因此人們認為此特性適用於函數和 OCIR,不過,我們對 OCIR (image-compartment-id) 具有個別的特性。因此,如果您使用具名區間執行函數並儲存映像檔,請確定已使用下列 OCI Cloud Shell 命令明確設定這兩個區間 ID。此外,也必須設定適當的 OCI IAM 原則,以允許 OCIR 與函數之間的動作 (如果它們來自不同的指定區間)。

    fn update context oracle.image-compartment-id <compartment-ocid>
    fn update context oracle.compartment-id <compartment-ocid>
    

    如果這樣做未正確完成,您將會遇到有線 403 錯誤,而且您可能甚至不知道 image-compartment-id,所以很難找到線索。

  2. 當 OCI Cloud Shell 是從 docker.io 可存取的網路環境啟動時,設定函數以使用 OCIR,因為我們必須套用 docker API 來處理映像檔,而且 OCI 服務網路通常不允許您存取。如果您使用 OCI Cloud Shell,建議您使用公用網路部署容器。

    如需詳細資訊,請參閱函數:使用 Cloud Shell 開始使用

  3. 此處的另一個潛在阻斷器是當您嘗試將佇列訊息傳遞至函數輸入時。您可以在其他文章中找到有關如何傳入變數的文章,但其實與輸入 json 簡單,並在 Python 程式碼的 data 物件中接收。

    注意:請避免使用 Javascript 類型的 json 加上單引號或不加上引號,因為現在只有 OCI 佇列能夠辨識嚴格的語法。

    {"name":"John"}
    

認可

其他學習資源

探索 docs.oracle.com/learn 上的其他實驗室,或存取 Oracle Learning YouTube 頻道上的更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。

如需產品文件,請造訪 Oracle Help Center