Grupy Microsoft Entra (ME-ID), role Administracja istratora i role aplikacji

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

W tym artykule wyjaśniono, jak skonfigurować używanie Blazor WebAssembly grup i ról identyfikatorów firmy Microsoft.

Firma Microsoft Entra (ME-ID) udostępnia kilka metod autoryzacji, które można połączyć z ASP.NET Core Identity:

  • Grupy
    • Zabezpieczenia
    • Microsoft 365
    • Dystrybucja
  • Ról
    • Role Administracja istratora ME-ID
    • Role aplikacji

Wskazówki przedstawione w tym artykule dotyczą Blazor WebAssembly scenariuszy wdrażania identyfikatora ME opisanego w następujących tematach:

Wskazówki zawarte w artykule zawierają instrukcje dotyczące aplikacji klienckich i serwerowych:

  • KLIENT: Aplikacje autonomiczne Blazor WebAssembly .
  • SERWER: ASP.NET Core server API/web API apps. Wskazówki dotyczące serwera można zignorować w całym artykule dotyczącym aplikacji autonomicznejBlazor WebAssembly.
  • KLIENT: aplikacje autonomiczne Blazor WebAssembly lub Client aplikacja hostowanego Blazorrozwiązania.
  • SERWER: ASP.NET Core server API/web API apps lub Server aplikacji hostowanego Blazor rozwiązania. Wskazówki dotyczące serwera można zignorować w całym artykule dotyczącym aplikacji autonomicznejBlazor WebAssembly.

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 identyfikatorem ME-ID i programem Microsoft Graph są takie same dla wszystkich wersji platformy ASP.NET Core.

Warunek wstępny

Wskazówki zawarte w tym artykule implementują interfejs API programu Microsoft Graph zgodnie ze wskazówkami dotyczącymi zestawu Graph SDK w temacie Używanie interfejsu API programu Graph z ASP.NET Core Blazor WebAssembly. Postępuj zgodnie ze wskazówkami dotyczącymi implementacji zestawu Graph SDK , aby skonfigurować aplikację i przetestować ją, aby potwierdzić, że aplikacja może uzyskać dane interfejsu API programu Graph dla konta użytkownika testowego. Ponadto zapoznaj się z artykułem dotyczącym zabezpieczeń interfejsu API programu Graph, aby zapoznać się z pojęciami dotyczącymi zabezpieczeń programu Microsoft Graph.

Podczas testowania przy użyciu zestawu Graph SDK lokalnie zalecamy użycie nowej sesji przeglądarki w trybie prywatnym/incognito dla każdego testu, aby zapobiec zakłócaniu cookietestów. 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).

Zakresy

