在前篇[Azure] [Xamarin] 使用Xamarin.Forms達成Azure AD的帳號驗證中說明了如何透過Xamarin進行Azure AD帳號的驗證
本篇會延續這個主題,將Xamrin App要連接WebAPI時,進行二次Azure AD驗證的作法
在[Azure] [Xamarin] 使用Xamarin.Forms達成Azure AD的帳號驗證這篇文章中有說明到,如何透過Xamarin的App進行Azure AD的登入驗證
但是這對於App與整體規劃架構來說是不夠的,因為行動化裝置中,取得WebAPI進行資料交換佔了App中相當大比例的動作
所以除了App端進行Azure AD帳號驗證外,也需要在WebAPI這一層再次的驗證,連入WebAPI的客戶端是否為正確的Azure AD帳號
設定的方式很簡單,依照下面的步驟就可以完成了
在Azure AD中,加入一個應用程式,這個應用程式必須有別於上一篇文章中所建立的類別,請選擇[WEB應用程式和/或WEB API]
應用程式屬性設定中,分別輸入登入URL以及應用程式識別碼URI,其中,[應用程式識別碼URI]請先記下來,等一下會用到
建立完成後,進入應用程式的設定頁,加入一份金鑰,金鑰加入後,按下儲存才會顯示在畫面上,請第一時間將這個金鑰值記錄下來
在應用程式設定頁中,其他應用程式的權限項目,加上下方的設定[Read directory data]
委派的權限請加入[Read directory data]、[Sign in and read user profile]
用戶端識別碼也請記下來,等下會用到
接著,回到上一篇文章裡,已經建好的原生App的應用程式設定中,將剛剛建好的WebApp/WebAPI應用程式加入,並設定委派權限
到這裡,Azure AD上的設定都已經完成了,接著就可以回到Visual Studio中,建立一個全新的WebAPI的WebApp
在這個WebAPI中,加入[Microsoft.IdentityModel.Clients.ActiveDirectory]這個Nuget套件
另外也要加入[Microsoft.Owin.Security.ActiveDirectory]這個Nuget套件
在專案上點右鍵,並選擇[設定 Azure AD 驗證]
在設定Azure AD驗證的畫面中,將網域,以及應用程式識別 URI填入,然後選擇現有的Azure AD應用程式設定
接著,請在用戶端密碼欄位上,加入剛剛取得的金鑰字串
在Web.Config裡,加入下面的設定
<add key="ida:Tenant" value="[Domain名稱]" />
<add key="ida:Audience" value="[應用程式識別碼 URI]" />
<add key="ida:ClientID" value="[用戶端識別碼GUID]" />
<add key="ida:Password" value="[金鑰]" />
這邊的設定主要是在告訴Microsoft.IdentityModel.Clients.ActiveDirectory套件,Azure AD上驗證的資訊
接著開啟App_Start\Startup.Auth.cs,加入下方程式碼
using Microsoft.Owin.Security.ActiveDirectory;
public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
},
});
}
設定完成後,就把這個WebAPI直接發佈至雲端WebApp
發佈過程中,有一個設定為[啟用組織驗證],請記得取消打勾,因為我們剛剛已經把組織驗證所有的動作都作完了,這裡無需再次執行
接著,回到Xamarin的App,將Xamarin裡,graphResourceUri這個參數,從原本的https://graph.windows.net,更改成[應用程式識別碼 URI],並在Xamarin中加上下面的程式碼
public static string clientId = "[在這裡填上原生App用戶端識別碼]";
public static string returnUri = "[在這裡填上原生App重新導向URI]";
public static string authority = "https://login.windows.net/common";
private const string graphResourceUri = "[在這裡填上WebApp/WebAPI的應用程式識別 URI]";
public static string graphApiVersion = "2013-11-08";
// 登入的驗證
var data = await iAuth.Authenticate(authority, graphResourceUri, clientId, returnUri);
var userName = data.UserInfo.GivenName + " " + data.UserInfo.FamilyName;
await DisplayAlert("Token", userName, "Ok", "Cancel");
// 取得WebAPI的資訊
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "[WebAPI的URL]");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", data.AccessToken);
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
await DisplayAlert("webapi", content, "Ok");
這段主要的目的,就是當連入WebAPI的時候,同時把從AAD上取得的AccessToken的Header一同傳至WebAPI端,讓WebAPI進行二次驗證的動作
最後,打開模擬器,並執行Xamarin的程式,可以順利取得WebAPI上的值了
如果是透過瀏覽器直接打開WebAPI的頁面,則會跳出沒有授權的訊息
這樣一來,要完成前端AAD驗證與後端WebAPI的介接動作,就大功告成了,對於WebAPI的安全性設定,也就有更進一步的保障
參考資料:
Protect a Web API using Bearer tokens from Azure AD
Azure Active Directory Code Samples
https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof
How to protect a Web API backend with Azure Active Directory and API Management
ASP.NET Web API - Secure ASP.NET Web API with Windows Azure AD and Microsoft OWIN Components
Authentication Scenarios for Azure AD
Secure ASP.NET Web API 2 using Azure Active Directory, Owin Middleware, and ADAL
範例程式已放上GitHub:
https://github.com/madukapai/maduka-Xamarin