Sdílet prostřednictvím


Použití rozhraní Graph API s ASP.NET Core Blazor WebAssembly

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Tento článek vysvětluje, jak používat Microsoft Graph v Blazor WebAssembly aplikacích, což umožňuje aplikacím přístup k prostředkům Microsoft Cloud.

Existují dva přístupy:

  • Graph SDK: Sada Microsoft Graph SDK zjednodušuje vytváření vysoce kvalitních, efektivních a odolných aplikací, které přistupuje k Microsoft Graphu. Vyberte tlačítko Sady Graph SDK v horní části tohoto článku, abyste tento přístup přijali.

  • Pojmenovaný HttpClient s rozhraním Graph API: Pojmenovaný HttpClientmůže vydávat požadavky rozhraní Microsoft Graph API přímo do Microsoft Graphu. Pokud chcete tento přístup přijmout, vyberte v horní části tohoto článku tlačítko Pojmenovaný HttpClient s rozhraním Graph API.

Pokyny v tomto článku nejsou určené k nahrazení dokumentace k Microsoft Graphu a pokynů k zabezpečení Azure v jiných sadách dokumentace Microsoftu. Před implementací Microsoft Graphu v produkčním prostředí vyhodnoťte pokyny k zabezpečení v části Další zdroje informací v tomto článku. Pokud chcete omezit ohrožení zabezpečení vašich aplikací, postupujte podle osvědčených postupů Microsoftu.

Další přístupy pro práci s Microsoft Graphem a Blazor WebAssembly poskytují následující ukázky Microsoft Graphu a Azure:

Pokud chcete poskytnout zpětnou vazbu na některou z předchozích dvou ukázek, otevřete problém v úložišti GitHubu ukázky. Pokud otevíráte problém s ukázkou Azure, zadejte odkaz na ukázku v úvodním komentáři, protože ukázkové úložiště Azure (Azure-Samples) obsahuje mnoho ukázek. Podrobně popište problém a podle potřeby zahrňte vzorový kód. Umístěte do GitHubu minimální aplikaci, která reprodukuje problém nebo chybu. Před potvrzením do veřejného úložiště nezapomeňte z ukázky odebrat konfigurační data účtu Azure.

Pokud chcete poskytnout zpětnou vazbu nebo požádat o pomoc s tímto článkem nebo ASP.NET Core, přečtěte si základní informace o ASP.NET CoreBlazor.

Důležité

Scénáře popsané v tomto článku platí pro použití Microsoft Entra (ME-ID) jako identity poskytovatele, nikoli AAD B2C. Použití Microsoft Graphu s aplikací na straně Blazor WebAssembly klienta a poskytovatele AAD B2C identity se v tuto chvíli nepodporuje, protože aplikace by vyžadovala tajný klíč klienta, který není možné zabezpečit v aplikaci na straně Blazor klienta. Pro samostatnou Blazor WebAssembly aplikaci AAD B2C použijte rozhraní Graph API, vytvořte back-endové (webové) rozhraní API pro přístup k Rozhraní Graph API jménem uživatelů. Aplikace na straně klienta ověřuje a autorizuje uživatele, aby volali webové rozhraní API pro bezpečný přístup k Microsoft Graphu a vrátila data do aplikace na straně Blazor klienta z webového rozhraní API založeného na serveru. Tajný klíč klienta se bezpečně udržuje v serverovém webovém rozhraní API, ne v Blazor aplikaci na klientovi. Nikdy neukládejte tajný klíč klienta do aplikace na straně Blazor klienta.

Použití hostované Blazor WebAssembly aplikace se podporuje, kde Server aplikace pomocí sady Graph SDK nebo rozhraní API poskytuje aplikaci Graph data prostřednictvím webového Client rozhraní API. Další informace najdete v části Hostovaná Blazor WebAssembly řešení tohoto článku.

Příklady v tomto článku využívají nové funkce .NET/C#. Při použití příkladů s .NET 7 nebo staršími jsou vyžadovány menší úpravy. Příklady textu a kódu, které se týkají interakce s Microsoft Graphem, jsou ale stejné pro všechny verze ASP.NET Core.

Následující doprovodné materiály platí pro Microsoft Graph v5.

Sada Microsoft Graph SDK pro použití v Blazor aplikacích se nazývá klientská knihovna Microsoft Graph .NET.

Příklady sady Graph SDK vyžadují v samostatné Blazor WebAssembly aplikaci následující odkazy na balíčky. Na první dva balíčky se už odkazuje, pokud je aplikace povolená pro ověřování MSAL, například při vytváření aplikace podle pokynů v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly s Microsoft Entra ID.

Příklady sady Graph SDK vyžadují následující odkazy na balíčky v samostatné Blazor WebAssembly aplikaci nebo Client v aplikaci hostovaného Blazor WebAssembly řešení. Na první dva balíčky se už odkazuje, pokud je aplikace povolená pro ověřování MSAL, například při vytváření aplikace podle pokynů v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly s Microsoft Entra ID.

Poznámka:

Pokyny k přidávání balíčků do aplikací .NET najdete v článcích v části Instalace a správa balíčků na webu Pracovní postup používání balíčků (dokumentace k NuGetu). Ověřte správné verze balíčků na NuGet.org.

