Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Important
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version von ASP.NET Core finden Sie in der neuesten Version von ASP.NET Core Blazor WebAssembly mit Microsoft Entra ID-Gruppen und Rollen.
Important
Die Vorlage für gehostete Blazor WebAssembly Projekte wurde mit der Version von .NET 8 (November 2023) aus dem Framework entfernt. Die Anleitungen in diesem Artikel werden nur für .NET 7 oder früher unterstützt. Gehostete Blazor WebAssembly Apps, die für jede Version aktualisiert wurden, erhalten weiterhin Produktsupport. Alternativ können Sie die App entweder in eine eigenständige Blazor WebAssembly-App oder eine Blazor Web App umwandeln.
In diesem Artikel wird erläutert, wie Sie Blazor WebAssembly für die Verwendung von Microsoft Entra ID-Gruppen und -Rollen konfigurieren.
Microsoft Entra ID (ME-ID) bietet mehrere Autorisierungsansätze, die mit ASP.NET Core Identity kombiniert werden können:
- Groups
- Security
- Microsoft 365
- Distribution
- Roles
- ME-ID-Administratorrollen
- App-Rollen
Die Hinweise in diesem Artikel gelten für die Blazor WebAssembly ME-ID Bereitstellungsszenarien, die in den folgenden Artikeln beschrieben werden:
- Sichern einer eigenständigen ASP.NET Core Blazor WebAssembly-App mit Microsoft-Konten
- Eigenständig mit ME-ID
- Gehostet mit ME-ID
Dieser Artikel enthält Anleitungen für Client- und Server-Apps:
- CLIENT: Eigenständige Blazor WebAssembly-Apps oder die Client -App einer gehosteten BlazorProjektmappe.
- SERVER: ASP.NET Core-Server-API-/Web-API-Apps oder die Server-App einer gehosteten Blazor-Lösung. Bei einer eigenständigen -App können Sie den Leitfaden Blazor WebAssembly in diesem Artikel ignorieren.
Die Beispiele in diesem Artikel nutzen neue .NET/C#-Funktionen. Wenn Sie die Beispiele mit .NET 7 oder früher verwenden, sind geringfügige Änderungen erforderlich. Die Text- und Codebeispiele, die sich auf die Interaktion mit ME-ID und Microsoft Graph beziehen, sind jedoch für alle Versionen von ASP.NET Core identisch.
Prerequisite
Im Leitfaden in diesem Artikel wird die Microsoft Graph-API gemäß dem Leitfaden zum Graph SDK unter Verwenden der Graph-API mit der Blazor WebAssembly von ASP.NET Core implementiert. Konfigurieren und testen Sie die App gemäß dem Implementierungsleitfaden für das Graph SDK, um sicherzustellen, dass die App Graph-API-Daten für ein Testbenutzerkonto abrufen kann. Lesen Sie außerdem die Informationen zu den Sicherheitskonzepten von Microsoft Graph, die Sie unter den Querlinks im Artikel zur Sicherheit der Graph-API finden.
Beim lokalem Testen mit dem Graph SDK empfehlen wir die Verwendung einer neuen privaten bzw. Inkognito-Browsersitzung für jeden Test, um zu verhindern, dass Tests durch vorhandene Cookies beeinträchtigt werden. Weitere Informationen finden Sie unter Sichern einer eigenständigen ASP.NET Core-Blazor WebAssembly-App mit Microsoft Entra ID.
Scopes
So lassen Sie Microsoft Graph-API-Aufrufe für Benutzerprofil-, Rollenzuweisungs- und Gruppenmitgliedschaftsdaten zu:
- Eine CLIENT-App wird mit dem delegierten
User.Read-Bereich (https://graph.microsoft.com/User.Read) im Azure-Portal konfiguriert, da der Zugriff auf das Lesen von Benutzerdaten durch die Bereiche bestimmt wird, die einzelnen Benutzern gewährt (delegiert) werden. - Eine SERVER-App wird mit dem -Bereich der (
GroupMember.Read.All) im Azure-Portal konfiguriert, da der Zugriff für die App für den Zugriff auf Informationen zur Gruppenmitgliedschaft gilt, nicht basierend auf der Autorisierung einzelner Benutzerinnen und Benutzer für den Zugriff auf Daten zu Gruppenmitgliedern.
Die vorstehenden Bereiche sind zusätzlich zu den Bereichen erforderlich, die in den ME-ID-Bereitstellungsszenarien benötigt werden, die in den zuvor aufgeführten Artikeln beschrieben sind (Standalone mit Microsoft-Konten, Standalone mit ME-ID und Gehostet mit ME-ID).
Weitere Informationen finden Sie unter Übersicht über Berechtigungen und Zustimmung in der Microsoft Identity Platform und Übersicht über Microsoft Graph-Berechtigungen.
Berechtigungen und Bereiche bedeuten dasselbe und werden in der Sicherheitsdokumentation und im Azure-Portal austauschbar verwendet. Sofern sich der Text nicht auf das Azure-Portal bezieht, verwendet dieser Artikel scope/scopes, wenn er sich auf Graph-Berechtigungen bezieht.
Die Groß- und Kleinschreibung spielt keine Rolle, also ist User.Read dasselbe wie user.read. Sie können beide Formate verwenden, aber wir empfehlen eine einheitliche Wahl für den gesamten Anwendungscode.
groupMembershipClaims-Attribut
Legen Sie im Azure-Portal im App-Manifest für CLIENT- und SERVER-Apps das groupMembershipClaims-Attribut auf DirectoryRole fest. Ein Wert von DirectoryRole führt dazu, dass ME-ID alle Rollen des angemeldeten Benutzers im Well-known IDs claim (wids) sendet:
- Öffnen Sie die Azure-Portal-Registrierung der App.
- Wählen Sie in der Randleiste Verwalten>Manifest aus.
- Suchen Sie das
groupMembershipClaims-Attribut. - Legen Sie den Wert auf
DirectoryRolefest ("groupMembershipClaims": "DirectoryRole"). - Wählen Sie die Schaltfläche Speichern aus, wenn Sie Änderungen vorgenommen haben.
Legen Sie im Azure-Portal im App-Manifest für CLIENT- und SERVER-Apps das groupMembershipClaims-Attribut auf All fest. Beim Wert All sendet ME-ID alle Sicherheitsgruppen, Verteilergruppen und Rollen des angemeldeten Benutzers im Anspruch bekannter IDs (wids):
- Öffnen Sie die Azure-Portal-Registrierung der App.
- Wählen Sie in der Randleiste Verwalten>Manifest aus.
- Suchen Sie das
groupMembershipClaims-Attribut. - Legen Sie den Wert auf
Allfest ("groupMembershipClaims": "All"). - Wählen Sie die Schaltfläche Speichern aus, wenn Sie Änderungen vorgenommen haben.
Benutzerdefiniertes Benutzerkonto
Weisen Sie Benutzer im Azure-Portal zu ME-ID-Sicherheitsgruppen und ME-ID-Administratorrollen zu.
Für die Beispiele in diesem Artikel gilt:
- Es wird angenommen, dass einem Benutzer im ME-ID-Mandanten im Azure-Portal die ME-ID-Rolle Abrechnungsadministrator zugewiesen ist, damit dieser Benutzer für den Zugriff auf die Zugriffsserver-API-Daten autorisiert ist.
- Verwenden Sie Autorisierungsrichtlinien, um den Zugriff innerhalb der CLIENT- und SERVER-Apps zu steuern.
Erweitern Sie in der RemoteUserAccount-App, um Eigenschaften für Folgendes einzuschließen:
-
Roles: Array aus ME-ID-App-Rollen (beschrieben im Abschnitt App-Rollen) -
Wids: ME-ID-Administratorrollen im Anspruch bekannter IDs (wids) -
Oid: Unveränderlicheroid-Anspruch (Objektbezeichneranspruch) (identifiziert einen Benutzer mandantenintern und mandantenübergreifend eindeutig)
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; }
}
Fügen Sie einen Paketverweis zur CLIENT-App für Microsoft.Graph hinzu.
Note
Eine Anleitung zum Hinzufügen von Paketen zu .NET-Anwendungen finden Sie in den Artikeln unter Pakete installieren und verwalten unter Workflow für die Paketnutzung (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Fügen Sie die Hilfsklassen des Graph SDK und die Konfiguration im Leitfaden zum Graph SDK im Artikel Verwenden der Graph-API mit der Blazor WebAssembly von ASP.NET Core hinzu. Geben Sie wie in der Beispieldatei User.Read im Artikel gezeigt den wwwroot/appsettings.json-Bereich für das Zugriffstoken an.
Fügen Sie der CLIENT-App die folgende benutzerdefinierte Benutzerkontofactory hinzu. Die benutzerdefinierte Benutzerfactory wird verwendet, um Folgendes einzurichten:
- App-Rollenansprüche (
appRole) (beschrieben im Abschnitt App-Rollen) - ME-ID-Administratorrollenansprüche (
directoryRole). - Beispiel für Benutzerprofildaten-Ansprüche für die Mobiltelefonnummer (
mobilePhone) und den Bürostandort (officeLocation) des Benutzers - ME-ID-Gruppenansprüche (
directoryGroup). - Ein ILogger (
logger) für den Fall, dass Sie Informationen oder Fehler protokollieren möchten
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;
}
}
Der vorangehende Code enthält keine transitiven Mitgliedschaften. Wenn die App direkte und transitive Gruppenmitgliedschaftsansprüche erfordert, ersetzen Sie die MemberOf-Eigenschaft (IUserMemberOfCollectionWithReferencesRequestBuilder) durch TransitiveMemberOf (IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).
Der vorangehende Code ignoriert Gruppenmitgliedschaftsansprüche (groups), die ME-ID Administratorrollen (#microsoft.graph.directoryRole Typ) sind, weil die von ME-ID zurückgegebenen GUID-Werte Administratorrollen Entitäts-IDs und nicht Rollen Template IDs sind. Entitäts-IDs sind nicht mandantenübergreifend stabil und sollten nicht zur Erstellung von Richtlinien für die Berechtigung von Benutzern in Apps verwendet werden. Verwenden Sie immer Vorlagen-IDs für ME-ID-Administrator-Rollen, die von wids-Ansprüchen bereitgestellt werden.
Der wids-Anspruch(und damit directoryRole-Forderung) mit einem Wert von b79fbf4d-3ef9-4689-8143-76b194e85509 existiert für Nicht-Gastkonten des Mandanten. Sie bezieht sich nicht auf eine ME-ID Administrator Role Vorlagen-ID.
Konfigurieren Sie in der CLIENT-App die MSAL-Authentifizierung (Microsoft Authentication Library) für die Verwendung der benutzerdefinierten Benutzerkontofactory.
Vergewissern Sie sich, dass die Datei Program den Microsoft.AspNetCore.Components.WebAssembly.Authentication-Namespace verwendet:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
Aktualisieren Sie den AddMsalAuthentication-Aufruf wie im Folgenden gezeigt. Beachten Sie, dass das Blazor des RemoteUserAccount-Frameworks durch das CustomUserAccount der App für die MSAL-Authentifizierung und die Kontoanspruchs-Prinzipalfactory ersetzt wird:
builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
CustomUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd",
options.ProviderOptions.Authentication);
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
CustomAccountFactory>();
Vergewissern Sie sich, dass der im Artikel beschriebene Blazor WebAssembly-Code vorhanden ist und die Konfiguration von dem Leitfaden zum wwwroot/appsettings.json entspricht:
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"
]
}
}
Konfigurieren der Autorisierung
Erstellen Sie in der CLIENT-App eine Richtlinie für jede App-Rolle, ME-ID-Administratorrolle oder Sicherheitsgruppe in der Program-Datei. Das folgende Beispiel erstellt eine Richtlinie für die in ME-ID integrierte Rolle Billing Administrator:
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("BillingAdministrator", policy =>
policy.RequireClaim("directoryRole",
"b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});
Die vollständige Liste der IDs für ME-ID Administratorrollen finden Sie unter Rollenvorlagen-IDs in der Entra-Dokumentation. Weitere Informationen zu Autorisierungsrichtlinien finden Sie unter Richtlinienbasierte Autorisierung in ASP.NET Core.
In den folgenden Beispielen verwendet die CLIENT-App die oben genannte Richtlinie zum Autorisieren des Benutzers.
Die AuthorizeView-Komponente verwendet die Richtlinie:
<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>
Durch Verwendung einer [Authorize]-Attributanweisung (AuthorizeAttribute) kann mithilfe der Richtlinie der Zugriff auf eine gesamte Komponente geregelt werden:
@page "/"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "BillingAdministrator")]
Wenn der Benutzer nicht autorisiert ist, wird er zur ME-ID-Anmeldeseite umgeleitet.
Eine Richtlinienüberprüfung kann auch in Code mit prozeduraler Logik durchgeführt werden.
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.";
}
}
}
Mit den vorstehenden Ansätzen können Sie auch einen richtlinienbasierten Zugriff für App-Rollen erstellen, wobei die für die Richtlinie verwendete GUID im appRoles-Element des Manifests der App im Azure-Portal festgelegt wird, sowie für Sicherheitsgruppen, wobei die für die Richtlinie verwendete GUID mit der Gruppe Objekt-ID im Bereich Gruppen des Azure-Portals übereinstimmt.
Autorisieren des Server-API-/Web-API-Zugriffs
Eine SERVER-API-App kann Benutzer mit Autorisierungsrichtlinien für Sicherheitsgruppen, ME-ID-Administratorrollen und App-Rollen für den Zugriff auf sichere API-Endpunkte autorisieren, wenn ein Zugriffstoken groups-, wids- und role-Ansprüche enthält. Das folgende Beispiel erstellt eine Richtlinie für die ME-ID-Rolle Abrechnungsadministrator in der Program-Datei mithilfe der wids-Ansprüche (bekannte IDs oder Rollenvorlagen-IDs):
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("BillingAdministrator", policy =>
policy.RequireClaim("wids", "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});
Die vollständige Liste der IDs für ME-ID-Administratorrollen finden Sie in der Azure-Dokumentation unter Rollenvorlagen-IDs. Weitere Informationen zu Autorisierungsrichtlinien finden Sie unter Richtlinienbasierte Autorisierung in ASP.NET Core.
Der Zugriff auf einen Controller in der SERVER-App kann auf der Verwendung eines [Authorize]-Attributs mit dem Namen der Richtlinie basieren (API-Dokumentation: AuthorizeAttribute).
Das folgende Beispiel beschränkt den Zugriff auf Abrechnungsdaten vom BillingDataController auf Azure-Abrechnungsadministratoren mit dem Richtliniennamen BillingAdministrator:
using Microsoft.AspNetCore.Authorization;
[Authorize(Policy = "BillingAdministrator")]
[ApiController]
[Route("[controller]")]
public class BillingDataController : ControllerBase
{
...
}
Weitere Informationen finden Sie unter Richtlinienbasierte Autorisierung in ASP.NET Core.
App-Rollen
Um die Anwendung im Azure-Portal so zu konfigurieren, dass sie Mitgliedschaftsansprüche von Anwendungsrollen bereitstellt, lesen Sie den Abschnitt Anwendungsrollen zu Ihrer Anwendung hinzufügen und im Token empfangen in der Entra-Dokumentation.
Im folgenden Beispiel wird angenommen, dass die CLIENT- und SERVER-Apps mit zwei Rollen konfiguriert und die Rollen einem Testbenutzer zugewiesen sind:
AdminDeveloper
Note
Wenn Sie eine gehostete Blazor WebAssembly-App oder ein Client-Server-Paar aus eigenständigen Apps (einer eigenständigen Blazor WebAssembly-App und einer ASP.NET Core-Server-API-/Web-API-App) entwickeln, muss die Manifesteigenschaft appRoles der Registrierungen des Clients und des Servers im Azure-Portal dieselben konfigurierten Rollen enthalten. Nachdem die Rollen im Manifest der Client-App festgelegt wurden, kopieren Sie diese in Gänze in das Manifest der Server-App. Wenn Sie das appRoles-Manifest zwischen den Client- und Server-App-Registrierungen nicht spiegeln, werden keine Rollenansprüche für authentifizierte Benutzende der Server-API/Web-API erstellt, auch wenn das Zugriffstoken über die richtigen Einträge in den Rollenansprüchen verfügt.
Zwar können Sie ohne Microsoft Entra ID-Premium-Konto nicht Rollen zu Gruppen zuweisen, aber Sie können Benutzenden Rollen zuweisen und Rollenansprüche für Benutzende mit einem Azure-Standardkonto erhalten. Für die Schritte in diesem Abschnitt ist kein ME-ID Premium-Konto erforderlich.
Befolgen Sie beim Arbeiten mit dem Standardverzeichnis die Anweisungen unter Anwendungsrollen zu Ihrer Anwendung hinzufügen und im Token empfangen, um Rollen zu konfigurieren und zuzuweisen. Wenn Sie nicht mit dem Standardverzeichnis arbeiten, bearbeiten Sie das Manifest der App im Azure-Portal, um die Rollen der App manuell im appRoles-Eintrag der Manifestdatei einzurichten. Im Folgenden sehen Sie einen appRoles-Beispieleintrag, der Admin- und Developer-Rollen erstellt. Diese Beispielrollen werden an späterer Stelle im Beispiel in diesem Abschnitt auf Komponentenebene verwendet, um Zugriffsbeschränkungen zu implementieren:
"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 die {ADMIN GUID} und {DEVELOPER GUID} Platzhalter im vorherigen Beispiel können Sie GUIDs mit einem Online-GUID-Generator (Google-Suchergebnis für "guid generator") generieren.
So weisen Sie einem Benutzer (oder einer Gruppe, wenn Sie über ein Azure-Konto im Premium-Tarif verfügen) eine Rolle zu:
- Navigieren Sie im ME-ID-Bereich des Azure-Portals zu Unternehmensanwendungen.
- Wählen Sie die App aus. Wählen Sie auf der Randleiste Verwalten>Benutzer und Gruppen aus.
- Aktivieren Sie das Kontrollkästchen für ein oder mehrere Benutzerkonten.
- Wählen Sie im Menü über der Liste der Benutzer die Option Zuweisung bearbeiten aus.
- Wählen Sie für den Eintrag Rolle auswählen die Option Keine ausgewählt aus.
- Klicken Sie in der Liste auf eine Rolle, und wählen Sie sie mit der Schaltfläche Auswählen aus.
- Verwenden Sie die Schaltfläche Zuweisen am unteren Bildschirmrand, um die Rolle zuzuweisen.
Mehrere Rollen werden im Azure-Portal durch separates Hinzufügen eines Benutzers für jede weitere Rollenzuweisung zugewiesen. Verwenden Sie die Schaltfläche Benutzer/Gruppe hinzufügen oben in der Liste der Benutzer, um einen Benutzer erneut hinzuzufügen. Führen Sie die obigen Schritte aus, um dem Benutzer eine weitere Rolle zuzuweisen. Sie können diesen Vorgang beliebig oft wiederholen, um einem Benutzer (oder einer Gruppe) zusätzliche Rollen hinzuzufügen.
Die im Abschnitt CustomAccountFactory gezeigte ist so konfiguriert, dass sie auf einen role-Anspruch mit einem JSON-Arraywert reagiert. Fügen Sie die CustomAccountFactory in der CLIENT-App hinzu, und registrieren Sie sie, wie im Abschnitt Benutzerdefiniertes Benutzerkonto gezeigt. Für das Entfernen des ursprünglichen role-Anspruchs muss kein Code bereitgestellt werden, da das Framework diesen automatisch entfernt.
Geben Sie in der Program-Datei einer CLIENT-App den Anspruch namens appRole als Rollenanspruch für ClaimsPrincipal.IsInRole-Überprüfungen an:
builder.Services.AddMsalAuthentication(options =>
{
...
options.UserOptions.RoleClaim = "appRole";
});
Note
Wenn Sie lieber den directoryRoles-Anspruch (ADD-Administratorrollen) verwenden möchten, weisen Sie directoryRoles zu RemoteAuthenticationUserOptions.RoleClaim zu.
Geben Sie in der Program-Datei einer SERVER-App den Anspruch namens http://schemas.microsoft.com/ws/2008/06/identity/claims/role als Rollenanspruch für ClaimsPrincipal.IsInRole-Überprüfungen an:
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
Wenn ein einzelnes Authentifizierungsschema registriert ist, wird es automatisch als Standardschema der App verwendet, und es ist nicht erforderlich, das Schema auf AddAuthentication oder über AuthenticationOptions anzugeben. Weitere Informationen finden Sie in der Übersicht über die ASP.NET Core- Authentifizierung und in der ASP.NET Core-Ankündigung (aspnet/Announcements #490).
Note
Wenn Sie lieber den wids-Anspruch (ADD-Administratorrollen) verwenden möchten, weisen Sie wids zu TokenValidationParameters.RoleClaimType zu.
Nachdem Sie die vorherigen Schritte zum Erstellen und Zuweisen von Rollen für Benutzer (oder Gruppen, wenn Sie über ein Azure-Konto im Premium-Tarif verfügen) ausgeführt und die CustomAccountFactory mit dem Graph SDK wie weiter oben in diesem Artikel und unter Verwenden der Graph-API mit der Blazor WebAssembly von ASP.NET Core beschrieben implementiert haben, sollte ein appRole-Anspruch für jede Rolle, die einem angemeldeten Benutzer zugewiesen ist (oder Rollen, die Gruppen zugewiesen sind, denen er angehört), angezeigt werden. Führen Sie die App mit einem Testbenutzer aus, um sicherzustellen, dass die Ansprüche wie erwartet vorhanden sind. Beim lokalem Testen mit dem Graph SDK empfehlen wir die Verwendung einer neuen privaten bzw. Inkognito-Browsersitzung für jeden Test, um zu verhindern, dass Tests durch vorhandene Cookies beeinträchtigt werden. Weitere Informationen finden Sie unter Sichern einer eigenständigen ASP.NET Core-Blazor WebAssembly-App mit Microsoft Entra ID.
Die Komponentenautorisierungsansätze sind Stand jetzt funktional. Jeder der Autorisierungsmechanismen in Komponenten der CLIENT-App kann die Rolle Admin verwenden, um Benutzer zu autorisieren:
-
<AuthorizeView Roles="Admin"> [Authorize]-Attributanweisung (AuthorizeAttribute)@attribute [Authorize(Roles = "Admin")]-
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); var user = authState.User; if (user.IsInRole("Admin")) { ... }
Mehrere Rollentests werden unterstützt:
Legen Sie mithilfe der -Komponente als erforderlich fest, dass der Benutzer
Admindie RolleDeveloperdie RolleAuthorizeViewinnehat:<AuthorizeView Roles="Admin, Developer"> ... </AuthorizeView>Legen Sie mithilfe der -Komponente als erforderlich fest, dass der Benutzer
Admindie RolleDeveloperdie RolleAuthorizeViewinnehat:<AuthorizeView Roles="Admin"> <AuthorizeView Roles="Developer" Context="innerContext"> ... </AuthorizeView> </AuthorizeView>Weitere Informationen zu
Contextfür die innere AuthorizeView finden Sie unter ASP.NET Core-Blazor-Authentifizierung und -Autorisierung.Legen Sie mithilfe des -Attributs als erforderlich fest, dass der Benutzer
Admindie RolleDeveloperdie Rolle[Authorize]innehat:@attribute [Authorize(Roles = "Admin, Developer")]Legen Sie mithilfe des -Attributs als erforderlich fest, dass der Benutzer
Admindie RolleDeveloperdie Rolle[Authorize]innehat:@attribute [Authorize(Roles = "Admin")] @attribute [Authorize(Roles = "Developer")]Legen Sie per prozeduralem Code als erforderlich fest, dass der Benutzer entweder die Rolle
Adminoder die RolleDeveloperinnehat:@code { private async Task DoSomething() { var authState = await AuthenticationStateProvider .GetAuthenticationStateAsync(); var user = authState.User; if (user.IsInRole("Admin") || user.IsInRole("Developer")) { ... } else { ... } } }Legen Sie per prozeduralem Code als erforderlich fest, dass der Benutzer sowohl die Rolle
Adminals auch die RolleDeveloperinnehat. Ändern Sie dazu im vorherigen Beispiel das bedingte OR (||) in ein bedingtes AND (&&):if (user.IsInRole("Admin") && user.IsInRole("Developer"))
Jeder der Autorisierungsmechanismen in Controllern der SERVER-App kann die Rolle Admin verwenden, um Benutzer zu autorisieren:
[Authorize]-Attributanweisung (AuthorizeAttribute)[Authorize(Roles = "Admin")]-
if (User.IsInRole("Admin")) { ... }
Mehrere Rollentests werden unterstützt:
Legen Sie mithilfe des -Attributs als erforderlich fest, dass der Benutzer
Admindie RolleDeveloperdie Rolle[Authorize]innehat:[Authorize(Roles = "Admin, Developer")]Legen Sie mithilfe des -Attributs als erforderlich fest, dass der Benutzer
Admindie RolleDeveloperdie Rolle[Authorize]innehat:[Authorize(Roles = "Admin")] [Authorize(Roles = "Developer")]Legen Sie per prozeduralem Code als erforderlich fest, dass der Benutzer entweder die Rolle
Adminoder die RolleDeveloperinnehat: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 ... }Legen Sie per prozeduralem Code als erforderlich fest, dass der Benutzer sowohl die Rolle
Adminals auch die RolleDeveloperinnehat. Ändern Sie dazu im vorherigen Beispiel das bedingte OR (||) in ein bedingtes AND (&&):if (User.IsInRole("Admin") && User.IsInRole("Developer"))
Da bei Zeichenfolgenvergleichen in .NET zwischen Groß- und Kleinschreibung unterschieden wird, wird auch beim Abgleich von Rollennamen zwischen Groß- und Kleinschreibung unterschieden. Beispielsweise wird Admin (mit Großbuchstabe A) nicht als dieselbe Rolle wie admin (mit Kleinbuchstabe a) behandelt.
Die Pascal-Schreibweise wird in der Regel für Rollennamen (z. B. BillingAdministrator) verwendet, aber die Verwendung der Pascal-Schreibweise ist keine strenge Anforderung. Unterschiedliche Groß-/Kleinschreibungen wie Camel Case, Kebab Case und Snake Case sind zulässig. Die Verwendung von Leerzeichen in Rollennamen ist ebenfalls ungewöhnlich, aber zulässig. Beispielsweise ist billing administrator ein ungewöhnliches Rollennamenformat in .NET-Apps, aber gültig.
Weitere Ressourcen
- Rollenvorlagen-IDs (Entra-Dokumentation)
-
groupMembershipClaimsAttribut (Entra-Dokumentation) - Anwendungsrollen zu Ihrer Anwendung hinzufügen und im Token empfangen (Entra-Dokumentation)
- Anwendungsrollen (Azure-Dokumentation)
- Anspruchsbasierte Autorisierung in ASP.NET Core
- Rollenbasierte Autorisierung in ASP.NET Core
- Authentifizierung und Autorisierung in ASP.NET Core Blazor