Aby zezwolić na wywołania interfejsu API programu Microsoft Graph dla danych dotyczących profilu użytkownika, przypisania roli i członkostwa w grupach:

  • Aplikacja KLIENCKA jest skonfigurowana z zakresem delegowanymUser.Read () w witrynie Azure Portal, ponieważ dostęp do odczytu danych użytkownika jest określany przez zakresy przyznane (https://graph.microsoft.com/User.Readdelegowane) poszczególnym użytkownikom.
  • Aplikacja SERWER jest skonfigurowana z zakresem aplikacjiGroupMember.Read.All () (https://graph.microsoft.com/GroupMember.Read.All) w witrynie Azure Portal, ponieważ dostęp jest przeznaczony dla aplikacji w celu uzyskania informacji o członkostwie w grupie, a nie na podstawie indywidualnej autoryzacji użytkownika w celu uzyskania dostępu do danych dotyczących członków grupy.

Powyższe zakresy są wymagane oprócz zakresów wymaganych w scenariuszach wdrażania identyfikatora ME opisanych wcześniej w tematach wymienionych wcześniej (autonomiczna z kontami Microsoft lub autonomiczna ze stanem ME-ID).

Powyższe zakresy są wymagane oprócz zakresów wymaganych w scenariuszach wdrażania identyfikatora ME opisanych wcześniej w tematach wymienionych wcześniej (autonomiczna z kontami Microsoft, autonomiczna z identyfikatorem ME i hostowana przy użyciu identyfikatora ME).

Aby uzyskać więcej informacji, zobacz Omówienie uprawnień i zgody w Platforma tożsamości Microsoft i Omówienie uprawnień programu Microsoft Graph.

Uwaga

Słowa "permission" i "scope" są używane zamiennie w witrynie Azure Portal i w różnych zestawach dokumentacji firmy Microsoft i zewnętrznych. W tym artykule użyto słowa "zakres" dla uprawnień przypisanych do aplikacji w witrynie Azure Portal.

Atrybut Oświadczenia członkostwa w grupie

W manifeście aplikacji w witrynie Azure Portal dla aplikacji KLIENT i SERWER ustaw groupMembershipClaims atrybut na All. Wartość All wyników w identyfikatorze ME-ID wysyła wszystkie grupy zabezpieczeń, grupy dystrybucyjne i role zalogowanego użytkownika w dobrze znanym oświadczeniu identyfikatorów (wids):

  1. Otwórz rejestrację witryny Azure Portal aplikacji.
  2. Wybierz pozycję Zarządzaj>manifestem na pasku bocznym.
  3. groupMembershipClaims Znajdź atrybut .
  4. Ustaw wartość na All ("groupMembershipClaims": "All").
  5. Wybierz przycisk Zapisz, jeśli wprowadzono zmiany.

Niestandardowe konto użytkownika

Przypisz użytkowników do grup zabezpieczeń ME-ID i ról Administracja istratora ME-ID w witrynie Azure Portal.

Przykłady w tym artykule:

  • Załóżmy, że użytkownik jest przypisany do roli Administracja istratora rozliczeń me-ID w dzierżawie ME-ID witryny Azure Portal w celu uzyskania autoryzacji w celu uzyskania dostępu do danych interfejsu API serwera.
  • Użyj zasad autoryzacji, aby kontrolować dostęp w aplikacjach KLIENT i SERWER .

W aplikacji CLIENT rozszerz rozszerzenie RemoteUserAccount , aby uwzględnić właściwości dla:

CustomUserAccount.cs:

using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

namespace BlazorSample;

public class CustomUserAccount : RemoteUserAccount
{
    [JsonPropertyName("roles")]
    public List<string>? Roles { get; set; }

    [JsonPropertyName("wids")]
    public List<string>? Wids { get; set; }

    [JsonPropertyName("oid")]
    public string? Oid { get; set; }
}

Dodaj odwołanie do pakietu do aplikacji KLIENCKIej dla programu Microsoft.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.

Dodaj klasy narzędzi zestawu Graph SDK i konfigurację w wskazówki dotyczące zestawu Graph SDK artykułu Use Graph API with ASP.NET Core (Korzystanie z interfejsu API programu Graph z platformą ASP.NET Core Blazor WebAssembly ). User.Read Określ zakres tokenu dostępu, jak pokazano w przykładowym wwwroot/appsettings.json pliku artykułu.

Dodaj następującą niestandardową fabrykę kont użytkowników do aplikacji CLIENT . Niestandardowa fabryka użytkowników służy do ustanawiania:

  • Oświadczenia roli aplikacji () (appRoleopisane w sekcji Role aplikacji).
  • Oświadczenia roli Administracja istratora ME-ID (directoryRole).
  • Przykładowe oświadczenia dotyczące danych profilu użytkownika dla numeru telefonu komórkowego użytkownika (mobilePhone) i lokalizacji biura (officeLocation).
  • Oświadczenia grupy ME-ID (directoryGroup).
  • logger(ILogger) dla wygody, jeśli chcesz rejestrować informacje lub błędy.

CustomAccountFactory.cs:

W poniższym przykładzie przyjęto założenie, że plik ustawień aplikacji projektu zawiera wpis dla podstawowego adresu URL:

{
  "MicrosoftGraph": {
    "BaseUrl": "https://graph.microsoft.com/{VERSION}",
    ...
  }
}

W poprzednim przykładzie {VERSION} symbol zastępczy jest wersją interfejsu API programu MS Graph (na przykład: v1.0).

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;

namespace BlazorSample;

public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger,
        IConfiguration config)
    : AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
    private readonly ILogger<CustomAccountFactory> logger = logger;
    private readonly IServiceProvider serviceProvider = serviceProvider;
    private readonly string? baseUrl = 
        config.GetSection("MicrosoftGraph")["BaseUrl"];

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        CustomUserAccount 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))
            {
                account?.Roles?.ForEach((role) =>
                {
                    userIdentity.AddClaim(new Claim("appRole", role));
                });

                account?.Wids?.ForEach((wid) =>
                {
                    userIdentity.AddClaim(new Claim("directoryRole", wid));
                });

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

                    var requestMemberOf = client.Users[account?.Oid].MemberOf;
                    var memberships = await requestMemberOf.Request().GetAsync();

                    if (memberships is not null)
                    {
                        foreach (var entry in memberships)
                        {
                            if (entry.ODataType == "#microsoft.graph.group")
                            {
                                userIdentity.AddClaim(
                                    new Claim("directoryGroup", entry.Id));
                            }
                        }
                    }
                }
                catch (AccessTokenNotAvailableException exception)
                {
                    exception.Redirect();
                }
            }
        }

        return initialUser;
    }
}
using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;

