2016年8月5日

[Azure]存取AD B2C tenant的資料

在上兩篇文章中,我們示範了如何建立Azure B2C Tenant以及如何透過B2C Tenant驗證管理會員資料;接下來我們要模擬一個情境:我的公司管理網站需要透過企業AD驗證身分,並且我作為一個管理員可以透過此管理網站取得(或修改)已經登入的會員資訊。

為了達到這個模擬情境,我們需要準備以下的資源:

  • 一個Azure AD Tenant(非B2C Tenant)
  • 一個Azure AD B2C tenant
  • 一個管理網站,並設定期使用Azure AD驗證身分

為了方便起見,這裡的Azure AD Tenant我使用公司本身的Azure AD;Azure B2C Tenant則沿用上篇文章中所使用的B2C Tenant。

在B2C Tenant建立App

  • 輸入基本資料

  • 完成

  • 接著,我們要給予這個App存取B2C Tenant中AD資料的權限;回到管理介面,打開此App的設定頁面

  • 在這裡,因為範例的緣故,我給予這個app完整的AD存取權限;實際上的權限可以依需要指定

  • 接著記下Client ID與Client Secret;這裡Client Secret必須等我們儲存所有設定之後才會顯示

  • 確認所有資料無誤之後按下儲存。
  • 我把存取B2C Tenant所需要的相關API,包成一個B2C Client Library;為了展示的目的,這個Library中現在只包含一個GetUsers()的方法,此方法會取得所有B2C Tenant中的使用者資料
  • 開啟Visual Studio,建立一個新的Class Libaray專案,並加入Microsoft.IdentityModel.Clients.ActiveDirectory package (版本2.18.206251556)

B2C Client Library

  • 程式碼如下;其中Constructor接受三個參數:TenentName, ClientId與ClientSecret
    • TenantName就是B2C Tenant的名稱,例如demo.onmicrosoft.com
    • ClientId與ClientSecret為剛剛記下的ClientID與ClientSecret
  • 完整的Azure AD Graph API文件請參考這裡:https://msdn.microsoft.com/library/azure/ad/graph/api/api-catalog

public class AADB2CClient
{
    //private string TenantId;
    private string ClientId;
    private string ClientSecret;
    private string TenantName;
    private string BearerToken;
    public AADB2CClient(string tenantName,string clientId, string clientSecret)
    {
        ClientId = clientId;
        ClientSecret = clientSecret;
        TenantName = tenantName;
    }
    protected string GetAuthorizationHeader()
    {
        AuthenticationResult result = null;
        var context = new AuthenticationContext($"https://login.microsoftonline.com/{TenantName}");
        var thread = new Thread(() =>
        {
            result = context.AcquireToken("https://graph.windows.net", new ClientCredential(ClientId, ClientSecret));
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Name = "AquireTokenThread";
        thread.Start();
        thread.Join();

        if (result == null)
        {
            throw new InvalidOperationException("Failed to obtain the JWT token");
        }

        BearerToken = result.AccessToken;
        return BearerToken;
    }
    //https://graph.windows.net/{tenant-name}/users?api-version=1.6
    public string GET(string url)
    {
        string token = GetAuthorizationHeader();
        HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
        request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
        request.Method = "GET";
        using (var respStream = request.GetResponse().GetResponseStream())
        {
            using (var sr = new StreamReader(respStream))
            {
                return sr.ReadToEnd();
            }
        }
    }
}

管理介面

  • 管理網站的程式碼較為簡單,為了方便起見,我直接將網站發布到Azure Web App,然後設定為透過公司的AAD驗證

  • 程式的部分僅是在Controller中呼叫B2CClient,並傳入B2C Tenant所需的Tenant Name、Client ID與Client Secret

[Authorize]
public class B2CController : Controller
{
    [HttpGet]
    public ActionResult GetUsers()
    {
        AADB2CClient client = new AADB2CClient(
           tenantName: "mydemob2ctenant.onmicrosoft.com",
           clientId: "{my client id}",
           clientSecret: "{my client secret}");
        var resp = client.GET("https://graph.windows.net/mydemob2ctenant.onmicrosoft.com/users?api-version=1.6");
        B2CModel model = new B2CModel();
        model.Text = resp;

        return View(model);
    }

}

沒有留言:

Blog Archive

About Me