透過 API Management 管理 OAuth 授權

  • 148
  • 0

前言

現在許多主流的 API 服務的驗證都是透過 OAuth 來實做,而為了安全性許多服務針對取得的 Access Token 也都會有授權的期限,因此在實做存取 API 的時候大部分人第一個卡關的點就是 OAuth 取得 Access Token,後續則是實做快取 Token 和重新取得 Access Token,而這些每一個不同的 API 服務都要再重新寫一次,實在是太費時了,我們應該把時間留給在真正呼叫 API 的時候,而不是一直花在取得授權這一段重複的工,本文就來介紹透過 API Management 來協助我們管理這些 OAoth 授權。

說明

通常在實做 OAuth 的時候會有一些關鍵的點:

  1. 實做 OAuth 流程取得 Access Token
  2. 暫存 Access Token
  3. 透過 Refresh Token 重新取得 Access Token

而這些雖然微軟有提供 SDK 方便我們實做,但是對於開發者來說還是會有點難度,會需要很清楚整個 oAuth 驗證流程,不然常常會遇到錯誤的時候都不知道該怎麼解決。 

微軟針對 API 有提供一個 API Management 的服務,方便我們管理自行開發的 API,也可以針對不同使用者開放不同可存取的 API 服務,而不需要我們針對自己開發的 API 再撰寫這些權限的管理,也可以把多個不同自行開發的 API 或是第三方的 API 統整成單一的 API 服務接口,更方便的是還提供可以客制化開發者的入口網站,可以提給使用我們自行開發的開發者察看文件和線上測試 API,更多功能可以參考官方文件。而最近這個服務推出了授權管理的公開預覽功能,可以更方便的解決開發 API 時候需要串接第三方 API 服務的 oAuth 取得和管理功能,目前可以支援的 OAuth 包含底下這些,就算不支援的話只要是一般的 OAuth 驗證還是可以使用 Generic  OAuth 2 來設定即可。

從官方文件說明的架構圖來說明,就是我們的前端(靜態網頁、動態網頁、Logic App 或 Functions 等)統一透過 API Management 連接到後面的第三方服務 API,而這些 API 的存取授權部分則是用新的預覽功能來管理。

實做

首先建立 API Management 服務部分就不再重複說明,可以參考我前面的文章:「實做 API Management 使用外部授權驗證」。

建立應用程式

授權管理功能可以支援很多 OAuth,本文就來介紹微軟自己的 AAD 的驗證,一樣到 AAD 底下來建立一個應用程式。

輸入名稱和選擇帳務類型,因為未來會限制透過同一個 AAD 底下的帳號來做驗證,所以我選擇第一個選項:僅此組織目錄中的帳戶,重新導向 URL 先不填寫,後面我們會取的 API Management 的網址再來修改就好。

建立好之後把 ClientId 記錄下來。

接下來新增一組 Secret。

將產生的 Secret 記錄下來。

因為後面我們打算實做存取 Azure 管理的 API,因此要到 API 權限來新增 Azure API 的權限。

點選之後選擇 user_impersonation 權限,這樣未來就可以使用我們設定的使用者身份來存取 API 了。

設定 API Management 授權

接下來回到 API Management,點選授權來建立新的 OAuth 驗證。

這邊就選擇 Azure Active Directory,Client Id 就是前面我們記錄下來的 ID,Client Secret 也是前面我們記錄下來的 Secret,Resource URL 則輸入 Azure API 的網址,這邊我特別把提供者名稱和授權名稱輸入不一樣,方便後面說明,會比較清楚後面輸入的值,最後點選建立。

建立成功的時候就會出現重新導向的 URL,複製下來之後就可以回到我們應用程式註冊裡面去設定了。

點選驗證,因為前面我們沒有輸入網址,這時候先點選新增平台,並選擇 Web。

輸入重新導向的 URL,點選設定就完成了。