namespace BlazorSample;

public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger)
    : AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
    private readonly ILogger<CustomAccountFactory> logger = logger;
    private readonly IServiceProvider serviceProvider = serviceProvider;

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        CustomUserAccount 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)
            {
                account?.Roles?.ForEach((role) =>
                {
                    userIdentity.AddClaim(new Claim("appRole", role));
                });

                account?.Wids?.ForEach((wid) =>
                {
                    userIdentity.AddClaim(new Claim("directoryRole", wid));
                });

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

                    var requestMemberOf = client.Users[account?.Oid].MemberOf;
                    var memberships = await requestMemberOf.Request().GetAsync();

                    if (memberships is not null)
                    {
                        foreach (var entry in memberships)
                        {
                            if (entry.ODataType == "#microsoft.graph.group")
                            {
                                userIdentity.AddClaim(
                                    new Claim("directoryGroup", entry.Id));
                            }
                        }
                    }
                }
                catch (AccessTokenNotAvailableException exception)
                {
                    exception.Redirect();
                }
            }
        }

        return initialUser;
    }
}

Powyższy kod nie zawiera przejściowych członkostw. Jeśli aplikacja wymaga bezpośrednich i przechodnich oświadczeń członkostwa w grupie, zastąp MemberOf właściwość () wartością TransitiveMemberOf (IUserMemberOfCollectionWithReferencesRequestBuilderIUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).