Na webu Azure Portal udělte delegovaná oprávnění (obory) † pro data Microsoft Graphu, ke kterým by měla mít aplikace přístup jménem uživatele. V příkladu v tomto článku by registrace aplikace měla obsahovat delegovaná oprávnění ke čtení uživatelských dat (Microsoft.Graph>User.Read obor v oprávněních rozhraní API, Typ: Delegováno). Rozsah User.Read umožňuje uživatelům přihlásit se k aplikaci a umožňuje aplikaci číst informace o profilu a společnosti přihlášených uživatelů. Další informace najdete v tématu Přehled oprávnění a souhlasu na platformě Microsoftu identity a přehled oprávnění Microsoft Graphu.

†Permissions a obory znamenají totéž a používají se zaměnitelně v dokumentaci k zabezpečení a na webu Azure Portal. Pokud text odkazuje na web Azure Portal, tento článek při odkazech na oprávnění Graphu používá obory oborů/.

Obory nerozlišují malá a velká písmena, takže User.Read jsou stejné jako user.read. Nebojte se použít některý z formátů, ale doporučujeme konzistentní volbu napříč kódem aplikace.

Po přidání rozsahů rozhraní Microsoft Graph API do registrace aplikace na webu Azure Portal přidejte do wwwroot/appsettings.json souboru v aplikaci následující konfiguraci nastavení aplikace, která zahrnuje základní adresu URL graphu s verzemi a obory Microsoft Graphu. V následujícím příkladu User.Read je obor určen pro příklady v pozdějších částech tohoto článku. Obory nerozlišují malá a velká písmena.

"MicrosoftGraph": {
  "BaseUrl": "https://graph.microsoft.com",
  "Version": "{VERSION}",
  "Scopes": [
    "user.read"
  ]
}

V předchozím příkladu {VERSION} je zástupný symbol verzí rozhraní Microsoft Graph API (například: v1.0).

Následuje příklad kompletního wwwroot/appsettings.json konfiguračního souboru pro aplikaci, která jako poskytovatele identity používá ME-ID, kde se pro Microsoft Graph zadává čtení uživatelských dat (user.read oboru):

{
  "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"
    ]
  }
}

V předchozím příkladu {TENANT ID} je zástupným symbolem ID adresáře (tenanta) a {CLIENT ID} zástupným symbolem je ID aplikace (klienta). Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Přidejte do samostatné aplikace následující GraphClientExtensions třídu. Obory jsou poskytovány vlastnosti Scopes AccessTokenRequestOptions v AuthenticateRequestAsync metodě.

Do samostatné aplikace nebo Client aplikace hostovaného Blazor WebAssemblyřešení přidejte následující GraphClientExtensions třídu. Obory jsou poskytovány vlastnosti Scopes AccessTokenRequestOptions v AuthenticateRequestAsync metodě.

Pokud se přístupový token nezískal, následující kód nenastaví autorizační hlavičku Nosné pro požadavky Graphu.

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}");
            }
        }
    }
}

Důležité

Vysvětlení, proč předchozí kód používá DefaultAccessTokenScopes k přidání oborů místo AdditionalScopesToConsent.DefaultAccessTokenScopes AdditionalScopesToConsent

Program Do souboru přidejte klientské služby Graphu a konfiguraci pomocí AddGraphClient metody rozšíření. Následující kód ve výchozím nastavení nastaví základní adresu a User.Read obory Microsoft Graphu verze 1.0, pokud tato nastavení nejsou v souboru nastavení aplikace nalezena:

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);

Volání rozhraní Graph API z komponenty pomocí sady Graph SDK

Následující UserData komponenta používá vložený GraphServiceClient kód k získání dat profilu ME-ID uživatele a zobrazení jeho mobilního telefonního čísla.

Pro každého testovacího uživatele, kterého vytvoříte v ME-ID, se ujistěte, že profil ME-ID uživatele zadáte na webu Azure Portal číslo mobilního telefonu.

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();
    }
}

Přidejte odkaz na stránku komponenty v komponentě 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>

Tip

Pokud chcete do aplikace přidat uživatele, přečtěte si část Přiřazení uživatelů k registraci aplikace s rolemi aplikace nebo bez této aplikace .

Při místním testování pomocí sady Graph SDK doporučujeme pro každý test použít novou relaci prohlížeče InPrivate nebo incognito, aby se zabránilo zasahování souborů cookie do souborů cookie. Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Přizpůsobení deklarací identity uživatelů pomocí sady Graph SDK

V následujícím příkladu aplikace vytvoří deklarace identity mobilního telefonu a polohy kanceláře pro uživatele z dat profilu uživatele s ME-ID. Aplikace musí mít User.Read nakonfigurovaný obor rozhraní Graph API v ME-ID. Všichni testovací uživatelé pro tento scénář musí mít v profilu ME-ID číslo mobilního telefonu a umístění kanceláře, které je možné přidat prostřednictvím webu Azure Portal.

