Dela via


Microsoft Entra (ME-ID) grupper, administratörsroller och approller (.NET 5 till .NET 7)

Important

Det här är inte den senaste versionen av den här artikeln. Den nuvarande versionen av ASP.NET Core finns i den senaste utgåvan av ASP.NET Core Blazor WebAssembly med Microsoft Entra ID-grupper och roller.

Important

Projektmallen Hosted Blazor WebAssembly togs bort från ramverket med lanseringen av .NET 8 (november 2023). Vägledningen i den här artikeln stöds endast för .NET 7 eller tidigare. Värdbaserade Blazor WebAssembly appar som uppgraderas vid varje version fortsätter att få produktsupport. Du kan också omstrukturera appen till en fristående Blazor WebAssembly app eller en Blazor Web App.

Den här artikeln beskriver hur du konfigurerar Blazor WebAssembly att använda Microsoft Entra ID-grupper och roller.

Microsoft Entra (ME-ID) innehåller flera auktoriseringsmetoder som kan kombineras med ASP.NET Core Identity:

  • Groups
    • Security
    • Microsoft 365
    • Distribution
  • Roles
    • ME-ID Administratörsroller
    • App Roles

Vägledningen i den här artikeln gäller för de Blazor WebAssembly ME-ID distributionsscenarier som beskrivs i följande artiklar:

Artikelns vägledning innehåller instruktioner för klient- och serverappar:

  • KLIENT: Fristående Blazor WebAssembly appar eller appen för Client en värdbaserad Blazorlösning.
  • SERVER: ASP.NET Core Server API/web API-appar eller appen för Server en värdbaserad Blazor lösning. Du kan ignorera SERVER-vägledningen i hela artikeln för en fristående Blazor WebAssembly app.

Exemplen i den här artikeln drar nytta av nya .NET/C#-funktioner. När du använder exemplen med .NET 7 eller tidigare krävs mindre ändringar. De text- och kodexempel som gäller interaktion med ME-ID och Microsoft Graph är dock desamma för alla versioner av ASP.NET Core.

Prerequisite

Vägledningen i den här artikeln implementerar Microsoft Graph API enligt Graph SDK vägledning i Använda Graph API med ASP.NET Core Blazor WebAssembly. Följ Graph SDK implementeringsvägledning för att konfigurera appen och testa den för att bekräfta att appen kan hämta Graph API-data för ett testanvändarkonto. Se även länkar för säkerhetsartikeln i Graph API-artikeln för att granska säkerhetsbegreppen i Microsoft Graph.

När du testar med Graph SDK lokalt rekommenderar vi att du använder en ny privat/inkognito-webbläsarsession för varje test för att förhindra att kvardröjande cookies stör testerna. Mer information finns i Secure an ASP.NET Core Blazor WebAssembly standalone app with Microsoft Entra ID.

Scopes

