Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel implementeert u autorisatie in ASP.NET Core web-API's met behulp van Microsoft. Identity.Web. U valideert bereiken (gedelegeerde machtigingen) en app-machtigingen (toepassingsmachtigingen) om de toegang tot beveiligde resources te beheren. In de voorbeelden wordt Microsoft Entra ID gebruikt als id-provider.
Inzicht in autorisatieconcepten
In deze sectie worden de belangrijkste verschillen tussen verificatie en autorisatie beschreven en wordt beschreven wat Microsoft. Identity.Web valideert in toegangstokens.
Verificatie versus autorisatie
| Concept | Purpose | Resultaat |
|---|---|---|
| Authentication | Identiteit verifiëren | 401 Niet geautoriseerd als mislukt |
| Authorization | Machtigingen controleren | 403 Verboden indien onvoldoende |
Wat wordt gevalideerd
Wanneer een web-API een toegangstoken ontvangt, Microsoft. Identity.Web valideert:
- Tokenhandtekening - Is het afkomstig van een vertrouwde instantie?
- Token gebruikers - is het bedoeld voor deze API?
- Verloop van token - Is het nog steeds geldig?
- Scopes/rollen - Heeft de client-app of het onderwerp (gebruiker) de juiste machtigingen?
Deze handleiding is gericht op #4: toepassingsbereiken en app-machtigingen valideren.
Bereiken (gedelegeerde machtigingen)
Toepassingen zijn van toepassing wanneer een gebruiker machtigingen voor een app delegeert om namens hem of haar te handelen (bijvoorbeeld een web-API die namens een aangemelde gebruiker wordt aangeroepen).
| Het detail | Waarde |
|---|---|
| Tokenclaim |
scp of scope (client-app); roles (gebruiker) |
| Voorbeeldwaarden |
"access_as_user", "User.Read", "Files.ReadWrite" |
App-machtigingen (toepassingsmachtigingen)
App-machtigingen zijn van toepassing wanneer een app de web-API aanroept als zichzelf zonder gebruikerscontext, zoals een daemon of achtergrondservice met behulp van clientreferenties.
| Het detail | Waarde |
|---|---|
| Tokenclaim | roles |
| Voorbeeldwaarden |
"Mail.Read.All", "User.Read.All" |
Scopes valideren met RequiredScope
Het RequiredScope kenmerk controleert of het toegangstoken ten minste één van de gespecificeerde scopes bevat. Gebruik dit kenmerk wanneer uw API alleen door de gebruiker gedelegeerde aanvragen verwerkt.
Scopevalidatie instellen
Volg deze stappen om bereikvalidatie in te schakelen in uw API.
1. Autorisatie inschakelen in uw API:
Verificatie- en autorisatieservices toevoegen aan uw toepassingspijplijn:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization(); // Required for authorization
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization(); // Must be after UseAuthentication
app.MapControllers();
app.Run();
2. Controllers of acties beveiligen:
Pas de [Authorize] en [RequiredScope] kenmerken toe op uw controller of afzonderlijke acties:
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web.Resource;
[Authorize]
[RequiredScope("access_as_user")]
public class TodoListController : ControllerBase
{
[HttpGet]
public IActionResult GetTodos()
{
// Only accessible if token has "access_as_user" scope
return Ok(new[] { "Todo 1", "Todo 2" });
}
}
Scopepatronen implementeren
Kies het patroon dat het beste past bij hoe u schalen beheert in uw toepassing.
Patroon 1: vastgelegde bereiken
Gebruik dit patroon wanneer de scopes vast en bekend zijn tijdens de ontwikkeling.
[Authorize]
[RequiredScope("access_as_user")]
public class TodoListController : ControllerBase
{
// All actions require "access_as_user" scope
}
Als u een van meerdere scopes wilt accepteren, vermeld ze dan als parameters:
[Authorize]
[RequiredScope("read", "write", "admin")]
public class TodoListController : ControllerBase
{
// Token must have "read" OR "write" OR "admin"
}
Scopen vanuit configuratie
Gebruik dit patroon wanneer scopes per omgeving configureerbaar moeten zijn. Definieer de scopen in uw configuratiebestand.
appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-api-client-id",
"Scopes": "access_as_user read write"
}
}
Verwijs naar de configuratiesleutel in uw controller:
[Authorize]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class TodoListController : ControllerBase
{
// Scopes read from configuration
}
Met deze methode kunt u de scopes wijzigen zonder opnieuw te moeten compileren.
Patroon 3: Toepassingsgebied op actieniveau
Gebruik dit patroon wanneer voor verschillende acties verschillende machtigingen zijn vereist. Toepassen [RequiredScope] op afzonderlijke actiemethoden:
[Authorize]
public class TodoListController : ControllerBase
{
[HttpGet]
[RequiredScope("read")]
public IActionResult GetTodos()
{
return Ok(todos);
}
[HttpPost]
[RequiredScope("write")]
public IActionResult CreateTodo([FromBody] Todo todo)
{
// Only tokens with "write" scope can create
return CreatedAtAction(nameof(GetTodos), todo);
}
[HttpDelete("{id}")]
[RequiredScope("admin")]
public IActionResult DeleteTodo(int id)
{
// Only tokens with "admin" scope can delete
return NoContent();
}
}
Begrijp de validatiestroom
Wanneer een aanvraag binnenkomt, verwerkt de middleware deze in de volgende volgorde:
- ASP.NET Core verificatie-middleware valideert het token
-
RequiredScopekenmerk controleert op descpofscopeclaim - Als het token ten minste één overeenkomend bereik bevat, wordt de aanvraag voortgezet.
- Als er geen overeenkomend bereik wordt gevonden, retourneert de API een 403 Verboden antwoord.
In het volgende voorbeeld ziet u een typische foutreactie:
{
"error": "insufficient_scope",
"error_description": "The token does not have the required scope 'access_as_user'."
}
App-machtigingen valideren met RequiredScopeOrAppPermission
Het RequiredScopeOrAppPermission kenmerk valideert bereiken (gedelegeerd) of app-machtigingen (toepassing). Gebruik dit kenmerk wanneer uw API zowel door de gebruiker gedelegeerde apps als daemon-/service-apps van hetzelfde eindpunt bedient.
Als uw API alleen door de gebruiker gedelegeerde aanvragen verwerkt, moet u in plaats daarvan RequiredScope gebruiken.
Validatie van bereik- of app-machtigingen instellen
Pas het kenmerk toe om een van de tokentypen te accepteren:
using Microsoft.Identity.Web.Resource;
[Authorize]
[RequiredScopeOrAppPermission(
AcceptedScope = new[] { "access_as_user" },
AcceptedAppPermission = new[] { "TodoList.ReadWrite.All" }
)]
public class TodoListController : ControllerBase
{
[HttpGet]
public IActionResult GetTodos()
{
// Accessible with EITHER:
// - User-delegated token with "access_as_user" scope, OR
// - App-only token with "TodoList.ReadWrite.All" app permission
return Ok(todos);
}
}
App-machtigingen configureren vanuit instellingen
Sla scopes en app-machtigingen op binnen de configuratie om ze te wijzigen zonder hercompilatie.
appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-api-client-id",
"Scopes": "access_as_user",
"AppPermissions": "TodoList.ReadWrite.All TodoList.Admin"
}
}
Raadpleeg de configuratiesleutels in uw controller:
[Authorize]
[RequiredScopeOrAppPermission(
RequiredScopesConfigurationKey = "AzureAd:Scopes",
RequiredAppPermissionsConfigurationKey = "AzureAd:AppPermissions"
)]
public class TodoListController : ControllerBase
{
// Scopes and app permissions from configuration
}
Verschillen tussen tokenclaims vergelijken
In de volgende tabel ziet u hoe claims verschillen tussen door de gebruiker gedelegeerde tokens en alleen-app-tokens.
| Token type | Aanspraak | Voorbeeldwaarde |
|---|---|---|
| Door de gebruiker gedelegeerd |
scp of scope |
"access_as_user User.Read" |
| Alleen voor app | roles |
["TodoList.ReadWrite.All"] |
In het volgende voorbeeld ziet u een door de gebruiker gedelegeerd token:
{
"aud": "api://your-api-client-id",
"iss": "https://login.microsoftonline.com/.../v2.0",
"scp": "access_as_user",
"sub": "user-object-id",
...
}
In het volgende voorbeeld ziet u een token met alleen apps:
{
"aud": "api://your-api-client-id",
"iss": "https://login.microsoftonline.com/.../v2.0",
"roles": ["TodoList.ReadWrite.All"],
"sub": "app-object-id",
...
}
Autorisatiebeleid maken
Gebruik voor complexe autorisatiescenario's ASP.NET Core autorisatiebeleid. Met beleidsregels kunt u regels centraliseren, meerdere vereisten combineren en testbare autorisatielogica schrijven.
| Benefit | Description |
|---|---|
| Gecentraliseerde logica | Autorisatieregels eenmaal definiëren, overal opnieuw gebruiken |
| Samenstelbaar | Meerdere vereisten combineren (scopes + claims + aangepaste logica) |
| Testbaar | Eenvoudiger te testen autorisatielogica per eenheid |
| Buigzaam | Aangepaste vereisten buiten de scope-validatie |
Patroon 1: Een beleid definiëren met RequireScope
Definieer genaamde beleidsregels waarvoor specifieke toepassingsgebieden zijn vereist en raadpleeg deze vervolgens op uw controllers.
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("TodoReadPolicy", policyBuilder =>
{
policyBuilder.RequireScope("read", "access_as_user");
});
options.AddPolicy("TodoWritePolicy", policyBuilder =>
{
policyBuilder.RequireScope("write", "admin");
});
});
var app = builder.Build();
Pas het beleid toe op controlleracties:
[Authorize]
public class TodoListController : ControllerBase
{
[HttpGet]
[Authorize(Policy = "TodoReadPolicy")]
public IActionResult GetTodos()
{
return Ok(todos);
}
[HttpPost]
[Authorize(Policy = "TodoWritePolicy")]
public IActionResult CreateTodo([FromBody] Todo todo)
{
return CreatedAtAction(nameof(GetTodos), todo);
}
}
Patroon 2: Een beleid definiëren met ScopeAuthorizationRequirement
Gebruik ScopeAuthorizationRequirement voor meer expliciete scope-eisen:
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.Resource;
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CustomPolicy", policyBuilder =>
{
policyBuilder.AddRequirements(
new ScopeAuthorizationRequirement(new[] { "access_as_user" })
);
});
});
Patroon 3: Een standaardbeleid instellen
Stel automatisch een standaardbeleid in dat van toepassing is op alle [Authorize] kenmerken:
builder.Services.AddAuthorization(options =>
{
var defaultPolicy = new AuthorizationPolicyBuilder()
.RequireScope("access_as_user")
.Build();
options.DefaultPolicy = defaultPolicy;
});
Voor elk [Authorize] kenmerk is nu het access_as_user bereik vereist:
[Authorize] // Automatically requires "access_as_user" scope
public class TodoListController : ControllerBase
{
// All actions protected by default policy
}
Patroon 4: Meerdere vereisten combineren
Combineer de reikwijdte-, rol- en verificatievereisten in één beleid:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy", policyBuilder =>
{
policyBuilder.RequireScope("admin");
policyBuilder.RequireRole("Admin"); // Also check role claim
policyBuilder.RequireAuthenticatedUser();
});
});
Patroon 5: Een beleid bouwen op basis van configuratie
Scopes laden vanuit configuratie om beleidsregels omgevingsspecifiek te houden.
var requiredScopes = builder.Configuration["AzureAd:Scopes"]?.Split(' ');
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ApiAccessPolicy", policyBuilder =>
{
if (requiredScopes != null)
{
policyBuilder.RequireScope(requiredScopes);
}
});
});
Aanvragen filteren op tenant
Beperk API-toegang tot tokens van specifieke Microsoft Entra tenants. Dit is handig wanneer uw API met meerdere tenants alleen aanvragen van goedgekeurde klanttenants mag accepteren.
Toegang tot toegestane tenants beperken
Definieer een beleid waarmee de tenant-id-claim wordt gecontroleerd op basis van een acceptatielijst:
builder.Services.AddAuthorization(options =>
{
string[] allowedTenants =
{
"14c2f153-90a7-4689-9db7-9543bf084dad", // Contoso tenant
"af8cc1a0-d2aa-4ca7-b829-00d361edb652", // Fabrikam tenant
"979f4440-75dc-4664-b2e1-2cafa0ac67d1" // Northwind tenant
};
options.AddPolicy("AllowedTenantsOnly", policyBuilder =>
{
policyBuilder.RequireClaim(
"http://schemas.microsoft.com/identity/claims/tenantid",
allowedTenants
);
});
// Apply to all endpoints by default
options.DefaultPolicy = options.GetPolicy("AllowedTenantsOnly");
});
Tenantfiltering configureren via instellingen
Sla toegestane tenant-id's op in de configuratie om ze te beheren zonder codewijzigingen.
appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "your-api-client-id",
"AllowedTenants": [
"14c2f153-90a7-4689-9db7-9543bf084dad",
"af8cc1a0-d2aa-4ca7-b829-00d361edb652"
]
}
}
Lees de tenantlijst en maak het beleid bij het opstarten:
var allowedTenants = builder.Configuration.GetSection("AzureAd:AllowedTenants")
.Get<string[]>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AllowedTenantsOnly", policyBuilder =>
{
policyBuilder.RequireClaim(
"http://schemas.microsoft.com/identity/claims/tenantid",
allowedTenants ?? Array.Empty<string>()
);
});
});
Bereiken combineren met tenantfilters
Maak een beleid waarvoor zowel een geldig bereik als een goedgekeurde tenant is vereist:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("SecureApiAccess", policyBuilder =>
{
// Require specific scope
policyBuilder.RequireScope("access_as_user");
// AND require specific tenant
policyBuilder.RequireClaim(
"http://schemas.microsoft.com/identity/claims/tenantid",
allowedTenants
);
});
});
Best practices volgen
Pas deze aanbevelingen toe om veilige, onderhoudbare autorisatielogica te bouwen.
Aanbevelingen
1. Koppel altijd [Authorize] met validatie van de scope:
[Authorize] // Authentication
[RequiredScope("access_as_user")] // Authorization
public class MyController : ControllerBase { }
2. Gebruik configuratie voor omgevingsspecifieke instellingen:
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
3. Minimale bevoegdheden toepassen:
[HttpGet]
[RequiredScope("read")] // Only read permission needed
[HttpPost]
[RequiredScope("write")] // Write permission for modifications
4. Gebruik beleidsregels voor complexe autorisatie:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
{
policy.RequireScope("admin");
policy.RequireClaim("department", "IT");
});
});
5. Gedetailleerde foutreacties inschakelen tijdens ontwikkeling:
if (builder.Environment.IsDevelopment())
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
}
Dingen die je niet moet doen
1. Sla [Authorize] niet over wanneer u RequiredScope gebruikt:
// Wrong - RequiredScope won't work without [Authorize]
[RequiredScope("access_as_user")]
public class MyController : ControllerBase { }
// Correct
[Authorize]
[RequiredScope("access_as_user")]
public class MyController : ControllerBase { }
2. Codeer geen tenant-id's in productie:
// Wrong
policyBuilder.RequireClaim("tid", "14c2f153-90a7-4689-9db7-9543bf084dad");
// Better - use configuration
var tenants = Configuration.GetSection("AllowedTenants").Get<string[]>();
policyBuilder.RequireClaim("tid", tenants);
3. Verwar toepassingen niet met rollen:
// Wrong - This checks roles claim, not scopes
[RequiredScope("Admin")] // "Admin" is typically a role, not a scope
// Correct
[RequiredScope("access_as_user")] // Scope
[Authorize(Roles = "Admin")] // Role
4. Geef geen gevoelige bereikinformatie weer in productiefoutberichten:
Configureer de juiste logboekregistratieniveaus en foutafhandeling voor productieomgevingen.
Autorisatieproblemen oplossen
Gebruik de volgende richtlijnen om veelvoorkomende autorisatieproblemen vast te stellen.
403 Verboden - ontbrekend bereik
Fout: API retourneert 403, zelfs met een geldig token.
Diagnose:
- Decodeer het token op jwt.ms.
- Controleer de
scpofscopeaanspraak. - Controleer of de waarde overeenkomt met uw
RequiredScopekenmerk.
Solution:
- Zorg ervoor dat de client-app het juiste bereik aanvraagt bij het verkrijgen van het token.
- Controleer of het bereik beschikbaar is in de registratie van de API-app in Microsoft Entra.
- Ververleent beheerders toestemming indien nodig.
RequiredScope werkt niet
Symptoom: Het kenmerk lijkt te worden genegeerd.
Controleer:
- Hebt u het
[Authorize]kenmerk toegevoegd? - Wordt
app.UseAuthorization()ernaapp.UseAuthentication()gebeld? - Is
services.AddAuthorization()geregistreerd?
Configuratiesleutel niet gevonden
Fout: De scopevalidatie faalt geruisloos.
Controleer:
{
"AzureAd": {
"Scopes": "access_as_user" // Matches RequiredScopesConfigurationKey
}
}
Zorg ervoor dat het configuratiepad exact overeenkomt.