V následující vlastní továrně uživatelských účtů:

  • Pro ILogger případ, že chcete protokolovat informace nebo chyby v CreateUserAsync metodě, je k dispozici (logger) pro usnadnění.
  • V případě, že AccessTokenNotAvailableException dojde k vyvolání, se uživatel přesměruje na identity poskytovatele, aby se přihlásil ke svému účtu. Pokud žádost o přístupový token selže, můžete provést další nebo jiné akce. Aplikace může například protokolovat AccessTokenNotAvailableException a vytvořit lístek podpory pro další šetření.
  • RemoteUserAccount Architektura představuje účet uživatele. Pokud aplikace vyžaduje vlastní třídu uživatelských účtů, která rozšiřuje RemoteUserAccount, prohoďte třídu vlastních uživatelských účtů pro RemoteUserAccount následující kód.

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;
    }
}

Nakonfigurujte ověřování MSAL tak, aby používalo vlastní objekt pro vytváření uživatelských účtů.

Ověřte, že Program soubor používá Microsoft.AspNetCore.Components.WebAssembly.Authentication obor názvů:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Příklad v této části vychází z přístupu ke čtení základní adresy URL s verzemi a obory z konfigurace aplikace prostřednictvím oddílu MicrosoftGraph v wwwroot/appsettings.json souboru. V souboru by již měly být uvedené Program následující řádky z následujících pokynů uvedených výše v tomto článku:

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);

Program V souboru vyhledejte volání metody příponyAddMsalAuthentication. Aktualizujte kód na následující kód, který zahrnuje volání AddAccountClaimsPrincipalFactory , které přidá objekt pro vytváření objektů zabezpečení deklarací identity účtu s objektem CustomAccountFactory.

Pokud aplikace používá vlastní třídu uživatelských účtů, která rozšiřuje RemoteUserAccount, prohodte třídu vlastního uživatelského účtu pro RemoteUserAccount následující kód.

builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
    RemoteUserAccount>(options =>
    {
        builder.Configuration.Bind("AzureAd", 
            options.ProviderOptions.Authentication);
    })
    .AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount,
        CustomAccountFactory>();

Následující komponentu UserClaims můžete použít ke zkoumání deklarací identity uživatele po ověření uživatele 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;
    }
}

Přidejte odkaz na stránku komponenty v komponentě 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>

Při místním testování pomocí sady Graph SDK doporučujeme pro každý test použít novou relaci prohlížeče InPrivate nebo incognito, aby se zabránilo zasahování souborů cookie do souborů cookie. Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Následující doprovodné materiály platí pro Microsoft Graph v4. Pokud upgradujete aplikaci ze sady SDK verze 4 na verzi 5, prohlédni si průvodce upgradem a protokolem změn sady Microsoft Graph .NET SDK v5.

Sada Microsoft Graph SDK pro použití v Blazor aplikacích se nazývá klientská knihovna Microsoft Graph .NET.

Příklady sady Graph SDK vyžadují v samostatné Blazor WebAssembly aplikaci následující odkazy na balíčky. Na první dva balíčky se už odkazuje, pokud je aplikace povolená pro ověřování MSAL, například při vytváření aplikace podle pokynů v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly s Microsoft Entra ID.

Příklady sady Graph SDK vyžadují následující odkazy na balíčky v samostatné Blazor WebAssembly aplikaci nebo Client v aplikaci hostovaného Blazor WebAssembly řešení. Na první dva balíčky se už odkazuje, pokud je aplikace povolená pro ověřování MSAL, například při vytváření aplikace podle pokynů v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly s Microsoft Entra ID.

Poznámka:

Pokyny k přidávání balíčků do aplikací .NET najdete v článcích v části Instalace a správa balíčků na webu Pracovní postup používání balíčků (dokumentace k NuGetu). Ověřte správné verze balíčků na NuGet.org.

Na webu Azure Portal udělte delegovaná oprávnění (obory) † pro data Microsoft Graphu, ke kterým by měla mít aplikace přístup jménem uživatele. V příkladu v tomto článku by registrace aplikace měla obsahovat delegovaná oprávnění ke čtení uživatelských dat (Microsoft.Graph>User.Read obor v oprávněních rozhraní API, Typ: Delegováno). Rozsah User.Read umožňuje uživatelům přihlásit se k aplikaci a umožňuje aplikaci číst informace o profilu a společnosti přihlášených uživatelů. Další informace najdete v tématu Přehled oprávnění a souhlasu na platformě Microsoftu identity a přehled oprávnění Microsoft Graphu.

†Permissions a obory znamenají totéž a používají se zaměnitelně v dokumentaci k zabezpečení a na webu Azure Portal. Pokud text odkazuje na web Azure Portal, tento článek při odkazech na oprávnění Graphu používá obory oborů/.

Obory nerozlišují malá a velká písmena, takže User.Read jsou stejné jako user.read. Nebojte se použít některý z formátů, ale doporučujeme konzistentní volbu napříč kódem aplikace.

Po přidání rozsahů rozhraní Microsoft Graph API do registrace aplikace na webu Azure Portal přidejte do wwwroot/appsettings.json souboru v aplikaci následující konfiguraci nastavení aplikace, která zahrnuje základní adresu URL graphu s verzemi a obory Microsoft Graphu. V následujícím příkladu User.Read je obor určen pro příklady v pozdějších částech tohoto článku. Obory nerozlišují malá a velká písmena.

