使用证书保护 API

已完成

憑證可以用來在用戶端與 API 閘道之間提供傳輸層安全性 (TLS) 相互驗證。 您可以將 API 管理閘道設定為僅允許具有包含特定指紋之憑證的要求。 閘道層級的授權是透過連入原則處理。

傳輸層安全性用戶端驗證

使用 TLS 用戶端驗證,API 管理閘道可以檢查用戶端要求中包含的憑證,並檢查以下屬性:

屬性 說明
憑證授權單位 (CA) 僅允許特定 CA 所簽署的憑證
指紋 允許包含指定指紋的憑證
主體 僅允許具有指定主體的憑證
到期日期 不允許過期的憑證

這些屬性不會互斥,它們可以混合在一起形成您自己的原則需求。 例如,您可以指定傳入要求的憑證已簽署且未過期。

會簽署用戶端憑證以確保它們未遭竄改。 當合作夥伴向您傳送憑證時,請確認它是否來自他們而不是冒名頂替者。 驗證憑證有兩種常見的方式:

  • 檢查憑證的簽發者。 如果簽發者是您信任的憑證授權單位,則可以使用該憑證。 您可以在 Azure 入口網站中設定受信任的憑證授權單位以自動化此程序。
  • 如果憑證由合作夥伴所簽發,請確認它是否來自他們。 例如,如果他們親自提供憑證,您可以確定其真實性。 這些稱為自我簽署憑證。

接受使用量層中的用戶端憑證

API 管理中的使用量層旨在符合無伺服器的設計原則。 如果您使用無伺服器技術 (例如 Azure Functions) 建置 API,則此層非常適合。 在使用量層中,您必須明確啟用用戶端憑證,您可以在 [自訂網域] 頁面上執行此操作。 其他階層不需要此步驟。

設定閘道以要求憑證。

憑證授權原則

在 API 管理閘道的輸入處理原則檔案中建立這些原則:

[輸入處理原則] 按鈕。

檢查用戶端憑證的指紋

每個用戶端憑證都包含一個指紋,它是一個雜湊,根據其他憑證內容計算而來。 指紋可確保自憑證授權單位簽發憑證以來,憑證中的值沒有變更。 您可以在原則中檢查指紋。 下列範例會檢查要求中所傳遞之憑證的指紋:

<choose>
    <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Thumbprint != "desired-thumbprint")" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>

檢查指紋是否符合已上傳到 API 管理的憑證

在上述範例中,僅有一個指紋可行,因此只會驗證一個憑證。 通常,每個客戶或合作夥伴公司都會傳遞具有不同指紋的不同憑證。 若要支援此案例,請從您的合作夥伴處取得憑證,並使用 Azure 入口網站中的 [用戶端憑證] 頁面將其上傳到 API 管理資源。 然後將此程式碼新增至您的原則:

<choose>
    <when condition="@(context.Request.Certificate == null || !context.Request.Certificate.Verify()  || !context.Deployment.Certificates.Any(c => c.Value.Thumbprint == context.Request.Certificate.Thumbprint))" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>

檢查簽發者和用戶端憑證的主體

此範例會檢查要求中所傳遞之憑證的簽發者與主體:

<choose>
    <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Issuer != "trusted-issuer" || context.Request.Certificate.SubjectName.Name != "expected-subject-name")" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>