這時候回到 API Management 點選下一步繼續設定授權,接下來就是 OAuth 授權的流程了,如果未來取得授權的 Access Token 身份和現在 Azure 使用者一樣就可以點選按鈕直接登入就好,或是複製登入連結給有相關授權帳號的人員去進行後續授權操作。

這時候就可以看到熟悉的 OAuth 授權同意的畫面了。

再來就是同意未來 API Management 可以有該使用者的權限來存取 Azure API 了。

允許之後就會看到成功登入了,就可以進行下一步的設定了。

接下來步驟則是設定 API Management 可以使用我們設定好的 API 授權,依序選取,就可以找到 API Manegemt 的服務主體來新增,新增完成之後就完成整個授權的設定了。

設定 API Management 使用授權

接下來來設定一組 API 服務,點選 API ,然後選擇 HTTP。

輸入名稱和 Azure API 的網址。

接下來新增 azure-demo 這組 API 的 Operation。

首先新增一組 Get Token 的設定,其中 URL 部分則是為影響到之後打 API Management 的網址。

建立好之後針對 Inbound 來編輯內容。

接下來輸入底下的 Policy 設定,其中 provider-id 以我為例是 ms-azure,authorization-id 則是 ms-azure-anyun,這些設定就是前面我們建立的時候設定的,前面故意把名稱錯開,這樣就會比較清楚值的不同了。因為在同一個 provider 底下可以允許有多組的 authorization 設定,就可以分別設定不同的帳號授權,方便我們管理多組帳號授權。

<policies>
    <inbound>
        <base />
        <get-authorization-context provider-id="{provider-id}" authorization-id="{authorization-id}" context-variable-name="auth-context" ignore-error="false" identity-type="managed" />
        <return-response>
            <set-body>@(((Authorization)context.Variables.GetValueOrDefault("auth-context"))?.AccessToken)</set-body>
        </return-response>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

儲存好之後就可以來測試試打 API 來驗證結果了。點選 Test 之後 Send。

這時候就可以看到結果了,有正確的取得 Token,但是還是得驗證一下真的去打 Azure API 是不是可以正確取得結果。

拿 Access Token 來打 Azure API 測試取得訂閱列表,可以正確取得訂閱資訊。

以上就完成取得 Token 的授權流程了,透過 API Management 的授權管理,就可以方便管理我們授權的使用者,以及 Token 的暫存,假設 Token 過期的話也會再重新幫我們取的新的 Access Token。

接下來加碼說明,假設我們要直接新增一組 Operation 是可以直接往後打 Azure API 的話,該怎麼設定 Inbound 的 Policy。新增一組 Get Subscription 的 Operation,其中 URL 部分要設定成和 Azure API 要打的網址一樣,這樣後面就可以比較省事,不用另外設定要轉打的網址。

Inbound Policy 部分則輸入底下的設定,也就是針對 Header 設定會加上 Bearer 和我們的 Token。

<policies>
    <inbound>
        <base />
        <get-authorization-context provider-id="{provider-id}" authorization-id="{authorization-id}" context-variable-name="auth-context" ignore-error="false" identity-type="managed" />
        <set-header name="Authorization" exists-action="append">
            <value>@("Bearer " + ((Authorization)context.Variables.GetValueOrDefault("auth-context"))?.AccessToken)</value>
        </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

這時候再去測試打 API 就可以看到和我們直接用 Token 打的時候結果一樣了。

結論

透過 API Management 來管理授權,不僅可以節省我們很多實做的時間,也可以有一個統一的地方來管理串接的第三方 API 的授權,如果多個專案都會需要存取一樣的第三方服務,就不用每一個專案都實做,在管理上就會方便多了,而有些第三方 API 呼叫時候授權部分並非單純使用應用程式的授權方式,還會需要有使用者登入驗證的步驟,統一管理的話就不需要把該組使用者的授權資訊讓開發人員知道,在安全性上也可以避免太多人擁有這些授權資訊。

而其它官方提到的適合使用此 API Management 的授權管理功能還有底下這些,就讓大家參考一下可以試用的情境。

參考資料