"MicrosoftGraph": {
  "BaseUrl": "https://graph.microsoft.com",
  "Version": "{VERSION}",
  "Scopes": [
    "user.read"
  ]
}

V předchozím příkladu {VERSION} je zástupný symbol verzí rozhraní Microsoft Graph API (například: v1.0).

Následuje příklad kompletního wwwroot/appsettings.json konfiguračního souboru pro aplikaci, která jako poskytovatele identity používá ME-ID, kde se pro Microsoft Graph zadává čtení uživatelských dat (user.read oboru):

{
  "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"
    ]
  }
}

V předchozím příkladu {TENANT ID} je zástupným symbolem ID adresáře (tenanta) a {CLIENT ID} zástupným symbolem je ID aplikace (klienta). Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Přidejte do samostatné aplikace následující GraphClientExtensions třídu. Obory jsou poskytovány vlastnosti Scopes AccessTokenRequestOptions v AuthenticateRequestAsync metodě. Prodlužuje IHttpProvider.OverallTimeout se z výchozí hodnoty 100 sekund na 300 sekund, abyste získali HttpClient více času na přijetí odpovědi z Microsoft Graphu.

Do samostatné aplikace nebo Client aplikace hostovaného Blazor WebAssemblyřešení přidejte následující GraphClientExtensions třídu. Obory jsou poskytovány vlastnosti Scopes AccessTokenRequestOptions v AuthenticateRequestAsync metodě. Prodlužuje IHttpProvider.OverallTimeout se z výchozí hodnoty 100 sekund na 300 sekund, abyste získali HttpClient více času na přijetí odpovědi z Microsoft Graphu.

Pokud se přístupový token nezískal, následující kód nenastaví autorizační hlavičku Nosné pro požadavky Graphu.

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()
        {
        }
    }
}

Důležité

Vysvětlení, proč předchozí kód používá DefaultAccessTokenScopes k přidání oborů místo AdditionalScopesToConsent.DefaultAccessTokenScopes AdditionalScopesToConsent

Program Do souboru přidejte klientské služby Graphu a konfiguraci pomocí AddGraphClient metody rozšíření:

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);

Volání rozhraní Graph API z komponenty pomocí sady Graph SDK

Následující UserData komponenta používá vložený GraphServiceClient kód k získání dat profilu ME-ID uživatele a zobrazení jeho mobilního telefonního čísla. Pro každého testovacího uživatele, kterého vytvoříte v ME-ID, se ujistěte, že profil ME-ID uživatele zadáte na webu Azure Portal číslo mobilního telefonu.

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();
    }
}

Přidejte odkaz na stránku komponenty v komponentě 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>

Tip

Pokud chcete do aplikace přidat uživatele, přečtěte si část Přiřazení uživatelů k registraci aplikace s rolemi aplikace nebo bez této aplikace .

Při místním testování pomocí sady Graph SDK doporučujeme pro každý test použít novou relaci prohlížeče InPrivate nebo incognito, aby se zabránilo zasahování souborů cookie do souborů cookie. Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Přizpůsobení deklarací identity uživatelů pomocí sady Graph SDK

V následujícím příkladu aplikace vytvoří deklarace identity mobilního telefonu a polohy kanceláře pro uživatele z dat profilu uživatele s ME-ID. Aplikace musí mít User.Read nakonfigurovaný obor rozhraní Graph API v ME-ID. Všichni testovací uživatelé pro tento scénář musí mít v profilu ME-ID číslo mobilního telefonu a umístění kanceláře, které je možné přidat prostřednictvím webu Azure Portal.

V následující vlastní továrně uživatelských účtů:

  • Pro ILogger případ, že chcete protokolovat informace nebo chyby v CreateUserAsync metodě, je k dispozici (logger) pro usnadnění.
  • V případě, že AccessTokenNotAvailableException dojde k vyvolání, se uživatel přesměruje na identity poskytovatele, aby se přihlásil ke svému účtu. Pokud žádost o přístupový token selže, můžete provést další nebo jiné akce. Aplikace může například protokolovat AccessTokenNotAvailableException a vytvořit lístek podpory pro další šetření.
  • RemoteUserAccount Architektura představuje účet uživatele. Pokud aplikace vyžaduje vlastní třídu uživatelských účtů, která rozšiřuje RemoteUserAccount, prohoďte třídu vlastních uživatelských účtů pro RemoteUserAccount následující kód.

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;
    }
}

Nakonfigurujte ověřování MSAL tak, aby používalo vlastní objekt pro vytváření uživatelských účtů.

Ověřte, že Program soubor používá Microsoft.AspNetCore.Components.WebAssembly.Authentication obor názvů:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Příklad v této části vychází z přístupu ke čtení základní adresy URL s verzemi a obory z konfigurace aplikace prostřednictvím oddílu MicrosoftGraph v wwwroot/appsettings.json souboru. V souboru by již měly být uvedené Program následující řádky z následujících pokynů uvedených výše v tomto článku:

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);

Program V souboru vyhledejte volání metody příponyAddMsalAuthentication. Aktualizujte kód na následující kód, který zahrnuje volání AddAccountClaimsPrincipalFactory , které přidá objekt pro vytváření objektů zabezpečení deklarací identity účtu s objektem CustomAccountFactory.

