Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
W tym artykule wyjaśniono, jak używać programu Microsoft Graph w Blazor WebAssembly aplikacjach, co umożliwia aplikacjom uzyskiwanie dostępu do zasobów w chmurze firmy Microsoft.
Omówiono dwa podejścia:
Zestaw SDK programu Graph: zestaw SDK programu Microsoft Graph upraszcza tworzenie wysokiej jakości, wydajnych i odpornych aplikacji, które uzyskują dostęp do programu Microsoft Graph. Wybierz przycisk Graph SDK u góry tego artykułu, aby zastosować to podejście.
Nazwany klient HttpClient z interfejsem API Graph: nazwany
HttpClientmoże wysyłać żądania do interfejsu API Microsoft Graph bezpośrednio do Microsoft Graph. Wybierz przycisk Nazwany klient HttpClient z interfejsem API programu Graph w górnej części tego artykułu, aby zastosować to podejście.
Wskazówki zawarte w tym artykule nie dotyczą zastępowania dokumentacji programu Microsoft Graph i wskazówek dotyczących zabezpieczeń platformy Azure w innych zestawach dokumentacji firmy Microsoft. Przed wdrożeniem programu Microsoft Graph w środowisku produkcyjnym należy ocenić wskazówki dotyczące zabezpieczeń w sekcji Dodatkowe zasoby tego artykułu. Postępuj zgodnie z najlepszymi rozwiązaniami firmy Microsoft, aby ograniczyć luki w zabezpieczeniach aplikacji.
Dodatkowe podejścia do pracy z programem Microsoft Graph i Blazor WebAssembly są udostępniane przez następujące przykłady programu Microsoft Graph i platformy Azure:
-
Przykładowa aplikacja Blazor WebAssemblyMicrosoft Graph: Przykład wykorzystuje podejście oparte na wzorcu fabryki z użyciem zestawu Microsoft Graph SDK do uzyskiwania danych usługi Office 365. W przykładzie użyto wartości domyślnej HttpClient do tworzenia żądań klienta programu Graph. Jeśli musisz użyć domyślnego HttpClient z adresem bazowym aplikacji (
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) do innych celów, na przykład do ładowania danych z głównego katalogu sieci Web aplikacji, rozważ refaktoryzację fabryki klienta Graph, aby używała nazwanegoHttpClientdedykowanego żądaniom Graph. -
ASP.NET Core na platformie .NET 8 Blazor WebAssembly | aplikacja autonomiczna | Logowanie użytkownika, chroniony dostęp do internetowego interfejsu API (Microsoft Graph) | Platforma tożsamości firmy Microsoft: przykładowa aplikacja internetowa progresywna (PWA), która używa procedury obsługi komunikatów autoryzacji i HttpClient uzyskiwania danych programu Graph. Podobnie jak w przypadku poprzedniego przykładu, ten przykład używa również wartości domyślnej HttpClient do tworzenia żądań klientów programu Graph. Zamiast korzystać z zestawu Microsoft Graph SDK, przykład pobiera dane konta użytkownika jako dane JSON za pośrednictwem żądania interfejsu API programu Microsoft Graph w składniku. Jest to podobna technika do podejścia nazwanego httpclient z interfejsem API programu Graph w tym artykule (użyj przycisku w górnej części tego artykułu, aby wyświetlić wskazówki), z tą różnicą, że wskazówki w tym artykule używają nazwy
HttpClientdedykowanej dla żądań programu Graph.
Aby przekazać uwagi dotyczące któregokolwiek z dwóch poprzednich przykładów, utwórz zgłoszenie w repozytorium GitHub danego przykładu. Jeśli otwierasz problem dla przykładu platformy Azure, podaj link do przykładu w komentarzu otwierającym, ponieważ przykładowe repozytorium platformy Azure (Azure-Samples) zawiera wiele przykładów. Opisz szczegółowo problem i dołącz przykładowy kod zgodnie z potrzebami. Umieść minimalną aplikację w usłudze GitHub, która odtworzy problem lub błąd. Pamiętaj, aby usunąć dane konfiguracji konta platformy Azure z przykładu przed zatwierdzeniem ich w repozytorium publicznym.
Aby przekazać opinię lub uzyskać pomoc w sprawie tego artykułu albo platformy ASP.NET Core, zobacz podstawy platformy ASP.NET CoreBlazor.
Ważne
Scenariusze opisane w tym artykule dotyczą korzystania z usługi Microsoft Entra (ME-ID) jako dostawcy tożsamości, a nie usługi AAD B2C. Korzystanie z usługi Microsoft Graph z aplikacją Blazor WebAssembly po stronie klienta i dostawcą tożsamości usługi AAD B2C nie jest obecnie obsługiwane, ponieważ aplikacja wymaga sekretu klienta, który nie może być zabezpieczony w aplikacji Blazor po stronie klienta. W przypadku samodzielnej aplikacji usługi AAD B2C Blazor WebAssembly korzystającej z interfejsu API Microsoft Graph utwórz interfejs API serwera zaplecza (sieci Web), aby uzyskiwać dostęp do interfejsu API Microsoft Graph w imieniu użytkowników. Aplikacja po stronie klienta uwierzytelnia i autoryzuje użytkowników, aby mogli wywoływać internetowy interfejs API w celu bezpiecznego uzyskiwania dostępu do Microsoft Graph i zwracania danych do aplikacji po stronie klienta z internetowego interfejsu API działającego po stronie serwera. Klucz tajny klienta jest bezpiecznie przechowywany w interfejsie API opartym na serwerze, a nie w aplikacji Blazor po stronie klienta. Nigdy nie przechowuj klucza tajnego klienta w aplikacji po stronie Blazor klienta.
Uwaga
Usługa Azure Active Directory B2C nie jest już dostępna jako usługa dla nowych klientów od 1 maja 2025 r. Aby uzyskać więcej informacji, zobacz Azure AD B2C: często zadawane pytania.
Korzystanie z hostowanej aplikacji Blazor WebAssembly jest obsługiwane, w której aplikacja Server używa zestawu Graph SDK/interfejsu API Graph do udostępniania danych usługi Graph aplikacji Client za pośrednictwem internetowego interfejsu API. Aby uzyskać więcej informacji, zobacz sekcję Hostowane Blazor WebAssembly rozwiązania w tym artykule.
Przykłady w tym artykule korzystają z nowych funkcji platformy .NET/C#. W przypadku używania przykładów z platformą .NET 7 lub starszym wymagane są drobne modyfikacje. Jednak przykłady tekstu i kodu dotyczące interakcji z programem Microsoft Graph są takie same dla wszystkich wersji ASP.NET Core.
Poniższe wskazówki dotyczą Microsoft Graph w wersji 5 lub nowszej.
Zestaw SDK Microsoft Graph do użytku w aplikacjach Blazor nosi nazwę biblioteka kliencka Microsoft Graph dla platformy .NET.
Przykłady pakietu SDK Graph wymagają następujących odwołań do pakietów w samodzielnej aplikacji Blazor WebAssembly. Odwołania do pierwszych dwóch pakietów są już dodane, jeśli aplikacja została skonfigurowana do uwierzytelniania za pomocą biblioteki MSAL, na przykład podczas tworzenia aplikacji zgodnie ze wskazówkami zawartymi w artykule Zabezpiecz autonomiczną aplikację ASP.NET Core Blazor WebAssembly za pomocą identyfikatora Microsoft Entra.
Przykłady pakietu SDK Graph wymagają następujących odwołań do pakietów w autonomicznej aplikacji Blazor WebAssembly lub aplikacji Client hostowanego rozwiązania Blazor WebAssembly. Do pierwszych dwóch pakietów istnieją już odwołania, jeśli aplikacja została skonfigurowana do uwierzytelniania za pomocą biblioteki MSAL, na przykład podczas tworzenia aplikacji zgodnie ze wskazówkami zawartymi w artykule Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly za pomocą identyfikatora Microsoft Entra.
Microsoft.AspNetCore.Components.WebAssembly.AuthenticationMicrosoft.Authentication.WebAssembly.MsalMicrosoft.Extensions.HttpMicrosoft.Graph
Uwaga
Pakiet Microsoft.Authentication.WebAssembly.Msal przechodnio dodaje pakiet Microsoft.AspNetCore.Components.WebAssembly.Authentication do aplikacji.
Uwaga
Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.
W witrynie Azure Portal przyznaj delegowane uprawnienia (zakresy)† dla danych programu Microsoft Graph, do których aplikacja powinna mieć dostęp w imieniu użytkownika. Na przykład w tym artykule rejestracja aplikacji powinna zawierać delegowane uprawnienia do odczytu danych użytkownika (Microsoft.Graph>User.Read zakres w uprawnieniach interfejsu API, Typ: Delegowane). Zakres User.Read umożliwia użytkownikom logowanie się do aplikacji i umożliwia aplikacji odczytywanie profilu i informacji firmowych zalogowanych użytkowników. Aby uzyskać więcej informacji, zobacz Omówienie uprawnień i zgody na platformie tożsamości Microsoft oraz Omówienie uprawnień Microsoft Graph.
†Uprawnienia i zakresy oznaczają to samo i są używane zamiennie w dokumentacji zabezpieczeń i portalu Azure. Jeśli tekst nie odnosi się do portalu Azure, w tym artykule używa się terminów zakres/zakresy w odniesieniu do uprawnień Graph.
Zakresy są niewrażliwe na wielkość liter, więc User.Read jest taka sama jak user.read. Możesz użyć dowolnego formatu, ale zalecamy spójny wybór w kodzie aplikacji.
Po dodaniu zakresów interfejsu API Microsoft Graph do rejestracji aplikacji w portalu Azure dodaj do pliku wwwroot/appsettings.json aplikacji następującą konfigurację ustawień aplikacji, która obejmuje podstawowy adres URL Microsoft Graph wraz z wersją Microsoft Graph i zakresami. W poniższym przykładzie określono zakres User.Read dla przykładów w dalszych sekcjach tego artykułu. Zakresy nie rozróżniają wielkości liter.
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "{VERSION}",
"Scopes": [
"user.read"
]
}
W poprzednim przykładzie symbol zastępczy {VERSION} to wersja interfejsu API Microsoft Graph (na przykład: v1.0).
Poniżej przedstawiono przykład kompletnego pliku konfiguracji wwwroot/appsettings.json dla aplikacji, która używa ME-ID jako dostawcy tożsamości, gdzie odczytywanie danych użytkownika (zakresuser.read) jest określone dla programu Microsoft Graph:
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/{TENANT ID}",
"ClientId": "{CLIENT ID}",
"ValidateAuthority": true
},
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "v1.0",
"Scopes": [
"user.read"
]
}
}
W poprzednim przykładzie symbol zastępczy {TENANT ID} to identyfikator katalogu (dzierżawy), a symbol zastępczy {CLIENT ID} to identyfikator aplikacji (klienta). Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Dodaj następującą GraphClientExtensions klasę do aplikacji autonomicznej. Zakresy są przekazywane do właściwości Scopes elementu AccessTokenRequestOptions w metodzie AuthenticateRequestAsync.
Dodaj następującą GraphClientExtensions klasę do autonomicznej aplikacji lub Client aplikacji hostowanego Blazor WebAssemblyrozwiązania. Zakresy są przekazywane do właściwości Scopes elementu AccessTokenRequestOptions w metodzie AuthenticateRequestAsync.
Jeśli nie uda się uzyskać tokenu dostępu, poniższy kod nie ustawi nagłówka autoryzacji Bearer dla żądań Graph.
GraphClientExtensions.cs:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.Authentication.WebAssembly.Msal.Models;
using Microsoft.Graph;
using Microsoft.Kiota.Abstractions;
using Microsoft.Kiota.Abstractions.Authentication;
using IAccessTokenProvider =
Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider;
namespace BlazorSample;
internal static class GraphClientExtensions
{
public static IServiceCollection AddGraphClient(
this IServiceCollection services, string? baseUrl, List<string>? scopes)
{
if (string.IsNullOrEmpty(baseUrl) || scopes?.Count == 0)
{
return services;
}
services.Configure<RemoteAuthenticationOptions<MsalProviderOptions>>(
options =>
{
scopes?.ForEach((scope) =>
{
options.ProviderOptions.DefaultAccessTokenScopes.Add(scope);
});
});
services.AddScoped<IAuthenticationProvider, GraphAuthenticationProvider>();
services.AddScoped(sp =>
{
return new GraphServiceClient(
new HttpClient(),
sp.GetRequiredService<IAuthenticationProvider>(),
baseUrl);
});
return services;
}
private class GraphAuthenticationProvider(IAccessTokenProvider tokenProvider,
IConfiguration config) : IAuthenticationProvider
{
private readonly IConfiguration config = config;
public IAccessTokenProvider TokenProvider { get; } = tokenProvider;
public async Task AuthenticateRequestAsync(RequestInformation request,
Dictionary<string, object>? additionalAuthenticationContext = null,
CancellationToken cancellationToken = default)
{
var result = await TokenProvider.RequestAccessToken(
new AccessTokenRequestOptions()
{
Scopes =
config.GetSection("MicrosoftGraph:Scopes").Get<string[]>() ??
[ "user.read" ]
});
if (result.TryGetToken(out var token))
{
request.Headers.Add("Authorization",
$"{CoreConstants.Headers.Bearer} {token.Value}");
}
}
}
}
Ważne
Zobacz sekcję DefaultAccessTokenScopes a AdditionalScopesToConsent, aby wyjaśnić, dlaczego powyższy kod używa do dodania zakresów zamiast .
W pliku Program dodaj usługi klienta Graph i konfigurację za pomocą metody rozszerzającej AddGraphClient. Poniższy kod domyślnie używa bazowego adresu Microsoft Graph w wersji 1.0 oraz zakresów User.Read, jeśli te ustawienia nie zostaną znalezione w pliku ustawień aplikacji:
var baseUrl = string.Join("/",
builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
.Get<List<string>>() ?? [ "user.read" ];
builder.Services.AddGraphClient(baseUrl, scopes);
Wywoływanie interfejsu API programu Graph ze składnika przy użyciu zestawu Graph SDK
Poniższy UserData komponent używa wstrzykniętego elementu GraphServiceClient, aby pobrać dane profilu ME-ID użytkownika i wyświetlić numer jego telefonu komórkowego.
W przypadku dowolnego użytkownika testowego utworzonego w obszarze ME-ID upewnij się, że w witrynie Azure Portal nadasz profilowi ME-ID użytkownika numer telefonu komórkowego.
UserData.razor:
@page "/user-data"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Graph
@attribute [Authorize]
@inject GraphServiceClient Client
<PageTitle>User Data</PageTitle>
<h1>Microsoft Graph User Data</h1>
@if (!string.IsNullOrEmpty(user?.MobilePhone))
{
<p>Mobile Phone: @user.MobilePhone</p>
}
@code {
private Microsoft.Graph.Models.User? user;
protected override async Task OnInitializedAsync()
{
user = await Client.Me.GetAsync();
}
}
Dodaj link do strony składnika w składniku NavMenu (Layout/NavMenu.razor):
<div class="nav-item px-3">
<NavLink class="nav-link" href="user-data">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User Data
</NavLink>
</div>
Wskazówka
Aby dodać użytkowników do aplikacji, zobacz sekcję Przypisywanie użytkowników do rejestracji aplikacji z rolami aplikacji lub bez niego .
Podczas testowania za pomocą zestawu Graph SDK lokalnie zalecamy użycie nowej sesji przeglądarki InPrivate/incognito dla każdego testu, aby zapobiec zakłócaniu testów utrzymujących się plików cookie. Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Dostosowywanie oświadczeń użytkowników przy użyciu zestawu Graph SDK
W poniższym przykładzie aplikacja tworzy oświadczenia dotyczące numeru telefonu komórkowego i lokalizacji biura dla użytkownika na podstawie danych profilu użytkownika ME-ID. Aplikacja musi mieć skonfigurowany w ME-ID zakres uprawnień interfejsu API Graph User.Read. Wszyscy użytkownicy testowi w tym scenariuszu muszą mieć numer telefonu komórkowego i lokalizację biura w profilu ME-ID, który można dodać za pośrednictwem witryny Azure Portal.
W następującej niestandardowej fabryce kont użytkowników:
- Element ILogger (
logger) jest dołączany dla wygody w przypadku, gdy chcesz rejestrować informacje lub błędy w metodzieCreateUserAsync. - W przypadku zgłoszenia AccessTokenNotAvailableException użytkownik jest przekierowywany do dostawcy tożsamości w celu zalogowania się na swoje konto. Dodatkowe lub różne akcje można wykonać w przypadku niepowodzenia żądania tokenu dostępu. Na przykład aplikacja może zarejestrować AccessTokenNotAvailableException i utworzyć zgłoszenie do działu pomocy technicznej w celu dalszej analizy.
- Element RemoteUserAccount frameworka reprezentuje konto użytkownika. Jeśli aplikacja wymaga niestandardowej klasy konta użytkownika, która dziedziczy po RemoteUserAccount, zamień niestandardową klasę konta użytkownika na RemoteUserAccount w poniższym kodzie.
CustomAccountFactory.cs:
using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;
using Microsoft.Kiota.Abstractions.Authentication;
public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IServiceProvider serviceProvider, ILogger<CustomAccountFactory> logger,
IConfiguration config)
: AccountClaimsPrincipalFactory<RemoteUserAccount>(accessor)
{
private readonly ILogger<CustomAccountFactory> logger = logger;
private readonly IServiceProvider serviceProvider = serviceProvider;
private readonly string? baseUrl = string.Join("/",
config.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
config.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
RemoteUserAccount account,
RemoteAuthenticationUserOptions options)
{
var initialUser = await base.CreateUserAsync(account, options);
if (initialUser.Identity is not null &&
initialUser.Identity.IsAuthenticated)
{
var userIdentity = initialUser.Identity as ClaimsIdentity;
if (userIdentity is not null && !string.IsNullOrEmpty(baseUrl))
{
try
{
var client = new GraphServiceClient(
new HttpClient(),
serviceProvider
.GetRequiredService<IAuthenticationProvider>(),
baseUrl);
var user = await client.Me.GetAsync();
if (user is not null)
{
userIdentity.AddClaim(new Claim("mobilephone",
user.MobilePhone ?? "(000) 000-0000"));
userIdentity.AddClaim(new Claim("officelocation",
user.OfficeLocation ?? "Not set"));
}
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
return initialUser;
}
}
Skonfiguruj uwierzytelnianie MSAL tak, aby używało niestandardowej fabryki kont użytkowników.
Upewnij się, że Program plik używa Microsoft.AspNetCore.Components.WebAssembly.Authentication przestrzeni nazw:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
Przykład w tej sekcji opiera się na podejściu polegającym na odczytywaniu bazowego adresu URL wraz z wersją i zakresami z konfiguracji aplikacji z sekcji MicrosoftGraph w pliku wwwroot/appsettings.json. Następujące wiersze powinny już znajdować się w Program pliku, postępując zgodnie ze wskazówkami zawartymi wcześniej w tym artykule:
var baseUrl = string.Join("/",
builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
.Get<List<string>>() ?? [ "user.read" ];
builder.Services.AddGraphClient(baseUrl, scopes);
W pliku Program znajdź wywołanie metody rozszerzającej AddMsalAuthentication. Zaktualizuj kod do następującej postaci, która zawiera wywołanie AddAccountClaimsPrincipalFactory, dodające fabrykę ClaimsPrincipal dla konta za pomocą CustomAccountFactory.
Jeśli aplikacja używa niestandardowej klasy konta użytkownika, która dziedziczy po RemoteUserAccount, zamień niestandardową klasę konta użytkownika na RemoteUserAccount w poniższym kodzie.
builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
RemoteUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd",
options.ProviderOptions.Authentication);
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount,
CustomAccountFactory>();
Możesz użyć następującego UserClaims składnika do zbadania oświadczeń użytkownika po uwierzytelnieniu użytkownika za pomocą me-ID:
UserClaims.razor:
@page "/user-claims"
@using System.Security.Claims
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>User Claims</h1>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
else
{
<p>No claims found.</p>
}
@code {
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
claims = user.Claims;
}
}
Dodaj link do strony składnika w składniku NavMenu (Layout/NavMenu.razor):
<div class="nav-item px-3">
<NavLink class="nav-link" href="user-claims">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User Claims
</NavLink>
</div>
Podczas testowania za pomocą zestawu Graph SDK lokalnie zalecamy użycie nowej sesji przeglądarki InPrivate/incognito dla każdego testu, aby zapobiec zakłócaniu testów utrzymujących się plików cookie. Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Poniższe wskazówki dotyczą programu Microsoft Graph w wersji 4. Jeśli uaktualniasz aplikację z zestawu SDK w wersji 4 do wersji 5 lub nowszej, zobacz następujące zasoby:
- Microsoft Graph .NET SDK v5 changelog and upgrade guide (Dziennik zmian i uaktualnianie zestawu SDK w wersji 5)
-
Wydania zestawu SDK Microsoft Graph .NET (
microsoftgraph/msgraph-sdk-dotnetrepozytorium GitHub) (zobacz uwagi dotyczące niezgodnych zmian w wersji 6.0.0)
Zestaw SDK Microsoft Graph używany w aplikacjach Blazor nosi nazwę biblioteka kliencka Microsoft Graph .NET.
Przykłady biblioteki Graph SDK wymagają następujących odwołań do pakietów w samodzielnej aplikacji Blazor WebAssembly. Odwołania do pierwszych dwóch pakietów są już dodane, jeśli aplikacja została skonfigurowana do uwierzytelniania za pomocą biblioteki MSAL, na przykład podczas tworzenia aplikacji zgodnie ze wskazówkami w artykule Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Microsoft Entra.
Przykłady użycia zestawu Graph SDK wymagają następujących odwołań do pakietów w autonomicznej aplikacji Blazor WebAssembly lub w aplikacji Client hostowanego rozwiązania Blazor WebAssembly. Do pierwszych dwóch pakietów istnieją już odwołania, jeśli aplikacja została skonfigurowana do uwierzytelniania za pomocą biblioteki MSAL, na przykład podczas tworzenia aplikacji zgodnie ze wskazówkami w artykule Zabezpiecz autonomiczną aplikację ASP.NET Core Blazor WebAssembly za pomocą Microsoft Entra ID.
Microsoft.AspNetCore.Components.WebAssembly.AuthenticationMicrosoft.Authentication.WebAssembly.MsalMicrosoft.Extensions.HttpMicrosoft.Graph
Uwaga
Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.
W witrynie Azure Portal przyznaj delegowane uprawnienia (zakresy)† dla danych programu Microsoft Graph, do których aplikacja powinna mieć dostęp w imieniu użytkownika. Na przykład w tym artykule rejestracja aplikacji powinna zawierać delegowane uprawnienia do odczytu danych użytkownika (Microsoft.Graph>User.Read zakres w uprawnieniach interfejsu API, Typ: Delegowane). Zakres User.Read umożliwia użytkownikom logowanie się do aplikacji i umożliwia aplikacji odczytywanie profilu i informacji firmowych zalogowanych użytkowników. Aby uzyskać więcej informacji, zobacz Omówienie uprawnień i zgody na platformie tożsamości Microsoft oraz Omówienie uprawnień Microsoft Graph.
†Uprawnienia i zakresy oznaczają to samo i są używane zamiennie w dokumentacji dotyczącej zabezpieczeń i w portalu Azure. O ile tekst nie odnosi się do portalu Azure, w tym artykule używa się terminów zakres/zakresy w odniesieniu do uprawnień Microsoft Graph.
Zakresy są niewrażliwe na wielkość liter, więc User.Read jest taka sama jak user.read. Możesz użyć dowolnego formatu, ale zalecamy spójny wybór w kodzie aplikacji.
Po dodaniu zakresów interfejsu API Microsoft Graph do rejestracji aplikacji w portalu Azure dodaj do pliku wwwroot/appsettings.json w aplikacji następującą konfigurację ustawień aplikacji, która obejmuje bazowy adres URL Microsoft Graph z wersją Microsoft Graph i zakresami. W poniższym przykładzie określono zakres User.Read dla przykładów przedstawionych w dalszych sekcjach tego artykułu. W zakresach wielkość liter nie ma znaczenia.
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "{VERSION}",
"Scopes": [
"user.read"
]
}
W poprzednim przykładzie symbol zastępczy {VERSION} oznacza wersję interfejsu API Microsoft Graph (na przykład: v1.0).
Poniżej przedstawiono przykład kompletnego pliku konfiguracji wwwroot/appsettings.json dla aplikacji, która używa ME-ID jako dostawcy tożsamości, gdzie odczytywanie danych użytkownika (zakresuser.read) jest określone dla programu Microsoft Graph:
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/{TENANT ID}",
"ClientId": "{CLIENT ID}",
"ValidateAuthority": true
},
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "v1.0",
"Scopes": [
"user.read"
]
}
}
W poprzednim przykładzie symbol zastępczy {TENANT ID} to identyfikator katalogu (dzierżawy), a symbol zastępczy {CLIENT ID} to identyfikator aplikacji (klienta). Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Dodaj następującą GraphClientExtensions klasę do aplikacji autonomicznej. Zakresy są przekazywane do właściwości Scopes obiektu AccessTokenRequestOptions w metodzie AuthenticateRequestAsync. Parametr IHttpProvider.OverallTimeout jest rozszerzony z wartości domyślnej 100 sekund do 300 sekund, aby dać HttpClient więcej czasu na odebranie odpowiedzi z programu Microsoft Graph.
Dodaj następującą GraphClientExtensions klasę do autonomicznej aplikacji lub Client aplikacji hostowanego Blazor WebAssemblyrozwiązania. Zakresy są przekazywane do właściwości Scopes elementu AccessTokenRequestOptions w metodzie AuthenticateRequestAsync. Parametr IHttpProvider.OverallTimeout jest rozszerzony z wartości domyślnej 100 sekund do 300 sekund, aby dać HttpClient więcej czasu na odebranie odpowiedzi z programu Microsoft Graph.
Jeśli nie uda się uzyskać tokenu dostępu, poniższy kod nie ustawia nagłówka autoryzacji Bearer dla żądań do interfejsu Graph.
GraphClientExtensions.cs:
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.Authentication.WebAssembly.Msal.Models;
using Microsoft.Graph;
namespace BlazorSample;
internal static class GraphClientExtensions
{
public static IServiceCollection AddGraphClient(
this IServiceCollection services, string? baseUrl, List<string>? scopes)
{
if (string.IsNullOrEmpty(baseUrl) || scopes?.Count == 0)
{
return services;
}
services.Configure<RemoteAuthenticationOptions<MsalProviderOptions>>(
options =>
{
scopes?.ForEach((scope) =>
{
options.ProviderOptions.DefaultAccessTokenScopes.Add(scope);
});
});
services.AddScoped<IAuthenticationProvider, GraphAuthenticationProvider>();
services.AddScoped<IHttpProvider, HttpClientHttpProvider>(sp =>
new HttpClientHttpProvider(new HttpClient()));
services.AddScoped(sp =>
{
return new GraphServiceClient(
baseUrl,
sp.GetRequiredService<IAuthenticationProvider>(),
sp.GetRequiredService<IHttpProvider>());
});
return services;
}
private class GraphAuthenticationProvider(IAccessTokenProvider tokenProvider,
IConfiguration config) : IAuthenticationProvider
{
private readonly IConfiguration config = config;
public IAccessTokenProvider TokenProvider { get; } = tokenProvider;
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
var result = await TokenProvider.RequestAccessToken(
new AccessTokenRequestOptions()
{
Scopes = config.GetSection("MicrosoftGraph:Scopes").Get<string[]>()
});
if (result.TryGetToken(out var token))
{
request.Headers.Authorization ??= new AuthenticationHeaderValue(
"Bearer", token.Value);
}
}
}
private class HttpClientHttpProvider(HttpClient client) : IHttpProvider
{
private readonly HttpClient client = client;
public ISerializer Serializer { get; } = new Serializer();
public TimeSpan OverallTimeout { get; set; } = TimeSpan.FromSeconds(300);
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
{
return client.SendAsync(request);
}
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
HttpCompletionOption completionOption,
CancellationToken cancellationToken)
{
return client.SendAsync(request, completionOption, cancellationToken);
}
public void Dispose()
{
}
}
}
Ważne
Zobacz sekcję DefaultAccessTokenScopes versus AdditionalScopesToConsent, aby dowiedzieć się, dlaczego poprzedni kod używa do dodawania zakresów zamiast .
W pliku Program dodaj usługi klienta Graph i konfigurację za pomocą metody rozszerzającej AddGraphClient:
var baseUrl = string.Join("/",
builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
.Get<List<string>>() ?? [ "user.read" ];
builder.Services.AddGraphClient(baseUrl, scopes);
Wywoływanie interfejsu API programu Graph ze składnika przy użyciu zestawu Graph SDK
Poniższy komponent UserData używa wstrzykniętego składnika GraphServiceClient, aby pobrać dane profilu ME-ID użytkownika i wyświetlić numer jego telefonu komórkowego. W przypadku dowolnego użytkownika testowego utworzonego w obszarze ME-ID upewnij się, że w witrynie Azure Portal nadasz profilowi ME-ID użytkownika numer telefonu komórkowego.
UserData.razor:
@page "/user-data"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Graph
@attribute [Authorize]
@inject GraphServiceClient Client
<PageTitle>User Data</PageTitle>
<h1>Microsoft Graph User Data</h1>
@if (!string.IsNullOrEmpty(user?.MobilePhone))
{
<p>Mobile Phone: @user.MobilePhone</p>
}
@code {
private Microsoft.Graph.User? user;
protected override async Task OnInitializedAsync()
{
var request = Client.Me.Request();
user = await request.GetAsync();
}
}
Dodaj link do strony składnika w składniku NavMenu (Layout/NavMenu.razor):
<div class="nav-item px-3">
<NavLink class="nav-link" href="user-data">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User Data
</NavLink>
</div>
Wskazówka
Aby dodać użytkowników do aplikacji, zobacz sekcję Przypisywanie użytkowników do rejestracji aplikacji z rolami aplikacji lub bez ról aplikacji.
Podczas testowania za pomocą zestawu Graph SDK lokalnie zalecamy użycie nowej sesji przeglądarki InPrivate/incognito dla każdego testu, aby zapobiec zakłócaniu testów utrzymujących się plików cookie. Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Dostosowywanie oświadczeń użytkowników przy użyciu zestawu Graph SDK
W poniższym przykładzie aplikacja tworzy oświadczenia dotyczące numeru telefonu komórkowego i lokalizacji biura dla użytkownika na podstawie danych profilu użytkownika ME-ID. Aplikacja musi mieć skonfigurowany w ME-ID zakres User.Read interfejs Graph API. Wszyscy użytkownicy testowi w tym scenariuszu muszą mieć numer telefonu komórkowego i lokalizację biura w profilu ME-ID, który można dodać za pośrednictwem witryny Azure Portal.
W następującej niestandardowej fabryce kont użytkowników:
- Element ILogger (
logger) jest dołączany dla wygody w przypadku, gdy chcesz rejestrować informacje lub błędy w metodzieCreateUserAsync. - W przypadku zgłoszenia AccessTokenNotAvailableException użytkownik jest przekierowywany do dostawcy tożsamości w celu zalogowania się na swoje konto. Dodatkowe lub różne akcje można wykonać w przypadku niepowodzenia żądania tokenu dostępu. Na przykład aplikacja może zarejestrować AccessTokenNotAvailableException i utworzyć zgłoszenie do działu wsparcia w celu dalszej analizy.
- Element RemoteUserAccount frameworka reprezentuje konto użytkownika. Jeśli aplikacja wymaga niestandardowej klasy konta użytkownika, która rozszerza klasę RemoteUserAccount, zamień niestandardową klasę konta użytkownika na RemoteUserAccount w poniższym kodzie.
CustomAccountFactory.cs:
using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;
public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IServiceProvider serviceProvider, ILogger<CustomAccountFactory> logger)
: AccountClaimsPrincipalFactory<RemoteUserAccount>(accessor)
{
private readonly ILogger<CustomAccountFactory> logger = logger;
private readonly IServiceProvider serviceProvider = serviceProvider;
public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
RemoteUserAccount account,
RemoteAuthenticationUserOptions options)
{
var initialUser = await base.CreateUserAsync(account, options);
if (initialUser.Identity is not null &&
initialUser.Identity.IsAuthenticated)
{
var userIdentity = initialUser.Identity as ClaimsIdentity;
if (userIdentity is not null)
{
try
{
var client = ActivatorUtilities
.CreateInstance<GraphServiceClient>(serviceProvider);
var request = client.Me.Request();
var user = await request.GetAsync();
if (user is not null)
{
userIdentity.AddClaim(new Claim("mobilephone",
user.MobilePhone ?? "(000) 000-0000"));
userIdentity.AddClaim(new Claim("officelocation",
user.OfficeLocation ?? "Not set"));
}
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
return initialUser;
}
}
Skonfiguruj uwierzytelnianie MSAL tak, aby używało niestandardowej fabryki konta użytkownika.
Upewnij się, że Program plik używa Microsoft.AspNetCore.Components.WebAssembly.Authentication przestrzeni nazw:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
Przykład w tej sekcji opiera się na podejściu polegającym na odczytywaniu z konfiguracji aplikacji bazowego adresu URL wraz z wersją i zakresami za pośrednictwem sekcji MicrosoftGraph w pliku wwwroot/appsettings.json. Następujące wiersze powinny już znajdować się w Program pliku, postępując zgodnie ze wskazówkami zawartymi wcześniej w tym artykule:
var baseUrl = string.Join("/",
builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
.Get<List<string>>() ?? [ "user.read" ];
builder.Services.AddGraphClient(baseUrl, scopes);
W pliku Program znajdź wywołanie metody rozszerzającej AddMsalAuthentication. Zaktualizuj kod do następującej postaci, która zawiera wywołanie AddAccountClaimsPrincipalFactory, dodające fabrykę obiektu ClaimsPrincipal dla konta przy użyciu CustomAccountFactory.
Jeśli aplikacja używa niestandardowej klasy konta użytkownika, która rozszerza RemoteUserAccount, zamień tę niestandardową klasę konta użytkownika na RemoteUserAccount w poniższym kodzie.
builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
RemoteUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd",
options.ProviderOptions.Authentication);
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount,
CustomAccountFactory>();
Możesz użyć następującego UserClaims składnika do zbadania oświadczeń użytkownika po uwierzytelnieniu użytkownika za pomocą me-ID:
UserClaims.razor:
@page "/user-claims"
@using System.Security.Claims
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>User Claims</h1>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
else
{
<p>No claims found.</p>
}
@code {
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
claims = user.Claims;
}
}
Dodaj link do strony składnika w składniku NavMenu (Layout/NavMenu.razor):
<div class="nav-item px-3">
<NavLink class="nav-link" href="user-claims">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User Claims
</NavLink>
</div>
Podczas testowania za pomocą zestawu Graph SDK lokalnie zalecamy użycie nowej sesji przeglądarki InPrivate/incognito dla każdego testu, aby zapobiec zakłócaniu testów utrzymujących się plików cookie. Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
W poniższych przykładach użyto nazwanego elementu HttpClient w wywołaniach interfejsu interfejs Graph API, aby uzyskać numer telefonu komórkowego użytkownika na potrzeby obsłużenia połączenia lub dostosować oświadczenia użytkownika tak, aby uwzględniały oświadczenie numeru telefonu komórkowego oraz oświadczenie lokalizacji biura.
Przykłady wymagają odwołania do pakietu Microsoft.Extensions.Http dla samodzielnej aplikacji Blazor WebAssembly.
Przykłady wymagają odwołania do pakietu dla Microsoft.Extensions.Http w autonomicznej aplikacji Blazor WebAssembly lub w aplikacji Client hostowanego rozwiązania Blazor WebAssembly.
Uwaga
Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.
W witrynie Azure Portal przyznaj delegowane uprawnienia (zakresy)† dla danych programu Microsoft Graph, do których aplikacja powinna mieć dostęp w imieniu użytkownika. Na przykład w tym artykule rejestracja aplikacji powinna zawierać delegowane uprawnienia do odczytu danych użytkownika (Microsoft.Graph>User.Read zakres w uprawnieniach interfejsu API, Typ: Delegowane). Zakres User.Read umożliwia użytkownikom logowanie się do aplikacji i umożliwia aplikacji odczytywanie profilu i informacji firmowych zalogowanych użytkowników. Aby uzyskać więcej informacji, zobacz Omówienie uprawnień i zgody na platformie tożsamości Microsoft oraz Omówienie uprawnień Microsoft Graph.
†Uprawnienia i zakresy oznaczają to samo i są używane zamiennie w dokumentacji dotyczącej zabezpieczeń i w portalu Azure. Jeśli tekst nie odnosi się do portalu Azure, w tym artykule używa się terminów zakres/zakresy w odniesieniu do uprawnień Graph.
Zakresy są niewrażliwe na wielkość liter, więc User.Read jest taka sama jak user.read. Możesz użyć dowolnego formatu, ale zalecamy spójny wybór w kodzie aplikacji.
Po dodaniu zakresów interfejsu API Microsoft Graph do rejestracji aplikacji w portalu Azure dodaj do pliku wwwroot/appsettings.json w aplikacji następującą konfigurację ustawień aplikacji, która obejmuje podstawowy adres URL usługi Graph z wersją Microsoft Graph oraz zakresy. W poniższym przykładzie określono zakres User.Read dla przykładów w dalszych sekcjach tego artykułu. Zakresy nie rozróżniają wielkości liter.
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "{VERSION}",
"Scopes": [
"user.read"
]
}
W poprzednim przykładzie symbol zastępczy {VERSION} oznacza wersję interfejsu API Microsoft Graph (na przykład: v1.0).
Poniżej przedstawiono przykład kompletnego pliku konfiguracji wwwroot/appsettings.json dla aplikacji, która używa ME-ID jako dostawcy tożsamości, gdzie odczytywanie danych użytkownika (zakresuser.read) jest określone dla programu Microsoft Graph:
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/{TENANT ID}",
"ClientId": "{CLIENT ID}",
"ValidateAuthority": true
},
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "v1.0",
"Scopes": [
"user.read"
]
}
}
W poprzednim przykładzie w miejscu symbolu zastępczego {TENANT ID} znajduje się identyfikator katalogu (dzierżawy), a w miejscu symbolu zastępczego {CLIENT ID} — identyfikator aplikacji (klienta). Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Utwórz następującą GraphAuthorizationMessageHandler klasę i konfigurację Program projektu w pliku na potrzeby pracy z interfejsem API programu Graph. Bazowy adres URL i zakresy są przekazywane do modułu obsługi z konfiguracji.
GraphAuthorizationMessageHandler.cs:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
namespace BlazorSample;
public class GraphAuthorizationMessageHandler : AuthorizationMessageHandler
{
public GraphAuthorizationMessageHandler(IAccessTokenProvider provider,
NavigationManager navigation, IConfiguration config)
: base(provider, navigation)
{
ConfigureHandler(
authorizedUrls: [
string.Join("/",
config.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
config.GetSection("MicrosoftGraph")["Version"] ??
"v1.0")
],
scopes: config.GetSection("MicrosoftGraph:Scopes")
.Get<List<string>>() ?? [ "user.read" ]);
}
}
Wymagany jest końcowy ukośnik (/) autoryzowanego adresu URL. Powyższy kod tworzy następujący autoryzacyjny adres URL na podstawie konfiguracji ustawień aplikacji lub używa następującego autoryzacyjnego adresu URL jako domyślnego, jeśli konfiguracja ustawień aplikacji nie istnieje: https://graph.microsoft.com/v1.0/.
W pliku Program skonfiguruj nazwany element HttpClient dla interfejsu API Graph:
builder.Services.AddTransient<GraphAuthorizationMessageHandler>();
builder.Services.AddHttpClient("GraphAPI",
client => client.BaseAddress = new Uri(
string.Join("/",
builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
"v1.0",
string.Empty)))
.AddHttpMessageHandler<GraphAuthorizationMessageHandler>();
W poprzednim przykładzie parametr GraphAuthorizationMessageHandlerDelegatingHandler jest zarejestrowany jako usługa przejściowa dla elementu AddHttpMessageHandler. Rejestracja typu transient jest zalecana dla IHttpClientFactory, który zarządza własnymi zakresami DI. Aby uzyskać więcej informacji, zobacz następujące zasoby:
- Pomocnicze klasy bazowe komponentów do zarządzania zakresem DI
- Wykrywanie tymczasowych obiektów jednorazowego użytku po stronie klienta
-
DelegatingHandlerInstancje
Wymagany jest ukośnik końcowy (/) na adresie podstawowym. W poprzednim kodzie trzecim argumentem do string.Join jest string.Empty, aby zapewnić obecność końcowego ukośnika: https://graph.microsoft.com/v1.0/.
Wywoływanie interfejsu API programu Graph ze składnika przy użyciu nazwanego elementu HttpClient
Klasa UserInfo.cs wyznacza wymagane właściwości profilu użytkownika z atrybutem JsonPropertyNameAttribute i nazwą JSON używaną przez me-ID. Poniższy przykład konfiguruje właściwości numeru telefonu komórkowego i lokalizacji biura użytkownika.
UserInfo.cs:
using System.Text.Json.Serialization;
namespace BlazorSample;
public class UserInfo
{
[JsonPropertyName("mobilePhone")]
public string? MobilePhone { get; set; }
[JsonPropertyName("officeLocation")]
public string? OfficeLocation { get; set; }
}
W poniższym komponencie UserData tworzony jest element HttpClient dla interfejsu API Graph, aby wysłać żądanie o dane profilu użytkownika. Zasób me (me) jest dodawany do podstawowego adresu URL z wersją żądania interfejsu API programu Graph. Dane JSON zwracane przez program Graph są deserializowane we właściwościach UserInfo klasy. W poniższym przykładzie otrzymany jest numer telefonu komórkowego. Możesz dodać podobny kod, aby uwzględnić lokalizację biura profilu ME-ID użytkownika, jeśli chcesz (userInfo.OfficeLocation). Jeśli żądanie tokenu dostępu zakończy się niepowodzeniem, użytkownik zostanie przekierowany w celu zalogowania się do aplikacji w celu uzyskania nowego tokenu dostępu.
UserData.razor:
@page "/user-data"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@attribute [Authorize]
@inject IConfiguration Config
@inject IHttpClientFactory ClientFactory
<PageTitle>User Data</PageTitle>
<h1>Microsoft Graph User Data</h1>
@if (!string.IsNullOrEmpty(userInfo?.MobilePhone))
{
<p>Mobile Phone: @userInfo.MobilePhone</p>
}
@code {
private UserInfo? userInfo;
protected override async Task OnInitializedAsync()
{
try
{
var client = ClientFactory.CreateClient("GraphAPI");
userInfo = await client.GetFromJsonAsync<UserInfo>("me");
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
Dodaj link do strony składnika w składniku NavMenu (Layout/NavMenu.razor):
<div class="nav-item px-3">
<NavLink class="nav-link" href="user-data">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User Data
</NavLink>
</div>
Wskazówka
Aby dodać użytkowników do aplikacji, zobacz sekcję Przypisywanie użytkowników do rejestracji aplikacji z rolami aplikacji lub bez ról aplikacji.
W poniższej sekwencji opisano nowy przepływ użytkownika dla zakresów interfejsu API programu Graph:
- Nowy użytkownik loguje się do aplikacji po raz pierwszy.
- Użytkownik wyraża zgodę na korzystanie z aplikacji w interfejsie użytkownika zgody platformy Azure.
- Użytkownik uzyskuje dostęp do strony składnika, która żąda danych interfejsu API programu Graph po raz pierwszy.
- Użytkownik jest przekierowywany do interfejsu użytkownika zgody platformy Azure, aby wyrazić zgodę na zakresy interfejsu API programu Graph.
- Zwracane są dane użytkownika interfejsu API programu Graph.
Jeśli wolisz, aby aprowizacja zakresów (wyrażenie zgody na zakresy interfejsu API Microsoft Graph) odbywała się podczas pierwszego logowania, przekaż zakresy do uwierzytelniania MSAL jako domyślne zakresy tokenu dostępu w pliku Program:
+ var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
+ .Get<List<string>>() ?? [ "user.read" ];
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
+ foreach (var scope in scopes)
+ {
+ options.ProviderOptions.DefaultAccessTokenScopes.Add(scope);
+ }
});
Ważne
Zobacz sekcję DefaultAccessTokenScopes a AdditionalScopesToConsent, aby dowiedzieć się, dlaczego poprzedni kod używa elementu do dodawania zakresów zamiast .
Po wprowadzeniu powyższych zmian w aplikacji przepływ użytkownika przyjmuje następującą sekwencję:
- Nowy użytkownik loguje się do aplikacji po raz pierwszy.
- Użytkownik wyraża zgodę na aplikację i zakresy uprawnień interfejs Graph API w interfejsie zgody platformy Azure.
- Użytkownik uzyskuje dostęp do strony składnika, która żąda danych interfejsu API programu Graph po raz pierwszy.
- Zwracane są dane użytkownika interfejsu API programu Graph.
Podczas testowania przy użyciu interfejsu API programu Graph lokalnie zalecamy użycie nowej sesji przeglądarki InPrivate/incognito dla każdego testu, aby zapobiec zakłócaniu testowania przez utrzymujące się pliki cookie. Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Dostosowywanie oświadczeń użytkownika za pomocą nazwanego HttpClient
W poniższym przykładzie aplikacja tworzy oświadczenia dotyczące numeru telefonu komórkowego i lokalizacji biura dla użytkownika na podstawie danych profilu użytkownika ME-ID. Aplikacja musi mieć skonfigurowany w ME-ID zakres User.Read interfejs Graph API. Testowe konta użytkowników w ME-ID wymagają podania numeru telefonu komórkowego i lokalizacji biura, które można dodać w ich profilach użytkowników za pośrednictwem portalu Azure.
Jeśli jeszcze nie dodano do aplikacji klasy UserInfo zgodnie ze wskazówkami podanymi wcześniej w tym artykule, dodaj następującą klasę i oznacz wymagane właściwości profilu użytkownika atrybutem JsonPropertyNameAttribute oraz nazwą JSON używaną przez ME-ID. Poniższy przykład konfiguruje właściwości numeru telefonu komórkowego i lokalizacji biura użytkownika.
UserInfo.cs:
using System.Text.Json.Serialization;
namespace BlazorSample;
public class UserInfo
{
[JsonPropertyName("mobilePhone")]
public string? MobilePhone { get; set; }
[JsonPropertyName("officeLocation")]
public string? OfficeLocation { get; set; }
}
W następującej niestandardowej fabryce kont użytkowników:
- Element ILogger (
logger) jest dołączany dla wygody w przypadku, gdy chcesz rejestrować informacje lub błędy w metodzieCreateUserAsync. - W przypadku zgłoszenia AccessTokenNotAvailableException użytkownik jest przekierowywany do dostawcy tożsamości w celu zalogowania się na swoje konto. Dodatkowe lub różne akcje można wykonać w przypadku niepowodzenia żądania tokenu dostępu. Na przykład aplikacja może zarejestrować AccessTokenNotAvailableException i utworzyć zgłoszenie do działu pomocy technicznej w celu dalszej analizy.
- Element RemoteUserAccount struktury reprezentuje konto użytkownika. Jeśli aplikacja wymaga niestandardowej klasy konta użytkownika, która dziedziczy po RemoteUserAccount, w poniższym kodzie użyj RemoteUserAccount zamiast niestandardowej klasy konta użytkownika.
CustomAccountFactory.cs:
using System.Net.Http.Json;
using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IHttpClientFactory clientFactory,
ILogger<CustomAccountFactory> logger)
: AccountClaimsPrincipalFactory<RemoteUserAccount>(accessor)
{
private readonly ILogger<CustomAccountFactory> logger = logger;
private readonly IHttpClientFactory clientFactory = clientFactory;
public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
RemoteUserAccount account,
RemoteAuthenticationUserOptions options)
{
var initialUser = await base.CreateUserAsync(account, options);
if (initialUser.Identity is not null &&
initialUser.Identity.IsAuthenticated)
{
var userIdentity = initialUser.Identity as ClaimsIdentity;
if (userIdentity is not null)
{
try
{
var client = clientFactory.CreateClient("GraphAPI");
var userInfo = await client.GetFromJsonAsync<UserInfo>("me");
if (userInfo is not null)
{
userIdentity.AddClaim(new Claim("mobilephone",
userInfo.MobilePhone ?? "(000) 000-0000"));
userIdentity.AddClaim(new Claim("officelocation",
userInfo.OfficeLocation ?? "Not set"));
}
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
return initialUser;
}
}
Uwierzytelnianie MSAL jest skonfigurowane tak, aby używało niestandardowej fabryki kont użytkowników. Zacznij od potwierdzenia, że Program plik używa Microsoft.AspNetCore.Components.WebAssembly.Authentication przestrzeni nazw:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
W pliku Program znajdź wywołanie metody rozszerzającej AddMsalAuthentication. Zaktualizuj kod do następującej postaci, która zawiera wywołanie AddAccountClaimsPrincipalFactory, dodające fabrykę ClaimsPrincipal dla konta za pomocą CustomAccountFactory.
Jeśli aplikacja używa niestandardowej klasy konta użytkownika, która dziedziczy po RemoteUserAccount, w poniższym kodzie zastąp niestandardową klasę konta użytkownika aplikacji elementem RemoteUserAccount.
builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
RemoteUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd",
options.ProviderOptions.Authentication);
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount,
CustomAccountFactory>();
Powyższy przykład dotyczy aplikacji korzystającej z uwierzytelniania ME-ID i biblioteki MSAL. Podobne wzorce istnieją dla uwierzytelniania OIDC i interfejsu API. Aby uzyskać więcej informacji, zobacz przykłady w sekcji Dostosowywanie użytkownika za pomocą oświadczenia w ładunku w artykule ASP.NET Core Blazor WebAssembly — dodatkowe scenariusze zabezpieczeń.
Możesz użyć następującego UserClaims składnika do zbadania oświadczeń użytkownika po uwierzytelnieniu użytkownika za pomocą me-ID:
UserClaims.razor:
@page "/user-claims"
@using System.Security.Claims
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>User Claims</h1>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
else
{
<p>No claims found.</p>
}
@code {
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
claims = user.Claims;
}
}
Dodaj link do strony składnika w składniku NavMenu (Layout/NavMenu.razor):
<div class="nav-item px-3">
<NavLink class="nav-link" href="user-claims">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User Claims
</NavLink>
</div>
Podczas testowania przy użyciu interfejsu API programu Graph lokalnie zalecamy użycie nowej sesji przeglądarki InPrivate/incognito dla każdego testu, aby zapobiec zakłócaniu testowania przez utrzymujące się pliki cookie. Aby uzyskać więcej informacji, zobacz Secure an ASP.NET Core standalone app with Microsoft Entra ID (Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly przy użyciu identyfikatora Entra firmy Microsoft).
Przypisywanie użytkowników do rejestracji aplikacji z rolami aplikacji lub bez nich
Możesz dodać użytkowników do rejestracji aplikacji i przypisać role do użytkowników, wykonując następujące kroki w witrynie Azure Portal.
Aby dodać użytkownika, wybierz pozycję Użytkownicy w obszarze ME-ID w witrynie Azure Portal:
- Wybierz pozycję Nowy użytkownik>Utwórz nowego użytkownika.
- Użyj szablonu Tworzenie użytkownika .
- Wprowadź dane użytkownika w obszarze Identity.
- Możesz wygenerować początkowe hasło lub przypisać początkowe hasło, które użytkownik zmieni podczas pierwszego logowania. Jeśli używasz hasła wygenerowanego przez portal, zanotuj je teraz.
- Wybierz pozycję Utwórz , aby utworzyć użytkownika. Po zamknięciu pozycji Utwórz nowy interfejs użytkownika wybierz pozycję Odśwież , aby zaktualizować listę użytkowników i wyświetlić nowego użytkownika.
- W przykładach w tym artykule przypisz numer telefonu komórkowego do nowego użytkownika, wybierając jego nazwę z listy użytkowników, wybierając pozycję Właściwości i edytując informacje kontaktowe, aby podać numer telefonu komórkowego.
Aby przypisać użytkowników do aplikacji bez ról aplikacji:
- W obszarze ME-ID w witrynie Azure Portal otwórz aplikacje dla przedsiębiorstw.
- Wybierz aplikację z listy.
- Wybierz pozycję Użytkownicy i grupy.
- Wybierz pozycję Dodaj użytkownika/grupę.
- Wybierz użytkownika.
- Wybierz przycisk Przypisz.
Aby przypisać użytkowników do aplikacji z rolami aplikacji:
- Dodaj role do rejestracji aplikacji w portalu Azure, zgodnie ze wskazówkami zawartymi w temacie ASP.NET Core Blazor WebAssembly z grupami i rolami Microsoft Entra ID.
- W obszarze ME-ID w witrynie Azure Portal otwórz aplikacje dla przedsiębiorstw.
- Wybierz aplikację z listy.
- Wybierz pozycję Użytkownicy i grupy.
- Wybierz pozycję Dodaj użytkownika/grupę.
- Wybierz użytkownika i wybierz swoją rolę w celu uzyskania dostępu do aplikacji. Do użytkownika przypisano wiele ról, powtarzając proces dodawania użytkownika do aplikacji do momentu przypisania wszystkich ról użytkownika. Użytkownicy z wieloma rolami są wyświetlani raz dla każdej przypisanej roli na liście Użytkownicy i grupy użytkowników dla aplikacji.
- Wybierz przycisk Przypisz.
DefaultAccessTokenScopes w porównaniu z AdditionalScopesToConsent
Przykłady w tym artykule nadają zakresy interfejsu API Graph za pomocą elementu DefaultAccessTokenScopes, a nie AdditionalScopesToConsent.
AdditionalScopesToConsent nie jest używana, ponieważ nie może aprowizować zakresów Microsoft interfejs Graph API dla użytkowników, gdy po raz pierwszy logują się oni do aplikacji za pomocą biblioteki MSAL w interfejsie zgody platformy Azure. Gdy użytkownik próbuje uzyskać dostęp do interfejsu API programu Graph po raz pierwszy przy użyciu zestawu Graph SDK, jest on skonfrontowany z wyjątkiem:
Microsoft.Graph.Models.ODataErrors.ODataError: Access token is empty.
Gdy użytkownik nada zakresy interfejs Graph API udostępniane za pośrednictwem DefaultAccessTokenScopes, aplikacja może użyć AdditionalScopesToConsent podczas kolejnego logowania użytkownika. Jednak zmiana kodu aplikacji nie ma sensu dla aplikacji produkcyjnej, która wymaga okresowego dodawania nowych użytkowników z delegowanymi zakresami programu Graph lub dodawania nowych delegowanych zakresów interfejsu API programu Graph do aplikacji.
Poprzednia dyskusja na temat aprowizacji zakresów dostępu do interfejsu API programu Graph, gdy użytkownik po raz pierwszy loguje się do aplikacji, ma zastosowanie tylko do:
- Aplikacje, które przyjmują zestaw GRAPH SDK.
- Aplikacje, które używają nazwanego HttpClient do uzyskiwania dostępu do interfejsu API Graph i proszą użytkowników o wyrażenie zgody na zakresy Graph przy pierwszym logowaniu do aplikacji.
Jeśli używasz nazwanego HttpClient, który nie prosi użytkowników o wyrażenie zgody na zakresy usługi Microsoft Graph podczas ich pierwszego logowania, użytkownicy są przekierowywani do interfejsu zgody platformy Azure na zakresy interfejsu API Microsoft Graph gdy po raz pierwszy żądają dostępu do interfejsu API Microsoft Graph za pośrednictwem DelegatingHandler wstępnie skonfigurowanego nazwanego HttpClient. Gdy początkowo nie wyrażono zgody na zakresy Graph przy użyciu podejścia HttpClient, ani DefaultAccessTokenScopes, ani AdditionalScopesToConsent nie są wywoływane przez aplikację. Aby uzyskać więcej informacji, zobacz nazwane HttpClient pokrycie w tym artykule.
Rozwiązania hostowane Blazor WebAssembly
Przykłady w tym artykule dotyczą używania zestawu Graph SDK lub nazwanego HttpClient interfejsu API programu Graph bezpośrednio z autonomicznej Blazor WebAssembly aplikacji lub bezpośrednio z Client aplikacji hostowanego Blazor WebAssemblyrozwiązania. Dodatkowym scenariuszem, który nie został omówiony w tym artykule, jest sytuacja, w której aplikacja Client rozwiązania hostowanego wywołuje aplikację Server rozwiązania za pomocą internetowego interfejsu API, a następnie aplikacja Server używa zestawu SDK/interfejsu API Graph do wywołania interfejsu Microsoft Graph i zwrócenia danych do aplikacji Client. Chociaż jest to obsługiwana metoda, nie została ona omówiona w tym artykule. Jeśli chcesz przyjąć to podejście:
- Postępuj zgodnie ze wskazówkami w artykule Wywoływanie internetowego interfejsu API z aplikacji ASP.NET Core Blazor w kwestiach związanych z wysyłaniem żądań do aplikacji Server z aplikacji Client oraz zwracaniem danych do aplikacji Client.
- Postępuj zgodnie ze wskazówkami w podstawowej dokumentacji programu Microsoft Graph, aby użyć zestawu SDK programu Graph z typową aplikacją ASP.NET Core, która w tym scenariuszu jest Server aplikacją rozwiązania. Jeśli używasz szablonu projektu Blazor WebAssembly do stworzenia hostowanego rozwiązania Blazor WebAssembly (ASP.NET Core Hosted/
-h|--hosted) z autoryzacją organizacyjną (pojedynczej organizacji/SingleOrglub wielu organizacji/MultiOrg) oraz opcją Microsoft Graph (platforma tożsamości Microsoft>Połączone Usługi>Dodaj uprawnienia Microsoft Graph w Visual Studio lub opcją--calls-graphza pomocą polecenia .NET CLIdotnet new), aplikacja Server związana z rozwiązaniem jest konfigurowana do używania Graph SDK, gdy rozwiązanie jest tworzone na podstawie szablonu projektu.
Dodatkowe zasoby
Wskazówki ogólne
- Dokumentacja programu Microsoft Graph
- Przykładowa Blazor WebAssembly aplikacja programu Microsoft Graph: w tym przykładzie pokazano, jak używać zestawu MICROSOFT Graph .NET SDK do uzyskiwania dostępu do danych w usłudze Office 365 z Blazor WebAssembly aplikacji.
- Tworzenie aplikacji .NET przy użyciu samouczka programu Microsoft Graph i przykładowej aplikacji Microsoft Graph ASP.NET Core: chociaż te zasoby nie mają bezpośredniego zastosowania do wywoływania programu Graph z aplikacji po stronieBlazor WebAssembly klienta, konfiguracja aplikacji ME-ID i praktyki kodowania programu Microsoft Graph w połączonych zasobach są istotne dla Blazor WebAssembly autonomicznych aplikacji i powinny być konsultowane z ogólnymi najlepszymi rozwiązaniami.
- Dokumentacja programu Microsoft Graph
- Przykładowa Blazor WebAssembly aplikacja programu Microsoft Graph: w tym przykładzie pokazano, jak używać zestawu MICROSOFT Graph .NET SDK do uzyskiwania dostępu do danych w usłudze Office 365 z Blazor WebAssembly aplikacji.
- Samouczek tworzenia aplikacji .NET za pomocą Microsoft Graph i przykładowa aplikacja ASP.NET Core dla Microsoft Graph: te zasoby są najbardziej odpowiednie dla hostowanychBlazor WebAssembly rozwiązań, w których aplikacja jest skonfigurowana do uzyskiwania dostępu do Microsoft Graph jako typowa aplikacja ASP.NET Core w imieniu aplikacji . Aplikacja Client używa internetowego interfejsu API do podejmowania żądań do Server aplikacji dla danych programu Graph. Chociaż te zasoby nie odnoszą się bezpośrednio do wywoływania Microsoft Graph z aplikacji po stronie klientaBlazor WebAssembly, konfiguracja aplikacji ME-ID i praktyki kodowania dla Microsoft Graph opisane w zasobach, do których prowadzą łącza, są istotne w przypadku autonomicznych Blazor WebAssembly aplikacji i warto się z nimi zapoznać, aby poznać ogólne najlepsze praktyki.
Wskazówki dotyczące bezpieczeństwa
- Omówienie uwierzytelniania programu Microsoft Graph
- Omówienie uprawnień programu Microsoft Graph
- Dokumentacja uprawnień usługi Microsoft Graph
- Omówienie uprawnień i zgody na platformie tożsamości firmy Microsoft
- Zwiększanie zabezpieczeń przy użyciu zasady najniższych uprawnień
- Artykuły dotyczące eskalacji uprawnień platformy Azure w Internecie (wynik wyszukiwania Google)
- Najlepsze rozwiązania dotyczące zabezpieczeń firmy Microsoft: Zabezpieczanie uprzywilejowanego dostępu