Udostępnij za pomocą


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

Wskazówka

Ta treść jest fragmentem eBooka "Architektura mikrousług .NET dla konteneryzowanych aplikacji .NET", dostępnego na .NET Docs lub jako bezpłatny plik PDF do pobrania i czytania w trybie offline.

Miniatura okładki eBooka „Architektura mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET”.

Po uwierzytelnieniu interfejsy Web API ASP.NET Core 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ć sprawdzenie oświadczeń lub innych heurystyk.

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 zmieniać programowo za pomocą typu RoleManager, który aktualizuje role w trwałej pamięci, oraz typu UserManager, który może przydzielać lub cofać role użytkownikom.

Jeśli uwierzytelniasz się przy użyciu tokenów JWT typu bearer, oprogramowanie pośredniczące uwierzytelniania JWT w ASP.NET Core 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 Roles w adnotacji (atrybut), jak pokazano w poniższym fragmencie 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 Administrator 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 administratorów.

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:

  • Pełnić rolę Administratora lub PowerUsera 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 ASP.NET Authorization.

Niestandardowe zasady autoryzacji są rejestrowane w metodzie Startup.ConfigureServices przy użyciu metody usługi AddAuthorization. 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ę. Jeżeli [Authorize(Policy="AdministratorsOnly")] jest zastosowane do interfejsu API, tylko użytkownicy mający rolę Administratora 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 roszczenia. Jeśli wartości są określone, 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 typu IAuthorizationRequirement i zawiera pola, które określają szczegóły wymagań. W tym przykładzie jest to pole wiekowe dla przykładowego MinimumAgeRequirement typu.

  • Procedura obsługi, która implementuje AuthorizationHandler<TRequirement>, gdzie T jest typem IAuthorizationRequirement, który procedura obsługi może spełnić. 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 pośrednictwem wywołań AddPolicy, należy również zarejestrować niestandardowe procedury obsługi wymagań za pomocą mechanizmu 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 minimalistyczne 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