Pokud aplikace používá vlastní třídu uživatelských účtů, která rozšiřuje RemoteUserAccount, prohodte třídu vlastního uživatelského účtu pro RemoteUserAccount následující kód.

builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
    RemoteUserAccount>(options =>
    {
        builder.Configuration.Bind("AzureAd", 
            options.ProviderOptions.Authentication);
    })
    .AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount,
        CustomAccountFactory>();

Následující komponentu UserClaims můžete použít ke zkoumání deklarací identity uživatele po ověření uživatele 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;
    }
}

Přidejte odkaz na stránku komponenty v komponentě 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>

Při místním testování pomocí sady Graph SDK doporučujeme pro každý test použít novou relaci prohlížeče InPrivate nebo incognito, aby se zabránilo zasahování souborů cookie do souborů cookie. Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Následující příklady používají pojmenované HttpClient volání rozhraní Graph API k získání čísla mobilního telefonu uživatele ke zpracování hovoru nebo přizpůsobení deklarací identity uživatele tak, aby zahrnovaly deklaraci identity mobilního telefonního čísla a deklaraci polohy kanceláře.

Příklady vyžadují odkaz na balíček pro Microsoft.Extensions.Http samostatnou Blazor WebAssembly aplikaci.

Příklady vyžadují odkaz na balíček pro Microsoft.Extensions.Http samostatnou Blazor WebAssembly aplikaci nebo Client aplikaci hostovaného Blazor WebAssembly řešení.

Poznámka:

Pokyny k přidávání balíčků do aplikací .NET najdete v článcích v části Instalace a správa balíčků na webu Pracovní postup používání balíčků (dokumentace k NuGetu). Ověřte správné verze balíčků na NuGet.org.

Na webu Azure Portal udělte delegovaná oprávnění (obory) † pro data Microsoft Graphu, ke kterým by měla mít aplikace přístup jménem uživatele. V příkladu v tomto článku by registrace aplikace měla obsahovat delegovaná oprávnění ke čtení uživatelských dat (Microsoft.Graph>User.Read obor v oprávněních rozhraní API, Typ: Delegováno). Rozsah User.Read umožňuje uživatelům přihlásit se k aplikaci a umožňuje aplikaci číst informace o profilu a společnosti přihlášených uživatelů. Další informace najdete v tématu Přehled oprávnění a souhlasu na platformě Microsoftu identity a přehled oprávnění Microsoft Graphu.

†Permissions a obory znamenají totéž a používají se zaměnitelně v dokumentaci k zabezpečení a na webu Azure Portal. Pokud text odkazuje na web Azure Portal, tento článek při odkazech na oprávnění Graphu používá obory oborů/.

Obory nerozlišují malá a velká písmena, takže User.Read jsou stejné jako user.read. Nebojte se použít některý z formátů, ale doporučujeme konzistentní volbu napříč kódem aplikace.

Po přidání rozsahů rozhraní Microsoft Graph API do registrace aplikace na webu Azure Portal přidejte do wwwroot/appsettings.json souboru v aplikaci následující konfiguraci nastavení aplikace, která zahrnuje základní adresu URL graphu s verzemi a obory Microsoft Graphu. V následujícím příkladu User.Read je obor určen pro příklady v pozdějších částech tohoto článku. Obory nerozlišují malá a velká písmena.

"MicrosoftGraph": {
  "BaseUrl": "https://graph.microsoft.com",
  "Version": "{VERSION}",
  "Scopes": [
    "user.read"
  ]
}

V předchozím příkladu {VERSION} je zástupný symbol verzí rozhraní Microsoft Graph API (například: v1.0).

Následuje příklad kompletního wwwroot/appsettings.json konfiguračního souboru pro aplikaci, která jako poskytovatele identity používá ME-ID, kde se pro Microsoft Graph zadává čtení uživatelských dat (user.read oboru):

{
  "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"
    ]
  }
}

V předchozím příkladu {TENANT ID} je zástupným symbolem ID adresáře (tenanta) a {CLIENT ID} zástupným symbolem je ID aplikace (klienta). Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Vytvořte v Program souboru následující GraphAuthorizationMessageHandler konfiguraci třídy a projektu pro práci s rozhraním Graph API. Základní adresa URL a obory jsou poskytovány obslužné rutině z konfigurace.

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" ]);
    }
}

Vyžaduje se koncové lomítko (/) autorizované adresy URL. Předchozí kód sestaví následující autorizovanou adresu URL z konfigurace nastavení aplikace nebo výchozí hodnotu na následující autorizovanou adresu URL, pokud chybí konfigurace nastavení aplikace: https://graph.microsoft.com/v1.0/.

Program V souboru nakonfigurujte pojmenované HttpClient rozhraní Graph API:

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>();

V předchozím příkladu GraphAuthorizationMessageHandler DelegatingHandler je registrován jako přechodná služba pro AddHttpMessageHandler. Přechodná registrace se doporučuje pro IHttpClientFactory, která spravuje vlastní obory DI. Další informace naleznete v následujících zdrojích:

