Informacje o autoryzacji w mikrousługach .NET i aplikacjach internetowych

Napiwek

Ta zawartość jest fragmentem książki eBook, architektury mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET dostępnych na platformie .NET Docs lub jako bezpłatnego pliku PDF, który można odczytać w trybie offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Po uwierzytelnieniu ASP.NET core internetowych interfejsów API muszą autoryzować dostęp. Ten proces umożliwia usłudze udostępnianie interfejsów API niektórym uwierzytelnionymi użytkownikom, ale nie wszystkim. Autoryzację można wykonywać na podstawie ról użytkowników lub na podstawie zasad niestandardowych, które mogą obejmować inspekcję oświadczeń lub innych heurystyki.

Ograniczenie dostępu do trasy ASP.NET Core MVC jest tak proste, jak zastosowanie atrybutu Authorize do metody akcji (lub do klasy kontrolera, jeśli wszystkie akcje kontrolera wymagają autoryzacji), jak pokazano w poniższym przykładzie:

public class AccountController : Controller
{
    public ActionResult Login()
    {
    }

    [Authorize]
    public ActionResult Logout()
    {
    }
}

Domyślnie dodanie atrybutu Authorize bez parametrów spowoduje ograniczenie dostępu do uwierzytelnionych użytkowników dla tego kontrolera lub akcji. Aby dodatkowo ograniczyć dostęp do interfejsu API tylko dla określonych użytkowników, można rozszerzyć atrybut w celu określenia wymaganych ról lub zasad, które użytkownicy muszą spełnić.

Implementowanie autoryzacji opartej na rolach

ASP.NET Core Identity ma wbudowaną koncepcję ról. Oprócz użytkowników usługa ASP.NET Core Identity przechowuje informacje o różnych rolach używanych przez aplikację i śledzi, którzy użytkownicy są przypisani do których ról. Te przypisania można zmienić programowo przy RoleManager użyciu typu, który aktualizuje role w trwałym magazynie, oraz UserManager typ, który może udzielać lub odwoływać role od użytkowników.

Jeśli uwierzytelniasz się przy użyciu tokenów elementu nośnego JWT, oprogramowanie pośredniczące uwierzytelniania JWT platformy ASP.NET Core JWT wypełni role użytkownika na podstawie oświadczeń ról znalezionych w tokenie. Aby ograniczyć dostęp do akcji MVC lub kontrolera dla użytkowników w określonych rolach, możesz uwzględnić parametr Role w annotation (atrybut), jak pokazano w poniższym fragmentacji kodu:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult ShutDown()
    {
    }
}

W tym przykładzie tylko użytkownicy w rolach Administracja istrator lub PowerUser mogą uzyskiwać dostęp do interfejsów API na kontrolerze ControlPanel (na przykład wykonywania akcji SetTime). Interfejs API ShutDown jest dodatkowo ograniczony, aby zezwolić na dostęp tylko użytkownikom w roli Administracja istratora.

Aby wymagać, aby użytkownik był w wielu rolach, należy użyć wielu atrybutów Autoryzacja, jak pokazano w poniższym przykładzie:

[Authorize(Roles = "Administrator, PowerUser")]
[Authorize(Roles = "RemoteEmployee ")]
[Authorize(Policy = "CustomPolicy")]
public ActionResult API1 ()
{
}

W tym przykładzie, aby wywołać interfejs API1, użytkownik musi:

  • Bądź w roli Administracja istratora lub użytkownika PowerUser i

  • Bądź w roli RemoteEmployee i

  • Spełnij wymagania niestandardowej procedury obsługi dla autoryzacji CustomPolicy.

Implementowanie autoryzacji opartej na zasadach

Niestandardowe reguły autoryzacji można również pisać przy użyciu zasad autoryzacji. Ta sekcja zawiera omówienie. Aby uzyskać więcej informacji, zobacz warsztaty autoryzacji ASP.NET.

Niestandardowe zasady autoryzacji są rejestrowane w metodzie Startup.ConfigureServices przy użyciu usługi. AddAuthorization, metoda. Ta metoda przyjmuje delegata, który konfiguruje argument AuthorizationOptions.