Så här tillåter du Microsoft Graph API-anrop för användarprofil, rolltilldelning och gruppmedlemskapsdata:

  • En KLIENTapp konfigureras med det delegeradeUser.Read omfånget (https://graph.microsoft.com/User.Read) i Azure-portalen eftersom åtkomsten till läsanvändardata bestäms av de omfång som beviljas (delegeras) till enskilda användare.
  • En SERVER-app konfigureras med programomfångetGroupMember.Read.All (https://graph.microsoft.com/GroupMember.Read.All) i Azure-portalen eftersom åtkomst är till för att appen ska kunna hämta information om gruppmedlemskap, inte baserat på individuell användarbehörighet för åtkomst till data om gruppmedlemmar.

De föregående omfången krävs utöver de omfång som krävs i ME-ID distributionsscenarier som beskrivs i artiklarna ovan (fristående med Microsoft-konton, fristående med ME-ID och värdbaserad med ME-ID).

Mer information finns i Översikt över behörigheter och medgivande i Microsofts identitetsplattform och Översikt över Microsoft Graph-behörigheter.

Behörigheter och omfång betyder samma sak och används synonymt i säkerhetsdokumentation och Azure-portalen. Om inte texten refererar till Azure-portalen använder den här artikeln omfången / när den refererar till Graph-behörigheter.

Scopes är okänsliga för skiftläget, så User.Read är samma som user.read. Använd gärna något av formaten, men vi rekommenderar ett konsekvent val i programkoden.

Anspråksattribut för gruppmedlemskap

I appens manifest i Azure-portalen för KLIENT- och SERVER-appar anger du groupMembershipClaims attributet till DirectoryRole. Ett värde för DirectoryRole resulterar i att ME-ID skickar alla roller för den inloggade användaren i det välkända ID-anspråket (wids):

  1. Öppna appens Azure-portalregistrering.
  2. Välj Hantera>Manifest i sidofältet.
  3. Leta upp attributet groupMembershipClaims.
  4. Ange värdet till DirectoryRole ("groupMembershipClaims": "DirectoryRole").
  5. Välj knappen Spara om du har gjort ändringar.

I appens manifest i Azure-portalen för KLIENT- och SERVER-appar anger du groupMembershipClaims attributet till All. Ett värde av All resulterar i att ME-ID skickar alla säkerhetsgrupper, distributionsgrupper och roller för den inloggade användaren i det välkända ID-kravet (wids):

  1. Öppna appens Azure-portalregistrering.
  2. Välj Hantera>Manifest i sidofältet.
  3. Leta upp attributet groupMembershipClaims.
  4. Ange värdet till All ("groupMembershipClaims": "All").
  5. Välj knappen Spara om du har gjort ändringar.

Anpassat användarkonto

Tilldela användare till ME-ID säkerhetsgrupper och ME-ID administratörsroller i Azure-portalen.

Exemplen i den här artikeln:

  • Anta att en användare har tilldelats rollen ME-ID faktureringsadministratör i Azure-portalen ME-ID klientorganisation för auktorisering för åtkomst till server-API-data.
  • Använd auktoriseringsprinciper för att styra åtkomsten i KLIENT- och SERVER-apparna .

I KLIENTappen utökar du RemoteUserAccount till att omfatta egenskaper för:

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

Lägg till en paketreferens till KLIENT-appen för Microsoft.Graph.

Note

Vägledning om hur du lägger till paket i .NET-appar finns i artiklarna under Installera och hantera paket i arbetsflödet för paketförbrukning (NuGet-dokumentation). Bekräfta rätt paketversioner på NuGet.org.

Lägg till Graph SDK-verktygsklasser och konfiguration i Graph SDK vägledning för artikeln Use Graph API with ASP.NET Core Blazor WebAssembly . Ange omfånget User.Read för åtkomsttoken som artikeln visar i exempelfilen wwwroot/appsettings.json .

Lägg till följande anpassade användarkontofabrik i KLIENT-appen . Den anpassade användarfabriken används för att upprätta:

  • Approllsanspråk (appRole) (täckts i avsnittet App Roller).
  • ME-ID Administrator-rollens anspråk (directoryRole).
  • Exempel på användarprofildataanspråk för användarens mobiltelefonnummer (mobilePhone) och kontorsplats (officeLocation).
  • ME-ID Gruppens anspråk (directoryGroup).
  • En ILogger (logger) för enkelhetens skull om du vill logga information eller felmeddelanden.

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;

namespace BlazorSample;

public class CustomAccountFactory() 
    : AccountClaimsPrincipalFactory<CustomUserAccount>
{
    private readonly ILogger<CustomAccountFactory> logger;
    private readonly IServiceProvider serviceProvider;
    private readonly string? baseUrl =
        string.Join("/",
            config.GetSection("MicrosoftGraph")["BaseUrl"] ??
                "https://graph.microsoft.com",
            config.GetSection("MicrosoftGraph")["Version"] ??
                "v1.0");

    public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger)
        : base(accessor)
    {
        this.serviceProvider = serviceProvider;
        this.logger = logger;
    }

    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 graphGroups = await requestMemberOf.GraphGroup.GetAsync();

                    if (graphGroups?.Value is not null)
                    {
                        foreach (var entry in graphGroups.Value)
                        {
                            if (entry.Id is not null)
                            {
                                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() 
    : AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
    private readonly ILogger<CustomAccountFactory> logger;
    private readonly IServiceProvider serviceProvider;

    public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger)
        : base(accessor)
    {
        this.serviceProvider = serviceProvider;
        this.logger = logger;
    }

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

Föregående kod innehåller inte transitiva medlemskap. Om appen kräver direkta och transitiva gruppmedlemskapsanspråk ersätter du egenskapen MemberOf (IUserMemberOfCollectionWithReferencesRequestBuilder) med TransitiveMemberOf (IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).

Föregående kod ignorerar anspråk på gruppmedlemskap (groups) som är ME-ID administratörsroller (#microsoft.graph.directoryRole typ) eftersom GUID-värdena som returneras av ME-ID är entitets-ID:n för administratörsroll och inte rollmalls-ID:n. Entitets-ID:n är inte stabila mellan klienter och bör inte användas för att skapa auktoriseringsprinciper för användare i appar. Använd alltid mall-ID:n för ME-ID administratörsroller som tillhandahålls av wids anspråk.

Anspråket wids (och därmed directoryRole anspråket) med värdet b79fbf4d-3ef9-4689-8143-76b194e85509 finns för icke-gästkonton för klientorganisationen. Det refererar inte till ett ME-ID administratörsrollmall-ID.

I KLIENTappen konfigurerar du MSAL-autentiseringen så att den använder den anpassade användarkontofabriken.

Bekräfta att Program-filen använder namnområdet Microsoft.AspNetCore.Components.WebAssembly.Authentication:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Uppdatera AddMsalAuthentication-anropet till följande. Observera att Blazor ramverkets RemoteUserAccount ersätts av appens CustomUserAccount för MSAL-autentiserings- och kontoanspråkens huvudfabrik:

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

Bekräfta förekomsten av Graph SDK-koden som beskrivs i artikeln Använd Graph API med ASP.NET Core Blazor WebAssembly och att konfigurationen wwwroot/appsettings.json är korrekt enligt Graph SDK-vägledningen :

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

wwwroot/appsettings.json:

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

Authorization configuration

I KLIENTappen skapar du en princip för varje approll, ME-ID administratörsroll eller säkerhetsgrupp i Program filen. I följande exempel skapas en policy för den inbyggda rollen Faktureringsadministratör (ME-ID ):

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

En fullständig lista över ID:er för ME-ID administratörsroller finns i Rollmalls-ID i Entra-dokumentationen. Mer information om auktoriseringsprinciper finns i Principbaserad auktorisering i ASP.NET Core.

I följande exempel använder KLIENT-appen föregående princip för att auktorisera användaren.

Den AuthorizeView-komponenten fungerar i enlighet med policyn:

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

Åtkomst till en hel komponent kan baseras på principen med hjälp av ett [Authorize] attributdirektiv (AuthorizeAttribute):

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

Om användaren inte har behörighet omdirigeras de till ME-ID inloggningssida.

En principkontroll kan också utföras i kod med procedurlogik.

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

Med hjälp av ovanstående metoder kan du också skapa principbaserad åtkomst för approller, där GUID som används för principen anges i elementet appRoles i appens manifest i Azure-portalen och säkerhetsgrupper, där GUID:t som används för principen matchar gruppobjekt-ID:ti fönstret Azure-portalgrupper.

Auktorisera server-API/webb-API-åtkomst

En SERVER API-app kan ge användare åtkomst till säkra API-slutpunkter med auktoriseringsprinciper för säkerhetsgrupper, ME-ID administratörsroller och approller när en åtkomsttoken innehåller groups, widsoch role anspråk. I det följande exemplet skapas en policy för rollen ME-ID faktureringsadministratör i Program-filen med hjälp av anspråken wids (välkända ID:n/rollmalls-ID:n):

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

En fullständig lista över ID:er för ME-ID administratörsroller finns i Rollmalls-ID :t i Azure-dokumentationen. Mer information om auktoriseringsprinciper finns i Principbaserad auktorisering i ASP.NET Core.

Åtkomst till en kontrollant i SERVER-appen kan baseras på användning av ett [Authorize] attribut med namnet på principen (API-dokumentation: AuthorizeAttribute).

I följande exempel begränsas åtkomsten till faktureringsdata från BillingDataController till Azure-faktureringsadministratörer genom en policy med namnet BillingAdministrator:

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

Mer information finns i Principbaserad auktorisering i ASP.NET Core.

App Roles

Information om hur du konfigurerar appen i Azure-portalen för att tillhandahålla medlemskapsanspråk för approller finns i Lägga till approller i ditt program och ta emot dem i token i Entra-dokumentationen.

I följande exempel förutsätts att KLIENT- och SERVER-apparna är konfigurerade med två roller och att rollerna tilldelas till en testanvändare:

  • Admin
  • Developer

Note

När du utvecklar en värdbaserad Blazor WebAssembly app eller ett klientserverpar med fristående appar (en fristående Blazor WebAssembly app och en ASP.NET Core-server-API/webb-API-app) appRoles måste manifestegenskapen för både klienten och azure-portalappregistreringarna för servern innehålla samma konfigurerade roller. När du har upprättat rollerna i klientappens manifest kopierar du dem i sin helhet till serverappens manifest. Om du inte speglar manifestet appRoles mellan klient- och serverappregistreringarna upprättas inte rollanspråk för autentiserade användare av server-API:et/webb-API:et, även om deras åtkomsttoken har rätt poster i rollanspråken.

Även om du inte kan tilldela roller till grupper utan ett Microsoft Entra ID Premium-konto kan du tilldela roller till användare och ta emot rollanspråk för användare med ett Standard Azure-konto. Vägledningen i det här avsnittet kräver inte ett ME-ID Premium-konto.

När du arbetar med standardkatalogen, följ anvisningarna i Lägg till approller i ditt program och ta emot dem i tokenen för att konfigurera och tilldela roller. Om du inte arbetar med standardkatalogen redigerar du appens manifest i Azure-portalen för att upprätta appens roller manuellt i appRoles posten för manifestfilen. Följande är ett exempel appRoles post som skapar Admin och Developer roller. Dessa exempelroller används senare i det här avsnittets exempel på komponentnivå för att implementera åtkomstbegränsningar:

"appRoles": [
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Administrators manage developers.",
    "displayName": "Admin",
    "id": "{ADMIN GUID}",
    "isEnabled": true,
    "lang": null,
    "origin": "Application",
    "value": "Admin"
  },
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Developers write code.",
    "displayName": "Developer",
    "id": "{DEVELOPER GUID}",
    "isEnabled": true,
    "lang": null,
    "origin": "Application",
    "value": "Developer"
  }
],

För platshållarna {ADMIN GUID} och {DEVELOPER GUID} i föregående exempel kan du generera GUID:er med en GUID-generator online (Google-sökresultat för "guid generator").

Så här tilldelar du en roll till en användare (eller grupp om du har ett Azure-konto på Premium-nivå):

  1. Gå till företagsprogram i ME-ID-området i Azure-portalen.
  2. Välj appen. Välj Hantera>användare och grupper i sidofältet.
  3. Markera kryssrutan för ett eller flera användarkonton.
  4. På menyn ovanför listan över användare väljer du Redigera tilldelning.
  5. För posten Välj en roll väljer du Ingen markerad.
  6. Välj en roll i listan och använd knappen Välj för att välja den.
  7. Använd knappen Tilldela längst ned på skärmen för att tilldela rollen.

Flera roller tilldelas i Azure-portalen genom att lägga till en användare för varje ytterligare rolltilldelning. Använd knappen Lägg till användare/grupp överst i listan över användare för att lägga till en användare igen. Använd föregående steg för att tilldela användaren en annan roll. Du kan upprepa den här processen så många gånger som behövs för att lägga till ytterligare roller till en användare (eller grupp).

Det CustomAccountFactory som visas i avsnittet anpassat användarkonto konfigureras för att agera på ett role anspråk med ett JSON-matrisvärde. Lägg till och registrera CustomAccountFactory i KLIENT-appen enligt vad som visas i avsnittet Anpassat användarkonto . Du behöver inte ange kod för att ta bort det ursprungliga role anspråket eftersom det tas bort automatiskt av ramverket.

I Program-filen för en KLIENT-app anger du anspråket "appRole" som rollanspråk för ClaimsPrincipal.IsInRole-kontroller:

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

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

Note

Om du föredrar att använda anspråket directoryRoles (LÄGG till administratörsroller) tilldelar du "directoryRoles" till RemoteAuthenticationUserOptions.RoleClaim.

I Program-filen för en SERVER-app specificerar du anspråket med namnet "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" som rollanspråk för ClaimsPrincipal.IsInRole-kontroller:

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

Note

När ett enda autentiseringsschema registreras används det automatiskt som appens standardschema, och det är inte nödvändigt att ange schemat till AddAuthentication eller via AuthenticationOptions. Mer information finns i Översikt över ASP.NET Core Authentication och ASP.NET Core-meddelandet (aspnet/Meddelanden #490).

Note

Om du föredrar att använda anspråket wids (LÄGG till administratörsroller) tilldelar du "wids" till TokenValidationParameters.RoleClaimType.

När du har slutfört föregående steg för att skapa och tilldela roller till användare (eller grupper om du har ett Azure-konto på Premium-nivå) och implementerat CustomAccountFactory med Graph SDK, enligt beskrivningen tidigare i den här artikeln och i Använd Graph API med ASP.NET Core Blazor WebAssembly, bör du se ett appRole anspråk för varje tilldelad roll som en inloggad användare tilldelas (eller roller som tilldelats till grupper som de är medlemmar i). Kör appen med en testanvändare för att bekräfta att kraven finns som förväntat. När du testar med Graph SDK lokalt rekommenderar vi att du använder en ny privat/inkognito-webbläsarsession för varje test för att förhindra att kvardröjande cookies stör testerna. Mer information finns i Secure an ASP.NET Core Blazor WebAssembly standalone app with Microsoft Entra ID.

Metoderna för komponentauktorisering fungerar just nu. Någon av auktoriseringsmekanismerna i klientappens komponenter kan använda Admin rollen för att auktorisera användaren:

Flera rolltester stöds:

  • Kräv att användaren finns i antingen rollen AdminellerDeveloper med komponenten AuthorizeView:

    <AuthorizeView Roles="Admin, Developer">
        ...
    </AuthorizeView>
    
  • Kräv att användaren finns i rollerna både och AdminochDeveloper med komponenten AuthorizeView.

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

    Mer information om Context för den inre AuthorizeViewfinns i ASP.NET Core Blazor-autentisering och auktorisering.

  • Kräv att användaren finns i antingen rollen AdminellerDeveloper med attributet [Authorize]:

    @attribute [Authorize(Roles = "Admin, Developer")]
    
  • Kräv att användaren finns i både rollerna AdminochDeveloper med attributet [Authorize]:

    @attribute [Authorize(Roles = "Admin")]
    @attribute [Authorize(Roles = "Developer")]
    
  • Kräv att användaren finns i antingenAdminellerDeveloper roll med procedurkod:

    @code {
        private async Task DoSomething()
        {
            var authState = await AuthenticationStateProvider
                .GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.IsInRole("Admin") || user.IsInRole("Developer"))
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
    
  • Kräv att användaren finns i både rollerna AdminochDeveloper med procedurkod genom att ändra villkorsstyrda ELLER (||) till en villkorsstyrd AND (&&) i föregående exempel:

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

Någon av auktoriseringsmekanismerna i kontrollanter i SERVER-appen kan använda Admin rollen för att auktorisera användaren:

Flera rolltester stöds:

  • Kräv att användaren finns i antingen rollen AdminellerDeveloper med attributet [Authorize]:

    [Authorize(Roles = "Admin, Developer")]
    
  • Kräv att användaren finns i både rollerna AdminochDeveloper med attributet [Authorize]:

    [Authorize(Roles = "Admin")]
    [Authorize(Roles = "Developer")]
    
  • Kräv att användaren finns i antingenAdminellerDeveloper roll med procedurkod:

    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 ...
    }
    
  • Kräv att användaren finns i både rollerna AdminochDeveloper med procedurkod genom att ändra villkorsstyrda ELLER (||) till en villkorsstyrd AND (&&) i föregående exempel:

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

Eftersom .NET-strängjämförelser är skiftlägeskänsliga är matchande rollnamn också skiftlägeskänsliga. Till exempel behandlas Admin (stora bokstäver A) inte som samma roll som admin (små bokstäver a).

Pascal-fallet används vanligtvis för rollnamn (till exempel BillingAdministrator), men användningen av Pascal-fallet är inte ett strikt krav. Olika höljescheman, till exempel kamelfodring, kebabfodring och ormfodring, är tillåtna. Att använda blanksteg i rollnamn är också ovanligt men tillåtet. Till exempel är billing administrator ett ovanligt rollnamnsformat i .NET-appar men giltigt.

Additional resources