Vyžaduje se koncové lomítko (/) na základní adrese. Třetím argumentem string.Join v předchozím kódu je string.Empty zajistit, aby koncové lomítko bylo přítomno: https://graph.microsoft.com/v1.0/.

Volání rozhraní Graph API z komponenty pomocí pojmenovaného HttpClient

Třída UserInfo.cs určuje požadované vlastnosti profilu uživatele s atributem JsonPropertyNameAttribute a názvem JSON používaným ME-ID. Následující příklad nastaví vlastnosti pro mobilní telefonní číslo uživatele a umístění kanceláře.

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; }
}

V následující UserData komponentě se vytvoří rozhraní Graph API k HttpClient vydání požadavku na data profilu uživatele. Prostředek me (me) se přidá do základní adresy URL s verzí požadavku rozhraní Graph API. Data JSON vrácená Graphem se deserializují do UserInfo vlastností třídy. V následujícím příkladu se získá číslo mobilního telefonu. Podobný kód můžete přidat tak, aby zahrnoval umístění kanceláře profilu ME-ID uživatele, pokud chcete (userInfo.OfficeLocation). Pokud žádost o přístupový token selže, uživatel se přesměruje, aby se přihlásil k aplikaci pro nový přístupový token.

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();
        }
    }
}

Přidejte odkaz na stránku komponenty v komponentě 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>

Tip

Pokud chcete do aplikace přidat uživatele, přečtěte si část Přiřazení uživatelů k registraci aplikace s rolemi aplikace nebo bez této aplikace .

Následující posloupnost popisuje nový tok uživatele pro obory rozhraní Graph API:

  1. Nový uživatel se poprvé přihlásí k aplikaci.
  2. Uživatel souhlasí s používáním aplikace v uživatelském rozhraní souhlasu Azure.
  3. Uživatel přistupuje ke stránce komponenty, která poprvé požaduje data rozhraní Graph API.
  4. Uživatel se přesměruje do uživatelského rozhraní azure pro vyjádření souhlasu s obory rozhraní Graph API.
  5. Vrátí se uživatelská data rozhraní Graph API.

Pokud dáváte přednost tomu, aby zřizování oboru (souhlas pro obory rozhraní Graph API) proběhlo při počátečním přihlášení, zadejte obory ověřování MSAL jako výchozí obory přístupového tokenu Program v souboru:

+ 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);
+   }
});

Důležité

Vysvětlení, proč předchozí kód používá DefaultAccessTokenScopes k přidání oborů místo AdditionalScopesToConsent.DefaultAccessTokenScopes AdditionalScopesToConsent

Když se v aplikaci provede předchozí změny, tok uživatele přijme následující posloupnost:

  1. Nový uživatel se poprvé přihlásí k aplikaci.
  2. Uživatel souhlasí s používáním rozsahů aplikace a rozhraní Graph API v uživatelském rozhraní pro vyjádření souhlasu Azure.
  3. Uživatel přistupuje ke stránce komponenty, která poprvé požaduje data rozhraní Graph API.
  4. Vrátí se uživatelská data rozhraní Graph API.

Při místním testování pomocí rozhraní Graph API doporučujeme pro každý test použít novou relaci prohlížeče InPrivate nebo incognito, aby se zabránilo tomu, že se do testování zasahují soubory cookie. Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Přizpůsobení deklarací identity uživatelů pomocí pojmenovaného HttpClient

V následujícím příkladu aplikace vytvoří deklarace identity mobilního telefonu a polohy kanceláře pro uživatele z dat profilu uživatele s ME-ID. Aplikace musí mít User.Read nakonfigurovaný obor rozhraní Graph API v ME-ID. Testovací uživatelské účty v ME-ID vyžadují zadání pro číslo mobilního telefonu a umístění kanceláře, které je možné přidat prostřednictvím webu Azure Portal do profilů uživatelů.

Pokud jste ještě nepřidali UserInfo třídu do aplikace podle pokynů uvedených výše v tomto článku, přidejte následující třídu a určete požadované vlastnosti profilu uživatele s atributem JsonPropertyNameAttribute a názvem JSON používaným ME-ID. Následující příklad nastaví vlastnosti pro mobilní telefonní číslo uživatele a umístění kanceláře.

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; }
}

V následující vlastní továrně uživatelských účtů:

  • Pro ILogger případ, že chcete protokolovat informace nebo chyby v CreateUserAsync metodě, je k dispozici (logger) pro usnadnění.
  • V případě, že AccessTokenNotAvailableException dojde k vyvolání, se uživatel přesměruje na identity poskytovatele, aby se přihlásil ke svému účtu. Pokud žádost o přístupový token selže, můžete provést další nebo jiné akce. Aplikace může například protokolovat AccessTokenNotAvailableException a vytvořit lístek podpory pro další šetření.
  • RemoteUserAccount Architektura představuje účet uživatele. Pokud aplikace vyžaduje vlastní třídu uživatelských účtů, která rozšiřuje RemoteUserAccount, prohodte třídu vlastních uživatelských účtů pro RemoteUserAccount následující kód.

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;
    }
}

