Microsoft.Identity.Web 會抽象化 MSAL.NET 的複雜性。 提供您處理 MSAL.NET 內部的較高層級 API,例如處理條件式存取錯誤、快取。
以下是呼叫下游 API 之精靈應用程式的 Program.cs:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
// In the Program.cs, acquire a token for your downstream API
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi",
tokenAcquirerFactory.Configuration.GetSection("MyWebApi"));
var sp = tokenAcquirerFactory.Build();
var api = sp.GetRequiredService<IDownstreamApi>();
var result = await api.GetForAppAsync<IEnumerable<TodoItem>>("MyApi");
Console.WriteLine($"result = {result?.Count()}");
以下是呼叫 Microsoft Graph 之精靈應用程式的 Program.cs:
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddMicrosoftGraph();
var serviceProvider = tokenAcquirerFactory.Build();
try
{
GraphServiceClient graphServiceClient = serviceProvider.GetRequiredService<GraphServiceClient>();
var users = await graphServiceClient.Users
.GetAsync(r => r.Options.WithAppOnly());
Console.WriteLine($"{users.Count} users");
Console.ReadKey();
}
catch (Exception ex) { Console.WriteLine("We could not retrieve the user's list: " + $"{ex}"); }
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Set the appropriate header fields in the request header.
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept", "application/json");
String response = HttpClientHelper.getResponseStringFromConn(conn);
int responseCode = conn.getResponseCode();
if(responseCode != HttpURLConnection.HTTP_OK) {
throw new IOException(response);
}
JSONObject responseObject = HttpClientHelper.processResponse(responseCode, response);
使用 HTTP 用戶端 (例如 Axios),以存取權杖作為授權持有人來呼叫 API 端點 URI。
const axios = require('axios');
async function callApi(endpoint, accessToken) {
const options = {
headers: {
Authorization: `Bearer ${accessToken}`
}
};
console.log('request made to web API at: ' + new Date().toString());
try {
const response = await axios.default.get(endpoint, options);
return response.data;
} catch (error) {
console.log(error)
return error;
}
};
endpoint = "url to the API"
http_headers = {'Authorization': 'Bearer ' + result['access_token'],
'Accept': 'application/json',
'Content-Type': 'application/json'}
data = requests.get(endpoint, headers=http_headers, stream=False).json()
MSAL.NET 中的 AuthenticationResult 屬性
用來取得權杖的方法會傳回 AuthenticationResult
。 若是非同步方法,會傳回 Task<AuthenticationResult>
。
在 MSAL.NET 中,會公開 AuthenticationResult
:
AccessToken
適用於存取資源的 Web API。 此參數是字串,通常是 Base-64 編碼的 JWT。 用戶端永遠不應該查看存取權杖的內部結構。 此格式不保證會維持穩定,並可針對資源將其加密。 撰寫的程式碼相依於用戶端上的存取權杖內容,是最常造成錯誤和用戶端邏輯破碎的來源之一。 如需詳細資訊,請參閱存取權杖。
IdToken
,對象為使用者。 此參數是編碼的 JWT。 如需詳細資訊,請參閱識別碼權杖。
ExpiresOn
告知權杖到期的日期和時間。
TenantId
包含找到使用者時其所在的租用戶。 對於 Microsoft Entra B2B 案例中的來賓使用者,租用戶識別碼是來賓租用戶,而非唯一租用戶。
當使用者傳遞權杖時,AuthenticationResult
也會包含此使用者的相關資訊。 對於會在應用程式沒有使用者的情況下要求權杖的機密用戶端流程,此使用者資訊是 Null。
- 簽發權杖時所適用的
Scopes
。
- 使用者的唯一識別碼。
IAccount
MSAL.NET 會透過IAccount
介面定義帳戶的概念。 此重大變更會提供正確的語意。 同一個使用者可擁有數個位於不同 Microsoft Entra 目錄的帳戶。 此外,在來賓案例的情況中,因為會提供主帳戶資訊,所以 MSAL.NET 會提供更好的資訊。
下圖顯示 IAccount
介面的結構。
AccountId
類別會使用下表所示的屬性來識別特定租用戶中的帳戶。
屬性 |
說明 |
TenantId |
以字串表示的 GUID,這是帳戶所在租用戶的識別碼。 |
ObjectId |
以字串表示的 GUID,這是擁有租用戶中帳戶的使用者所具有的識別碼。 |
Identifier |
帳戶的唯一識別碼。 Identifier 是 ObjectId 及 TenantId 的串連,並會以逗號分隔。 兩者並非 Base-64 編碼的。 |
IAccount
介面會呈現單一帳戶的相關資訊。 相同的使用者可以存在於不同的租用戶中,這表示使用者可以有多個帳戶。 其成員會顯示在下表中。
屬性 |
說明 |
Username |
包含 UserPrincipalName (UPN) 格式中可顯示值的字串,例如 john.doe@contoso.com。 與 HomeAccountId 和 HomeAccountId 不同 (不是 Null),此字串可以是 Null。 此屬性會取代舊版 MSAL.NET 版本中 IUser 的 DisplayableId 屬性。 |
Environment |
包含此帳戶身分識別提供者的字串,例如 login.microsoftonline.com 。 除了雲端環境以外,除非 IdentityProvider 也具有租用戶相關的資訊,否則此屬性會取代 IUser 的 IdentityProvider 屬性。 在這裡,此值只是主機。 |
HomeAccountId |
使用者主帳戶的帳戶識別碼。 此屬性可跨 Microsoft Entra 租用戶來唯一識別使用者。 |
使用權杖呼叫受保護的 API
當 result
中的 AuthenticationResult
由 MSAL 傳回之後,請將之新增至 HTTP 授權標頭,再進行呼叫以存取受保護的 Web API。
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
...
對於精靈應用程式,您呼叫的 Web API 需要預先核准。 精靈應用程式不會有累加式同意。 (不需要使用者互動。)租用戶管理員必須事先同意應用程式和所有 API 權限。 如果您想要呼叫數個 API,您在每次呼叫 AcquireTokenForClient
時都須取得每個資源的權杖。 MSAL 會使用應用程式權杖快取,以避免不必要的服務呼叫。