Powyższy kod ignoruje oświadczenia członkostwa w grupie (groups), które są identyfikatorem ME-ID Administracja istrator Roles (#microsoft.graph.directoryRoletype), ponieważ wartości identyfikatorów GUID zwracane przez Platforma tożsamości Microsoft są identyfikatorami jednostek ME-ID Administracja istratora, a nie identyfikatorami jednostek szablonu roli. Identyfikatory jednostek nie są stabilne w dzierżawach w Platforma tożsamości Microsoft i nie powinny być używane do tworzenia zasad autoryzacji dla użytkowników w aplikacjach. Zawsze używaj identyfikatorów szablonów ról dla ról identyfikatora ME-ID Administracja istratora udostępnianych przez wids oświadczenia.

W aplikacji CLIENT 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;

Zaktualizuj wywołanie AddMsalAuthentication do następującego. Należy pamiętać, że Blazor struktura RemoteUserAccount jest zastępowana przez aplikacje CustomUserAccount dla uwierzytelniania MSAL i głównej fabryki oświadczeń kont:

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

Upewnij się, że obecność kodu zestawu Graph SDK opisanego w artykule Use Graph API with ASP.NET Core (Korzystanie z interfejsu API programu Graph z platformą ASP.NET CoreBlazor WebAssembly) i że wwwroot/appsettings.json konfiguracja jest poprawna zgodnie ze wskazówkami dotyczącymi zestawu Graph SDK:

var baseUrl = string.Join("/", 
    builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"], 
    builder.Configuration.GetSection("MicrosoftGraph")["Version"]);
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
    .Get<List<string>>();

builder.Services.AddGraphClient(baseUrl, scopes);

wwwroot/appsettings.json:

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

Konfiguracja autoryzacji

W aplikacji CLIENT utwórz zasady dla każdej roli aplikacji, identyfikatora ME-ID Administracja istrator roli lub grupy zabezpieczeń w Program pliku. Poniższy przykład tworzy zasady dla roli Administracja istratora rozliczeń ME-ID:

builder.Services.AddAuthorizationCore(options =>
{
    options.AddPolicy("BillingAdministrator", policy => 
        policy.RequireClaim("directoryRole", 
            "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});

Aby uzyskać pełną listę identyfikatorów ról Administracja istratora identyfikatorów ME-ID, zobacz Identyfikatory szablonów ról w dokumentacji entra. Aby uzyskać więcej informacji na temat zasad autoryzacji, zobacz Autoryzacja oparta na zasadach w programie ASP.NET Core.

W poniższych przykładach aplikacja CLIENT używa powyższych zasad do autoryzowania użytkownika.

Składnik AuthorizeView działa z zasadami:

<AuthorizeView Policy="BillingAdministrator">
    <Authorized>
        <p>
            The user is in the 'Billing Administrator' ME-ID Administrator Role
            and can see this content.
        </p>
    </Authorized>
    <NotAuthorized>
        <p>
            The user is NOT in the 'Billing Administrator' role and sees this
            content.
        </p>
    </NotAuthorized>
</AuthorizeView>

Dostęp do całego składnika może być oparty na zasadach przy użyciu [Authorize] dyrektywy atrybutu (AuthorizeAttribute):

@page "/"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "BillingAdministrator")]

Jeśli użytkownik nie jest autoryzowany, nastąpi przekierowanie do strony logowania ME-ID.

Sprawdzanie zasad można również wykonać w kodzie za pomocą logiki proceduralnej.

CheckPolicy.razor:

@page "/checkpolicy"
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

<h1>Check Policy</h1>

<p>This component checks a policy in code.</p>

<button @onclick="CheckPolicy">Check 'BillingAdministrator' policy</button>

<p>Policy Message: @policyMessage</p>

@code {
    private string policyMessage = "Check hasn't been made yet.";

    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    private async Task CheckPolicy()
    {
        var user = (await authenticationStateTask).User;

        if ((await AuthorizationService.AuthorizeAsync(user, 
            "BillingAdministrator")).Succeeded)
        {
            policyMessage = "Yes! The 'BillingAdministrator' policy is met.";
        }
        else
        {
            policyMessage = "No! 'BillingAdministrator' policy is NOT met.";
        }
    }
}

Autoryzowanie dostępu do interfejsu API serwera/internetowego interfejsu API

Aplikacja interfejsu API SERWERA może autoryzować użytkowników do uzyskiwania dostępu do bezpiecznych punktów końcowych interfejsu API przy użyciu zasad autoryzacji dla grup zabezpieczeń, ról Administracja istratora ME-ID i ról aplikacji, gdy token dostępu zawiera groupswids, i role oświadczenia. W poniższym przykładzie utworzono zasady dla roli Administracja istratora rozliczeń identyfikatorów ME-ID w Program pliku przy użyciu wids oświadczeń (dobrze znanych identyfikatorów/identyfikatorów szablonów ról):

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("BillingAdministrator", policy => 
        policy.RequireClaim("wids", "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});

Aby uzyskać pełną listę identyfikatorów ról Administracja istratora identyfikatorów ME-ID, zobacz Identyfikatory szablonów ról w dokumentacji platformy Azure. Aby uzyskać więcej informacji na temat zasad autoryzacji, zobacz Autoryzacja oparta na zasadach w programie ASP.NET Core.

Dostęp do kontrolera w aplikacji SERWERA może opierać się na użyciu [Authorize] atrybutu o nazwie zasad (dokumentacja interfejsu API: AuthorizeAttribute).

Poniższy przykład ogranicza dostęp do danych rozliczeniowych z BillingDataController obszaru do Administracja istratorów rozliczeń platformy Azure o nazwie BillingAdministratorzasad :

using Microsoft.AspNetCore.Authorization;
[Authorize(Policy = "BillingAdministrator")]
[ApiController]
[Route("[controller]")]
public class BillingDataController : ControllerBase
{
    ...
}

Aby uzyskać więcej informacji, zobacz Autoryzacja na podstawie zasad na platformie ASP.NET Core.

Role aplikacji

Aby skonfigurować aplikację w witrynie Azure Portal w celu zapewnienia oświadczeń członkostwa w rolach aplikacji, zobacz Dodawanie ról aplikacji do aplikacji i odbieranie ich w tokenie w dokumentacji usługi Entra.

W poniższym przykładzie przyjęto założenie, że aplikacje KLIENT i SERWER są skonfigurowane z dwiema rolami, a role są przypisywane do użytkownika testowego:

  • Admin
  • Developer

Uwaga

Podczas tworzenia pary klient-serwer autonomicznych aplikacji ( Blazor WebAssembly autonomicznej aplikacji i ASP.NET aplikacji interfejsu API serwera podstawowego/aplikacji interfejsu API serwera podstawowego/aplikacji interfejsu API sieci Web) appRoles właściwość manifestu zarówno klienta, jak i serwera rejestracji aplikacji w witrynie Azure Portal musi zawierać te same skonfigurowane role. Po ustanowieniu ról w manifeście aplikacji klienckiej skopiuj je w całości do manifestu aplikacji serwera. Jeśli nie dublujesz manifestu appRoles między rejestracją klienta i aplikacji serwera, oświadczenia ról nie są ustanawiane dla uwierzytelnionych użytkowników interfejsu API serwera/internetowego interfejsu API, nawet jeśli ich token dostępu zawiera poprawne wpisy w role oświadczeniach.

Uwaga

Podczas tworzenia aplikacji hostowanej Blazor WebAssembly lub pary aplikacji autonomicznych (aplikacji autonomicznej Blazor WebAssembly i aplikacji interfejsu API/internetowego interfejsu API serwera ASP.NET Core) appRoles właściwość manifestu zarówno klienta, jak i serwera rejestracji aplikacji witryny Azure Portal musi zawierać te same skonfigurowane role. Po ustanowieniu ról w manifeście aplikacji klienckiej skopiuj je w całości do manifestu aplikacji serwera. Jeśli nie dublujesz manifestu appRoles między rejestracją klienta i aplikacji serwera, oświadczenia ról nie są ustanawiane dla uwierzytelnionych użytkowników interfejsu API serwera/internetowego interfejsu API, nawet jeśli ich token dostępu zawiera poprawne wpisy w role oświadczeniach.

Chociaż nie można przypisywać ról do grup bez konta Microsoft Entra ID Premium, możesz przypisać role do użytkowników i otrzymać role oświadczenie dla użytkowników ze standardowym kontem platformy Azure. Wskazówki w tej sekcji nie wymagają konta Premium z identyfikatorem ME.ID.

Jeśli masz konto platformy Azure w warstwie Premium, na pasku bocznym rejestracji aplikacji w witrynie Azure Portal zostanie wyświetlona opcja Zarządzanie>rolami aplikacji. Postępuj zgodnie ze wskazówkami w artykule Dodawanie ról aplikacji do aplikacji i odbieranie ich w tokenie w celu skonfigurowania ról aplikacji.

Jeśli nie masz konta platformy Azure w warstwie Premium, edytuj manifest aplikacji w witrynie Azure Portal. Postępuj zgodnie ze wskazówkami w temacie Role aplikacji: Implementacja w celu ręcznego ustanowienia ról aplikacji we wpisie appRoles pliku manifestu. Zapisz zmiany w pliku.

Poniżej znajduje się przykładowy appRoles wpis, który tworzy Admin role i Developer . Te przykładowe role są używane w dalszej części tego przykładu na poziomie składnika w celu zaimplementowania ograniczeń dostępu:

"appRoles": [
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Administrators manage developers.",
    "displayName": "Admin",
    "id": "584e483a-7101-404b-9bb1-83bf9463e335",
    "isEnabled": true,
    "lang": null,
    "origin": "Application",
    "value": "Admin"
  },
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Developers write code.",
    "displayName": "Developer",
    "id": "82770d35-2a93-4182-b3f5-3d7bfe9dfe46",
    "isEnabled": true,
    "lang": null,
    "origin": "Application",
    "value": "Developer"
  }
],

Uwaga

Identyfikatory GUID można wygenerować za pomocą programu generatora identyfikatora GUID online (wynik wyszukiwania Google dla "generatora identyfikatora GUID").

Aby przypisać rolę do użytkownika (lub grupy, jeśli masz konto platformy Azure w warstwie Premium):

  1. Przejdź do pozycji Aplikacje dla przedsiębiorstw w obszarze ME-ID witryny Azure Portal.
  2. Wybierz aplikację. Wybierz pozycję Zarządzaj użytkownikami i grupami> na pasku bocznym.
  3. Zaznacz pole wyboru dla co najmniej jednego konta użytkownika.
  4. Z menu powyżej listy użytkowników wybierz pozycję Edytuj przypisanie.
  5. W polu Wybierz wpis roli wybierz pozycję Brak.
  6. Wybierz rolę z listy i wybierz ją za pomocą przycisku Wybierz .
  7. Użyj przycisku Przypisz w dolnej części ekranu, aby przypisać rolę.

Wiele ról jest przypisywanych w witrynie Azure Portal przez ponowne dodanie użytkownika dla każdego dodatkowego przypisania roli. Użyj przycisku Dodaj użytkownika/grupę w górnej części listy użytkowników, aby ponownie dodać użytkownika. Użyj powyższych kroków, aby przypisać inną rolę użytkownikowi. Ten proces można powtórzyć wielokrotnie, aby dodać dodatkowe role do użytkownika (lub grupy).

Pokazany CustomAccountFactory w sekcji Niestandardowe konto użytkownika jest skonfigurowany do działania względem role oświadczenia z wartością tablicy JSON. Dodaj i zarejestruj element CustomAccountFactory w aplikacji KLIENCKIej, jak pokazano w sekcji Niestandardowe konto użytkownika. Nie ma potrzeby podawania kodu w celu usunięcia oryginalnego role oświadczenia, ponieważ jest on automatycznie usuwany przez strukturę.

Program W pliku aplikacji KLIENCKIej określ oświadczenie o nazwie "appRole" jako oświadczenie roli do ClaimsPrincipal.IsInRole sprawdzania:

builder.Services.AddMsalAuthentication(options =>
{
    ...

    options.UserOptions.RoleClaim = "appRole";
});

Uwaga

Jeśli wolisz użyć directoryRoles oświadczenia (ADD Administracja istrator Roles), przypisz "directoryRoles" do .RemoteAuthenticationUserOptions.RoleClaim

Program W pliku aplikacji SERWERA określ oświadczenie o nazwie "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" jako oświadczenie roli do ClaimsPrincipal.IsInRole sprawdzania:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(options =>
    {
        Configuration.Bind("AzureAd", options);
        options.TokenValidationParameters.RoleClaimType = 
            "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
    },
    options => { Configuration.Bind("AzureAd", options); });

Uwaga

Po zarejestrowaniu pojedynczego schematu uwierzytelniania schemat uwierzytelniania jest automatycznie używany jako schemat domyślny aplikacji i nie jest konieczne podanie schematu do AddAuthentication programu lub za pośrednictwem metody AuthenticationOptions. Aby uzyskać więcej informacji, zobacz Overview of ASP.NET Core Authentication and the ASP.NET Core anons (aspnet/Announcements #490).

Uwaga

Jeśli wolisz użyć wids oświadczenia (ADD Administracja istrator Roles), przypisz "wids" do .TokenValidationParameters.RoleClaimType

Po wykonaniu powyższych kroków tworzenia i przypisywania ról do użytkowników (lub grup, jeśli masz konto platformy Azure w warstwie Premium) i zaimplementowano go CustomAccountFactory przy użyciu zestawu Graph SDK, zgodnie z opisem we wcześniejszej części tego artykułu i w temacie Używanie interfejsu API programu Graph z platformą ASP.NET Core Blazor WebAssemblypowinno zostać wyświetlone appRole oświadczenie dla każdej przypisanej roli przypisanej przez zalogowanego użytkownika (lub ról przypisanych do grup, do których należą). Uruchom aplikację z użytkownikiem testowym, aby potwierdzić, że oświadczenia są obecne zgodnie z oczekiwaniami. Podczas testowania przy użyciu zestawu Graph SDK lokalnie zalecamy użycie nowej sesji przeglądarki w trybie prywatnym/incognito dla każdego testu, aby zapobiec zakłócaniu cookietestów. 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).

Metody autoryzacji składników działają w tym momencie. Dowolny z mechanizmów autoryzacji w składnikach aplikacji KLIENCKIej może używać Admin roli do autoryzowania użytkownika:

Obsługiwane są wiele testów ról:

  • Wymagaj, aby użytkownik był w Adminroli lubDeveloper ze składnikiem:AuthorizeView

    <AuthorizeView Roles="Admin, Developer">
        ...
    </AuthorizeView>
    
  • Wymagaj, aby użytkownik był zarówno w rolach, jak AdminiDeveloper ze składnikiemAuthorizeView:

    <AuthorizeView Roles="Admin">
        <AuthorizeView Roles="Developer" Context="innerContext">
            ...
        </AuthorizeView>
    </AuthorizeView>
    

    Aby uzyskać więcej informacji na Context temat wewnętrznego elementu AuthorizeView, zobacz ASP.NET Core authentication and authorization (Uwierzytelnianie i autoryzacja w systemie ASP.NET CoreBlazor).

  • Wymagaj, aby użytkownik był w Adminroli lubDeveloper z atrybutem :[Authorize]

    @attribute [Authorize(Roles = "Admin, Developer")]
    
  • Wymagaj, aby użytkownik był w rolach Admin iDeveloper z atrybutem :[Authorize]

    @attribute [Authorize(Roles = "Admin")]
    @attribute [Authorize(Roles = "Developer")]
    
  • Wymagaj, aby użytkownik był w Adminroli lubDeveloper z kodem proceduralnym:

    @code {
        private async Task DoSomething()
        {
            var authState = await AuthenticationStateProvider
                .GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.IsInRole("Admin") || user.IsInRole("Developer"))
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
    
  • Wymagaj, aby użytkownik był zarówno w rolach, jakAdmin iDeveloper z kodem proceduralnym, zmieniając warunkowy or (||) na warunkowy AND (&&) w poprzednim przykładzie:

    if (user.IsInRole("Admin") && user.IsInRole("Developer"))
    

Dowolny z mechanizmów autoryzacji w kontrolerach aplikacji SERWERA może używać Admin roli do autoryzowania użytkownika:

Obsługiwane są wiele testów ról:

  • Wymagaj, aby użytkownik był w Adminroli lubDeveloper z atrybutem :[Authorize]

    [Authorize(Roles = "Admin, Developer")]
    
  • Wymagaj, aby użytkownik był w rolach Admin iDeveloper z atrybutem :[Authorize]

    [Authorize(Roles = "Admin")]
    [Authorize(Roles = "Developer")]
    
  • Wymagaj, aby użytkownik był w Adminroli lubDeveloper z kodem proceduralnym:

    static readonly string[] scopeRequiredByApi = new string[] { "API.Access" };
    
    ...
    
    [HttpGet]
    public IEnumerable<ReturnType> Get()
    {
        HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);
    
        if (User.IsInRole("Admin") || User.IsInRole("Developer"))
        {
            ...
        }
        else
        {
            ...
        }
    
        return ...
    }
    
  • Wymagaj, aby użytkownik był zarówno w rolach, jakAdmin iDeveloper z kodem proceduralnym, zmieniając warunkowy or (||) na warunkowy AND (&&) w poprzednim przykładzie:

    if (User.IsInRole("Admin") && User.IsInRole("Developer"))
    

Ponieważ porównania ciągów platformy .NET są domyślnie uwzględniane wielkość liter, dopasowywanie nazw ról również uwzględnia wielkość liter. Na przykład Admin (wielkie litery A) nie jest traktowana jako ta sama rola co admin (małe litery a).

Przypadek Pascal jest zwykle używany dla nazw ról (na przykład BillingAdministrator), ale użycie przypadku Pascal nie jest ścisłym wymaganiem. Różne schematy wielkości liter, takie jak przypadek wielbłąda, przypadek kebab i przypadek węża, są dozwolone. Używanie spacji w nazwach ról jest również nietypowe, ale dozwolone. Na przykład jest to nietypowy format nazwy roli w aplikacjach .NET, billing administrator ale prawidłowy.

Dodatkowe zasoby