Ověřování MSAL je nakonfigurováno tak, aby používalo vlastní objekt pro vytváření uživatelských účtů. Začněte potvrzením, že Program soubor používá Microsoft.AspNetCore.Components.WebAssembly.Authentication obor názvů:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Program V souboru vyhledejte volání metody příponyAddMsalAuthentication. Aktualizujte kód na následující kód, který zahrnuje volání AddAccountClaimsPrincipalFactory , které přidá objekt pro vytváření objektů zabezpečení deklarací identity účtu s objektem CustomAccountFactory.

Pokud aplikace používá vlastní třídu uživatelských účtů, která rozšiřuje RemoteUserAccount, prohoďte vlastní třídu uživatelských účtů vaší aplikace za RemoteUserAccount následující kód.

builder.Services.AddMsalAuthentication<RemoteAuthenticationState, 
    RemoteUserAccount>(options =>
    {
        builder.Configuration.Bind("AzureAd", 
            options.ProviderOptions.Authentication);
    })
    .AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount, 
        CustomAccountFactory>();

Předchozí příklad je určená pro aplikaci, která používá ověřování ME-ID se službou MSAL. Podobné vzory existují pro ověřování OIDC a rozhraní API. Další informace najdete v příkladech v části Přizpůsobení uživatele s deklarací identity datové části článku o dalších scénářích zabezpečení ASP.NET CoreBlazor WebAssembly.

Následující komponentu UserClaims můžete použít ke zkoumání deklarací identity uživatele po ověření uživatele 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;
    }
}

Přidejte odkaz na stránku komponenty v komponentě 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>

Při místním testování pomocí rozhraní Graph API doporučujeme pro každý test použít novou relaci prohlížeče InPrivate nebo incognito, aby se zabránilo tomu, že se do testování zasahují soubory cookie. Další informace najdete v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí Microsoft Entra ID.

Přiřazení uživatelů k registraci aplikace s rolemi aplikace nebo bez

Uživatele můžete přidat do registrace aplikace a přiřadit jim role pomocí následujícího postupu na webu Azure Portal.

Pokud chcete přidat uživatele, vyberte v oblasti ME-ID webu Azure Portal:

  1. Vyberte Nový uživatel>Vytvořit nového uživatele.
  2. Použijte šablonu Vytvořit uživatele.
  3. Zadejte informace o uživateli v Identity oblasti.
  4. Můžete vygenerovat počáteční heslo nebo přiřadit počáteční heslo, které uživatel změní při prvním přihlášení. Pokud používáte heslo vygenerované portálem, poznamenejte si ho.
  5. Vyberte Vytvořit a vytvořte uživatele. Když se okno Vytvořit nové uživatelské rozhraní zavře, vyberte Aktualizovat , aby se aktualizoval seznam uživatelů, a zobrazte nového uživatele.
  6. V příkladech v tomto článku přiřaďte novému uživateli číslo mobilního telefonu tak, že vyberete jeho jméno ze seznamu uživatelů, vyberete Vlastnosti a upravíte kontaktní údaje tak, aby poskytovaly číslo mobilního telefonu.

Přiřazení uživatelů k aplikaci bez rolí aplikace:

  1. V oblasti ME-ID webu Azure Portal otevřete podnikové aplikace.
  2. Vyberte aplikaci ze seznamu.
  3. Vyberte Uživatelé a skupiny.
  4. Vyberte Přidat uživatele nebo skupinu.
  5. Zvolte uživatele.
  6. Vyberte tlačítko Přiřadit.

Přiřazení uživatelů k aplikaci pomocí rolí aplikací:

  1. Přidejte role do registrace aplikace na webu Azure Portal podle pokynů v ASP.NET Core Blazor WebAssembly se skupinami a rolemi ID Microsoft Entra.
  2. V oblasti ME-ID webu Azure Portal otevřete podnikové aplikace.
  3. Vyberte aplikaci ze seznamu.
  4. Vyberte Uživatelé a skupiny.
  5. Vyberte Přidat uživatele nebo skupinu.
  6. Vyberte uživatele a vyberte jeho roli pro přístup k aplikaci. Uživateli se přiřadí více rolí opakováním procesu přidání uživatele do aplikace, dokud nebudou přiřazeny všechny role pro uživatele. Uživatelé s více rolemi jsou uvedeni jednou pro každou přiřazenou roli v seznamu uživatelů a skupin pro aplikaci.
  7. Vyberte tlačítko Přiřadit.

DefaultAccessTokenScopes versus AdditionalScopesToConsent

Příklady v tomto článku zřizují obory rozhraní Graph API, DefaultAccessTokenScopesnikoli AdditionalScopesToConsent.

AdditionalScopesToConsent se nepoužívá, protože není možné zřídit obory rozhraní Graph API pro uživatele při prvním přihlášení k aplikaci pomocí KNIHOVNY MSAL prostřednictvím uživatelského rozhraní pro vyjádření souhlasu Azure. Když se uživatel poprvé pokusí o přístup k rozhraní Graph API pomocí sady Graph SDK, bude konfrontován s výjimkou:

Microsoft.Graph.Models.ODataErrors.ODataError: Access token is empty.