services.AddAuthorization(options =>
{
    options.AddPolicy("AdministratorsOnly", policy =>
        policy.RequireRole("Administrator"));

    options.AddPolicy("EmployeesOnly", policy =>
        policy.RequireClaim("EmployeeNumber"));

    options.AddPolicy("Over21", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(21)));
});

Jak pokazano w przykładzie, zasady mogą być skojarzone z różnymi typami wymagań. Po zarejestrowaniu zasad można je zastosować do akcji lub kontrolera, przekazując nazwę zasad jako argument zasad atrybutu Autoryzowanie (na przykład [Authorize(Policy="EmployeesOnly")]) Zasady mogą mieć wiele wymagań, a nie tylko jedno (jak pokazano w tych przykładach).

W poprzednim przykładzie pierwsze wywołanie AddPolicy jest po prostu alternatywnym sposobem autoryzowania przez rolę. W przypadku [Authorize(Policy="AdministratorsOnly")] zastosowania do interfejsu API tylko użytkownicy w roli Administracja istratora będą mogli uzyskać do niego dostęp.

Drugie AddPolicy wywołanie demonstruje prosty sposób, aby wymagać, aby określone oświadczenie było obecne dla użytkownika. Metoda RequireClaim również opcjonalnie przyjmuje oczekiwane wartości dla oświadczenia. Jeśli określono wartości, wymaganie jest spełnione tylko wtedy, gdy użytkownik ma zarówno oświadczenie poprawnego typu, jak i jedną z określonych wartości. Jeśli używasz oprogramowania pośredniczącego uwierzytelniania elementu nośnego JWT, wszystkie właściwości JWT będą dostępne jako oświadczenia użytkownika.

Najbardziej interesujące zasady pokazane tutaj znajdują się w trzeciej AddPolicy metodzie, ponieważ korzystają z niestandardowego wymagania autoryzacji. Korzystając z niestandardowych wymagań dotyczących autoryzacji, możesz mieć dużą kontrolę nad sposobem wykonywania autoryzacji. Aby to zadziałało, należy zaimplementować następujące typy:

  • Typ wymagań, który pochodzi z IAuthorizationRequirement elementu i zawiera pola określające szczegóły wymagania. W tym przykładzie jest to pole wiekowe dla przykładowego MinimumAgeRequirement typu.

  • Procedura obsługi, która implementuje AuthorizationHandler<TRequirement>element , gdzie T jest typem IAuthorizationRequirement , który może spełnić program obsługi. Procedura obsługi musi zaimplementować metodę HandleRequirementAsync , która sprawdza, czy określony kontekst zawierający informacje o użytkowniku spełnia wymagania.

Jeśli użytkownik spełnia wymaganie, wywołanie polecenia context.Succeed wskaże, że użytkownik jest autoryzowany. Jeśli istnieje wiele sposobów, na które użytkownik może spełnić wymaganie autoryzacji, można utworzyć wiele procedur obsługi.

Oprócz rejestrowania niestandardowych wymagań zasad za AddPolicy pomocą wywołań należy również zarejestrować niestandardowe procedury obsługi wymagań za pomocą wstrzykiwania zależności (services.AddTransient<IAuthorizationHandler, MinimumAgeHandler>()).

Przykład niestandardowego wymagania autoryzacji i procedury obsługi sprawdzania wieku użytkownika (na DateOfBirth podstawie oświadczenia) jest dostępny w dokumentacji autoryzacji ASP.NET Core.

Autoryzacja i minimalne interfejsy API

ASP.NET obsługuje minimalne interfejsy API jako alternatywę dla interfejsów API opartych na kontrolerach. Zasady autoryzacji to zalecany sposób konfigurowania autoryzacji dla minimalnych interfejsów API, jak pokazano w tym przykładzie:

// Program.cs
builder.Services.AddAuthorizationBuilder()
  .AddPolicy("admin_greetings", policy =>
        policy
            .RequireRole("admin")
            .RequireScope("greetings_api"));

// build the app

app.MapGet("/hello", () => "Hello world!")
  .RequireAuthorization("admin_greetings");

Dodatkowe zasoby