透過 Azure AD 驗證 Azure Service Management REST API 呼叫

Microsoft Azure提供了各種管理服務的機制,除了透過Portal,也可以透過Powershell、XPlat-CLI、Python SDK等等;而這所有的工具,底層最終都是透過呼叫Azure的REST API與Azure管理機制溝通達到管理的目的。

Azure目前有兩種管理的API,Azure Resource Manager API與Azure Service Management API;兩者都允許我們管理與瀏覽各項服務,而呼叫這兩種API時,都必須通過驗證。

Azure Service Management API提供了透過Client Certificate的驗證以及Azure Active Directory驗證兩種機制;而呼叫Resource Manager API時則必須透過Azure AD作為驗證機制。

本文會以範例說明如何透過.Net呼叫Azure Service Management API,並以Azure Active Directory使用者的帳號密碼作為身分驗證機制。

在開始之前需要注意,所有的訂閱都必定會有一個預設的AAD;所有的訂閱都需要與一個AAD關聯。預設來說,你的訂閱會與預設的AAD關聯;但是你也可以建立新的AAD,並將你的訂閱與新的AAD關聯。而為了要讓程式可以透過使用者帳號密碼呼叫API存取資源,我們所建立的使用者必須是與訂閱關聯的AAD中的使用者。

l 在我的例子中,我總共有三個AAD。

l 我的訂閱是與MichaelChi.Net這個AAD關聯

l 首先,為了可以透過AAD驗證,我們需要在AAD中加入並賦予我們的程式相關權限。

l 切換到AD管理介面、應用程式

l 新增一個原生應用程式

l 輸入名稱

l 輸入一個合法的URI

l 完成後,切換到應用程式的設定頁面

l 加入應用程式

l 加入Windows Azure Service Management

l 完成後委派權限

l 然後存檔

l 回到畫面上方把用戶端識別碼(Client ID)記錄下來,稍後會用到

l 接著,如果AAD中還沒有使用者,請先創建一個新的使用者。我們要將此使用者加入成為co-admin

l 則切換到管理頁簽確認共同管理員

l 以該使用者登入https://manage.windowsazure.com 確認可以看到服務,並且已經不需更改密碼。

l 切換到Azure AD管理頁簽,並切換到應用程式頁簽

l 按下下方的檢視端點

l 紅框框起來的地方即是此AAD的Tenant ID,請先記起來

l 接著,打開Visual Studio專案,加入Active Directory Authentication Library

l 在專案中加入以下這段程式碼

        protected static string GetAuthorizationHeader()

        {

            AuthenticationResult result = null;

            var context = new AuthenticationContext("https://login.windows.net/<<Tenant ID>>");

            var thread = new Thread(() =>

            {

                result = context.AcquireToken("https://management.core.windows.net/", "<<Client ID>>", new UserCredential("<<User ID>>", "<<Password>>"));

                            });

            thread.SetApartmentState(ApartmentState.STA);

            thread.Name = "AquireTokenThread";

            thread.Start();

            thread.Join();

            if (result == null)

            {

                throw new InvalidOperationException("Failed to obtain the JWT token");

            }

            string token = result.AccessToken;

            return token;

        }

l 呼叫API前,先加入Authentication Header

string token = GetAuthorizationHeader();

var REQUEST_URL = string.Format("https://management.core.windows.net/{0}/services/storageservices", <<SUBSCRIPTION ID>>);

HttpWebRequest request = HttpWebRequest.Create(REQUEST_URL)

request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);

request.Method = "GET";

request.Headers.Add("x-ms-version","2015-04-01");

l 呼叫API

using (var resp = request.GetResponse())

            {

                using (var respStream = resp.GetResponseStream())

                {

                    using (var sr = new StreamReader(respStream))

                    {

                        return sr.ReadToEnd();

                    }

                }

            }

參考資料:

https://msdn.microsoft.com/en-us/library/azure/ee460782.aspx