Jakmile uživatel zřídí rozsahy rozhraní Graph API poskytnuté prostřednictvím DefaultAccessTokenScopes, může aplikace použít AdditionalScopesToConsent pro následné přihlášení uživatele. Změna kódu aplikace ale nemá smysl pro produkční aplikaci, která do aplikace vyžaduje pravidelné přidávání nových uživatelů s delegovanými obory Graphu nebo přidávání nových delegovaných oborů rozhraní Graph API.

Předchozí diskuze o tom, jak zřídit obory pro přístup k rozhraní Graph API, když se uživatel poprvé přihlásí k aplikaci, platí jenom pro:

  • Aplikace, které přijímají sadu Graph SDK.
  • Aplikace, které používají pojmenovaný HttpClient přístup k rozhraní Graph API, které uživatele vyzve k vyjádření souhlasu s obory Graphu při prvním přihlášení k aplikaci.

Při použití pojmenovaného HttpClient , který uživatele požádá o souhlas s rozsahy Graphu při prvním přihlášení, se uživatelé přesměrují na souhlas uživatelského rozhraní Azure pro obory Graph API při prvním vyžádání přístupu k rozhraní Graph API prostřednictvím DelegatingHandler předkonfigurovaného s názvem HttpClient. Pokud obory Graphu nejsou na začátku s pojmenovaným HttpClient přístupem odsouhlaseny, aplikace ani AdditionalScopesToConsent DefaultAccessTokenScopes je nevolá. Další informace najdete v pojmenovaném HttpClient pokrytí v tomto článku.

Hostovaná Blazor WebAssembly řešení

Příklady v tomto článku se týkají použití sady Graph SDK nebo pojmenovaného HttpClient rozhraní Graph API přímo ze samostatné Blazor WebAssembly aplikace nebo přímo z Client aplikace hostovaného Blazor WebAssemblyřešení. Dalším scénářem, který není popsaný v tomto článku, je Client aplikace hostovaného řešení, která volá Server aplikaci řešení prostřednictvím webového rozhraní API, a pak Server aplikace používá sadu Graph SDK/API k volání Microsoft Graphu a vrácení dat do Client aplikace. I když se jedná o podporovaný přístup, tento článek se na něj nevztahuje. Pokud chcete tento přístup přijmout:

  • Postupujte podle pokynů v části Volání webového rozhraní API z aplikace ASP.NET Core Blazor pro aspekty webového rozhraní API při vydávání požadavků na Server aplikaci z Client aplikace a vracení dat do Client aplikace.
  • Postupujte podle pokynů v primární dokumentaci k Microsoft Graphu a použijte sadu Graph SDK s typickou aplikací ASP.NET Core, což je Server v tomto scénáři aplikace řešení. Pokud použijete Blazor WebAssembly šablonu projektu k vytvoření hostovaného Blazor WebAssembly řešení (ASP.NET Core Hostované/-h|--hosted) s autorizací organizace (jedna organizace neboSingleOrg více organizací/MultiOrg) a možností Microsoft Graphu (Microsoft identity Platform>Connected Services>Add Microsoft Graph v sadě Visual Studio nebo --calls-graph možnost pomocí příkazu .NET CLI),Server dotnet new aplikace řešení je nakonfigurovaná tak, aby při vytváření řešení ze šablony projektu používala sadu Graph SDK.

Další materiály

Obecné pokyny

  • Dokumentace k Microsoft Graphu
  • Ukázková Blazor WebAssembly aplikace Microsoft Graphu: Tato ukázka ukazuje, jak používat sadu Microsoft Graph .NET SDK pro přístup k datům v Office 365 z Blazor WebAssembly aplikací.
  • Vytvářejte aplikace .NET pomocí kurzu k Microsoft Graphu a ukázkové aplikace Microsoft Graph ASP.NET Core: I když se tyto prostředky přímo nevztahují na volání Graphu z aplikací na straněBlazor WebAssembly klienta, konfigurace aplikace ME-ID a postupy kódování Microsoft Graphu v propojených prostředcích jsou relevantní pro samostatné Blazor WebAssembly aplikace a měly by se poradit s obecnými osvědčenými postupy.
  • Dokumentace k Microsoft Graphu
  • Ukázková Blazor WebAssembly aplikace Microsoft Graphu: Tato ukázka ukazuje, jak používat sadu Microsoft Graph .NET SDK pro přístup k datům v Office 365 z Blazor WebAssembly aplikací.
  • Vytvářejte aplikace .NET pomocí kurzu k Microsoft Graphu a ukázkové aplikace Microsoft Graph ASP.NET Core: Tyto prostředky jsou nejvhodnější pro hostovanáBlazor WebAssembly řešení, kde Server je aplikace nakonfigurovaná tak, aby přistupovala k Microsoft Graphu jako typická aplikace ASP.NET Core jménem Client aplikace. Aplikace Client používá webové rozhraní API k odesílání požadavků do Server aplikace pro data Graphu. I když se tyto prostředky přímo nevztahují na volání Graphu z aplikací na straněBlazor WebAssembly klienta, konfigurace aplikací ME-ID a postupy kódování Microsoft Graphu v propojených prostředcích jsou relevantní pro samostatné Blazor WebAssembly aplikace a měly by se poradit s obecnými osvědčenými postupy.

Doprovodné materiály k zabezpečení