如何使用 Azure Active Directory 認證和 Microsoft Graph 構建 Blazor Web 應用
阿新 • • 發佈:2020-10-24
# 如何使用 Azure Active Directory 認證和 Microsoft Graph 構建 Blazor Web 應用
英文原文:https://developer.microsoft.com/en-us/identity/blogs/how-to-build-a-blazor-web-app-with-azure-active-directory-authentication-and-microsoft-graph/
如果您是一個 .NET 開發者,你很可能聽過過 Blazor 是一個最近的熱門開發技術。Blazor 是一個使用 .NET Blazor 伺服器來構建可互動客戶端 Web 介面的框架。就是本文所專注的技術,提供了在 ASP.NET Core 應用中,在伺服器端寄宿 Razor 元件的支援。UI 的更新通過 SignalR 連線進行。由於多數的應用都需要某些程度的驗證和授權,這裡將展示如何使用 Azure AD 實現驗證的最佳方式,以及如何從 Microsoft Graph 獲取資料。
### 先決條件
為了繼續下面的演練,您需要最新版本的 [NET Core 3.1 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1), [Visual Studio 2019](https://visualstudio.microsoft.com/downloads/) (可選,但是最好),並且擁有一個 Azure AD 的租戶。如果你不能訪問 Azure AD 租戶,要麼你可以免費註冊一個 [Microsoft 365 Developer program](https://developer.microsoft.com/en-us/microsoft-365/dev-program),或者建立一個免費的 [Free Azure Trial](https://azure.microsoft.com/free) 試用賬號。
### Blazor 與驗證
如果你正在構建 Blazor (伺服器端) 應用,那麼我們有一些好訊息。Visual Studio 和 CLI 模版支援開箱即用的驗證支援。開啟 Visual Studio,然後建立一個新的 Blazor 應用。我們將它命名為 "BlazorAppWithAuth",然後按照下面的動畫進行。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/1.gif)
通過選擇工作或者學校賬號驗證選項,Visual Studio 將在 Azure AD 上建立適當的應用註冊,併為 Blazor 應用配置開箱即用的驗證所需的配置和程式碼。我們可以通過檢查 appsettings.json 來確認。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/2.png)
並且,如果你到 Azure 門戶的 Azure AD 註冊頁籤中檢視,還可以看到與 Visual Studio 中看到的資訊想匹配的應用註冊資料。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/3.png)
不需要寫一行程式碼,我們的 Blazor 應用在使用者訪問任何頁面之前,就可以提示使用者。我們可以通過執行應用來快速測試該應用。在我們第一次訪問該站點的時候,我們將被提示這些應用要求的 (預設) 許可權,這裡是讀取使用者的資料。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/4.png)!
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/5.png)
到了這一步,你可能認為我們的任務已經完成了,實際上,還有許多事情要做。首先,預設的模版使用了老式的,預設 v1 版本的 Azure AD 端點。如果你想知道為什麼你應當使用 Microsoft identity platform 並使用 v2 版本的端點,你可以[檢視 Microsoft identity platform 文件](https://docs.microsoft.com/en-us/azure/active-directory/develop/)。
### 使用 Microsoft.Identity.Web 現代化驗證
在 [Build 2020](https://techcommunity.microsoft.com/t5/azure-active-directory-identity/build-2020-fostering-a-secure-and-trustworthy-app-ecosystem-for/ba-p/1257360) 中,我們為 ASP.NET Core 3.1 (及後繼版本) 宣佈了一個新的驗證和令牌管理庫。新的庫對複雜性進行了很棒的大量抽象,支援開發者只需要很少的程式碼就可以實現驗證。而且,新庫最大的優勢是因為該庫構建與 MSAL 之上,你不再需要使用兩個單獨的庫來先進行驗證,然後獲得一個令牌來訪問後端的 API。所以,讓我們看一下如何遷移到這個最新的庫上。
> 注意:Microsoft.Identity.Web 仍然在預覽狀態,它將很快釋出
>
> 注意:現在 1.0 已經發布。釋出時間:2020/10/1
>
> 注意:現在 1.1.0 已經發布,釋出時間:Tuesday, October 6, 2020 (10/6/2020)
首先,我們需要下載這個新的 NuGet 包
* Microsoft.Identity.Web - 1.1.0 已經發布
* Microsoft.Identity.Web.UI - 1.1.0 已經發布
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/6.png)
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/7.png)
然後,我們需要修改幾行程式碼來清除老的驗證程式碼並切換到新的程式碼。
開啟 Startup() 並替換程式碼,下面是原來的程式碼:
```csharp
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
```
替換為:
```csharp
services.AddMicrosoftWebAppAuthentication(Configuration);
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddMicrosoftIdentityUI();
```
使用 1.1 SDK 後,應該為:
```csharp
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddMicrosoftIdentityUI();
```
最後,我們需要確保我們的應用可以使用正確的 v2 版本端點來進行登入和登出。開啟 LoginDisplay.razor 並進行如下的更新:
```html
Hello, @context.User.Identity.Name!
Log out
Log in
```
你需要注意到,這裡並沒有特定的用來登入和登出的頁面。相反,它們構建在 Microosft.Identity.Web.dll 內部。所以,在我們更新區域到 "MicrosoftIdentity" 的時候,不再需要其它的修改了。
當我們再次從 Visual Stuido 執行應用的時候,我們從 v2 中獲得新的登入體驗,例如無口令和多因子驗證。最棒的是這些功能被設計為不需要修改任何程式碼,隨著 Azure AD 的管理被配置為使用這些設定,所有的使用者可以從更強的安全性中獲益。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/8.png)
如你所見,使用很少的程式碼,我們可以藉助於 Microsoft.Identity.Web 庫基於 Azure AD 來驗證使用者。
### 從 Microsoft Graph 提取資料
Microsoft Graph 提供了大量的 API 來支援你基於使用者自己的資料構建豐富的沉浸式的應用。在下面的步驟中,我們將拉取使用者的電子郵件並將它們顯示在應用內。為達到該目標,我們首先需要在 Azure AD 上擴充套件應用註冊的許可權,增加訪問電子郵件資料的訪問,然後我們需要在 Blazore 應用中新增一些程式碼來提取,並在其中的一個頁面上顯示資料。
#### Azure AD 門戶
找到應用的註冊,並進入 API 許可權,選擇新增新的許可權,然後選擇 Graph API,在這裡,我們希望選擇被代理許可權,並選擇 "Mail Read" 許可權。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/9.gif)我們還需要建立一個使用者金鑰,因為我們的應用將需要一個驗證令牌,和提取資料而不需要任何使用者互動的方式。在同一個應用註冊中,開啟 Certificates 和 Secrets 頁籤,然後建立新的永不過期的金鑰,如下所示:
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/10.gif)
確保你複製了密碼,因為一旦你從該頁面切換出去,你就再也不能訪問它了。但是,如果需要的話,你總是可以重新建立它 - 這很簡單且免費。
回到 Blazor 應用中,在 Visual Studio 中,我們首先需要在 appsettings.json 中新增客戶金鑰。在 AzureAD
的配置節,我們必須新增如下的行:
```json
“ClientSecret”: “”
```
在 Startup.cs 檔案中,我們需要更新程式碼以確保使用正確的許可權獲取了適當的訪問令牌,並將它儲存在快取中,以便我們在後繼的應用中使用它訪問 Microsoft Graph。我們將新增 HttpClient 到我們的服務管線中,來支援我們隨後有效的發出 HTTP 呼叫到 Microsoft.Graph。
```csharp
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi( new string[] { "User.Read", "Mail.Read" })
.AddInMemoryTokenCaches();
services.AddHttpClient();
```
然後,我們需要更新在 FetchData.razor 頁面中的程式碼來獲取我們的電子郵件資料,來替代預設的天氣資料。下面的程式碼包含了所有我們需要獲取電子郵件並顯示在頁面上的程式碼。
```html
@page "/fetchdata"
@inject IHttpClientFactory HttpClientFactory
@inject Microsoft.Identity.Web.ITokenAcquisition TokenAcquisitionService
}
@code {
private string userDisplayName;
private List messages = new List();
private HttpClient _httpClient;
protected override async Task OnInitializedAsync()
{
_httpClient = HttpClientFactory.CreateClient();
// get a token
var token = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "User.Read", "Mail.Read" });
// make API call
_httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var dataRequest = await _httpClient.GetAsync("https://graph.microsoft.com/beta/me");
if (dataRequest.IsSuccessStatusCode)
{
var userData = System.Text.Json.JsonDocument.Parse(await dataRequest.Content.ReadAsStreamAsync());
userDisplayName = userData.RootElement.GetProperty("displayName").GetString();
}
var mailRequest = await _httpClient.GetAsync("https://graph.microsoft.com/beta/me/messages?$select=subject,receivedDateTime,sender&$top=10");
if (mailRequest.IsSuccessStatusCode)
{
var mailData = System.Text.Json.JsonDocument.Parse(await mailRequest.Content.ReadAsStreamAsync());
var messagesArray = mailData.RootElement.GetProperty("value").EnumerateArray();
foreach (var m in messagesArray)
{
var message = new MailMessage();
message.Subject = m.GetProperty("subject").GetString();
message.Sender = m.GetProperty("sender").GetProperty("emailAddress").GetProperty("address").GetString();
message.ReceivedTime = m.GetProperty("receivedDateTime").GetDateTime();
messages.Add(message);
}
}
}
public class MailMessage
{
public string Subject;
public string Sender;
public DateTime ReceivedTime;
}
}
```
重新執行應用,並確保先登出當前的使用者,因為當前的令牌沒有包含正確的訪問許可權,並且我們已經修改了一些程式碼。你將會注意到再次登入的時候,我們的提示增加了新的訪問許可權,這意味著一切如我們所願。現在,除了基本的使用者資料資料,應該還可以請求訪問我們的電子郵件資料。
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/11.png)
在授權之後,我們被導航到了 "Fetch Data" 頁面,可以看到一些電子郵件!
![](https://developer.microsoft.com/en-us/identity/blogs/wp-content/uploads/2020/07/12-1536x780.png)
如果你正確的如上演練,你現在應該可以看到類似上面圖示中的你的電子郵件資料了。
### 總結
新的 Microsoft.Identity.Web 在簡化驗證和令牌管理方面做了出色的改進,你現在就應該開始使用它,在開始之前,有些事情值得你關注:
1. 與普通的支援動態/增加提醒的 Web 應用不同,在 Blazor 中,你需要在一開始為你的應用請求所有需要的許可權。失敗的話,將會導致 TokenAcruisition 方法不能根據新的許可權驗證使用者。這是 Blazor 機制的一部分,所以在建立應用的時候要記住這一點。
2. 不是自己處理 Microsoft Graph HTTP 請求,你應該藉助於 Microsoft Graph SDK,它簡化了與 Microsoft Graph 的互動並提供了所有你需要序列化和反序列的物件。但是,在本示例中,我們僅僅遵循了建議 1,因為我們僅僅發出一個 Microsoft Graph 呼叫。
最後,你可以在 GitHub 上找到本示例 Blazor 應用程式的可執行示例的[所有的原始碼](https://github.com/jpda/msiddev-blazor-aad-graph),
### 參考
* [Microsoft.Identity.Web at NuGet](https://www.nuget.org/packages/Microsoft.Identit
Weather forecast
This component demonstrates fetching data from a service.
@if (messages == null) {Loading...
} else {Hello @userDisplayName !!!!
Subject | Sender | Received Time |
---|---|---|
@mail.Subject | @mail.Sender | @mail.ReceivedTime |