Anspruchsbasierte Autorisierung in ASP.NET Core

Wenn eine Identität erstellt wird, können ihr ein oder mehrere Ansprüche zugewiesen werden, die von einer vertrauenswürdigen Partei ausgestellt wurden. Ein Anspruch ist ein Name-Wert-Paar, das den Antragsteller repräsentiert, nicht jedoch die Aufgaben, die dieser ausführen kann. Beispielsweise können Sie über einen Führerschein verfügen, der von einer lokalen Führerscheinbehörde ausgestellt wurde. Ihr Führerschein enthält Ihr Geburtsdatum. In diesem Fall wäre der Anspruchsname DateOfBirth, der Anspruchswert wäre Ihr Geburtsdatum (z. B. 8th June 1970), und der Aussteller wäre die Führerscheinbehörde. Die anspruchsbasierte Autorisierung überprüft ganz grundsätzlich den Wert eines Anspruchs und erlaubt den Zugriff auf eine Ressource basierend auf diesem Wert. Wenn Sie beispielsweise einen Nachtclub besuchen möchten, kann der Autorisierungsprozess wie folgt aussehen:

Das Personal an der Tür wertet den Wert Ihres Geburtsdatumsanspruchs und die Vertrauensstellung des Ausstellers (der Führerscheinbehörde) aus, bevor es Ihnen Zugang gewährt.

Eine Identität kann mehrere Ansprüche mit verschiedenen Werten und mehrere Ansprüche desselben Typs enthalten.

Hinzufügen von Anspruchsüberprüfungen

Anspruchsbasierte Autorisierungsüberprüfungen:

  • sind deklarativ.
  • werden auf Razor Pages, Controller oder Aktionen innerhalb eines Controllers angewandt.
  • können nicht auf Ebene der Razor Pages-Handler angewandt werden, sondern müssen auf die Seite angewandt werden.

Ansprüche im Code geben Ansprüche an, die aktuelle Benutzer*innen besitzen müssen, und optional den Wert, den der Anspruch für den Zugriff auf die angeforderte Ressource enthalten muss. Anspruchsanforderungen sind richtlinienbasiert. Entwickler*innen müssen eine Richtlinie erstellen und registrieren, die die Anspruchsanforderungen ausdrückt.

Der einfachste Typ einer Anspruchsrichtlinie sucht nach dem Vorhandensein eines Anspruchs, aber überprüft den Wert nicht.

Erstellen und registrieren Sie die Richtlinie, und rufen Sie UseAuthorization auf. Die Registrierung der Richtlinie erfolgt im Rahmen der Konfiguration des Autorisierungsdiensts, in der Regel in der Datei Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
   options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

In diesem Fall überprüft die EmployeeOnly-Richtlinie, ob für die aktuelle Identität ein EmployeeNumber-Anspruch vorhanden ist.

Sie wenden die Richtlinie mithilfe der Policy-Eigenschaft im [Authorize]-Attribut an, um den Richtliniennamen anzugeben.

[Authorize(Policy = "EmployeeOnly")]
public IActionResult VacationBalance()
{
    return View();
}

Das [Authorize]-Attribut kann auf den gesamten Controller oder Razor Pages angewandt werden. In diesem Fall wird nur Identitäten, die der Richtlinie entsprechen, Zugriff auf eine Aktion auf dem Controller gewährt.

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public ActionResult VacationBalance()
    {
        return View();
    }

    [AllowAnonymous]
    public ActionResult VacationPolicy()
    {
        return View();
    }
}

Der folgende Code wendet das [Authorize]-Attribut auf eine Razor-Seite an:

[Authorize(Policy = "EmployeeOnly")]
public class IndexModel : PageModel
{
    public void OnGet()
    {

    }
}

Richtlinien können nicht auf Ebene der Razor Pages-Handler angewandt werden, sie müssen auf die Seite angewandt werden.

Wenn Sie über einen Controller verfügen, der durch das [Authorize]-Attribut geschützt ist, aber anonymen Zugriff auf bestimmte Aktionen zulassen möchten, wenden Sie das AllowAnonymousAttribute-Attribut an.

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public ActionResult VacationBalance()
    {
        return View();
    }

    [AllowAnonymous]
    public ActionResult VacationPolicy()
    {
        return View();
    }
}

Da Richtlinien nicht auf Ebene der Razor-Seitenhandler angewandt werden können, wird empfohlen, einen Controller zu verwenden, wenn Richtlinien auf Seitenhandlerebene angewandt werden müssen. Die restliche App, die keine Richtlinien auf Ebene der Razor-Seitenhandler erfordert, kann Razor Pages verwenden.

Die meisten Ansprüche weisen einen Wert auf. Sie können beim Erstellen der Richtlinie eine Liste mit zulässigen Werten angeben. Das folgende Beispiel ist nur für Mitarbeiter*innen erfolgreich, deren Mitarbeiternummer 1, 2, 3, 4 oder 5 lautet.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("Founders", policy =>
                      policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

Hinzufügen einer generischen Anspruchsüberprüfung

Wenn der Anspruchswert kein einzelner Wert ist oder wenn eine Transformation erforderlich ist, verwenden Sie RequireAssertion. Weitere Informationen finden Sie unter Verwenden einer Funktion zum Erfüllen einer Richtlinie.

Auswerten mehrerer Richtlinien

Wenn mehrere Richtlinien auf Controller- und Aktionsebene angewandt werden, müssen alle Richtlinien erfüllt werden, bevor der Zugriff gewährt wird:

[Authorize(Policy = "EmployeeOnly")]
public class SalaryController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Payslip()
    {
        return View();
    }

    [Authorize(Policy = "HumanResources")]
    public IActionResult UpdateSalary()
    {
        return View();
    }
}

Im obigen Beispiel kann jede Identität, die die EmployeeOnly-Richtlinie erfüllt, auf die Payslip-Aktion zugreifen, da diese Richtlinie auf dem Controller erzwungen wird. Um die UpdateSalary-Aktion aufzurufen, muss die Identität jedoch die EmployeeOnly-Richtlinie und die HumanResources-Richtlinie erfüllen.

Wenn Sie komplexere Richtlinien benötigen, z. B. die Übernahme eines Geburtsdatumsanspruchs, die Berechnung eines Alters daraus, und die Überprüfung, ob das Alter 21 oder höher ist, müssen Sie benutzerdefinierte Richtlinienhandler schreiben.

Im folgenden Beispiel müssen beide Seitenhandlermethoden die EmployeeOnly-Richtlinie und die HumanResources-Richtlinie erfüllen:

[Authorize(Policy = "EmployeeOnly")]
[Authorize(Policy = "HumanResources")]
public class SalaryModel : PageModel
{
    public ContentResult OnGetPayStub()
    {
        return Content("OnGetPayStub");
    }

    public ContentResult OnGetSalary()
    {
        return Content("OnGetSalary");
    }
}

Wenn eine Identität erstellt wird, können ihr ein oder mehrere Ansprüche zugewiesen werden, die von einer vertrauenswürdigen Partei ausgestellt wurden. Ein Anspruch ist ein Name-Wert-Paar, das den Antragsteller repräsentiert, nicht jedoch die Aufgaben, die dieser ausführen kann. Beispielsweise können Sie über einen Führerschein verfügen, der von einer lokalen Führerscheinbehörde ausgestellt wurde. Ihr Führerschein enthält Ihr Geburtsdatum. In diesem Fall wäre der Anspruchsname DateOfBirth, der Anspruchswert wäre Ihr Geburtsdatum (z. B. 8th June 1970), und der Aussteller wäre die Führerscheinbehörde. Die anspruchsbasierte Autorisierung überprüft ganz grundsätzlich den Wert eines Anspruchs und erlaubt den Zugriff auf eine Ressource basierend auf diesem Wert. Wenn Sie beispielsweise einen Nachtclub besuchen möchten, kann der Autorisierungsprozess wie folgt aussehen:

Das Personal an der Tür wertet den Wert Ihres Geburtsdatumsanspruchs und die Vertrauensstellung des Ausstellers (der Führerscheinbehörde) aus, bevor es Ihnen Zugang gewährt.

Eine Identität kann mehrere Ansprüche mit verschiedenen Werten und mehrere Ansprüche desselben Typs enthalten.

Hinzufügen von Anspruchsüberprüfungen

Anspruchsbasierte Autorisierungsüberprüfungen sind deklarativ. Entwickler*innen betten sie in den Code für einen Controller oder eine Aktion innerhalb eines Controllers ein und geben Ansprüche an, die die aktuellen Benutzer*innen besitzen müssen. Optional können sie auch den Wert angeben, den der Anspruch für den Zugriff auf die angeforderte Ressource enthalten muss. Anspruchsanforderungen sind richtlinienbasiert. Entwickler*innen müssen eine Richtlinie erstellen und registrieren, die die Anspruchsanforderungen ausdrückt.

Der einfachste Typ einer Anspruchsrichtlinie sucht nach dem Vorhandensein eines Anspruchs, aber überprüft den Wert nicht.

Erstellen und registrieren Sie die Richtlinie. Dies erfolgt im Rahmen der Konfiguration des Autorisierungsdiensts, die normalerweise in ConfigureServices() Ihrer Datei Startup.cs enthalten ist.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
    });
}

Rufen Sie Configure in UseAuthorization auf. Der folgende Code wird von den ASP.NET Core-Web-App-Vorlagen generiert:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseMigrationsEndPoint();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

In diesem Fall überprüft die EmployeeOnly-Richtlinie, ob für die aktuelle Identität ein EmployeeNumber-Anspruch vorhanden ist.

Sie wenden die Richtlinie dann mithilfe der Policy-Eigenschaft im [Authorize]-Attribut an, um den Richtliniennamen anzugeben.

[Authorize(Policy = "EmployeeOnly")]
public IActionResult VacationBalance()
{
    return View();
}

Das [Authorize]-Attribut kann auf den gesamten Controller angewandt werden. In diesem Fall wird nur den Identitäten, die der Richtlinie entsprechen, Zugriff auf eine Aktion auf dem Controller gewährt.

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public ActionResult VacationBalance()
    {
    }
}

Wenn Sie über einen Controller verfügen, der durch das [Authorize]-Attribut geschützt ist, aber anonymen Zugriff auf bestimmte Aktionen zulassen möchten, wenden Sie das AllowAnonymousAttribute-Attribut an.

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public ActionResult VacationBalance()
    {
    }

    [AllowAnonymous]
    public ActionResult VacationPolicy()
    {
    }
}

Die meisten Ansprüche weisen einen Wert auf. Sie können beim Erstellen der Richtlinie eine Liste mit zulässigen Werten angeben. Das folgende Beispiel ist nur für Mitarbeiter*innen erfolgreich, deren Mitarbeiternummer 1, 2, 3, 4 oder 5 lautet.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("Founders", policy =>
                          policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
    });
}

Hinzufügen einer generischen Anspruchsüberprüfung

Wenn der Anspruchswert kein einzelner Wert ist oder wenn eine Transformation erforderlich ist, verwenden Sie RequireAssertion. Weitere Informationen finden Sie unter Verwenden einer Funktion zum Erfüllen einer Richtlinie.

Auswerten mehrerer Richtlinien

Wenn Sie mehrere Richtlinien auf einen Controller oder eine Aktion anwenden, müssen alle Richtlinien erfüllt sein, damit Zugriff gewährt wird. Beispiel:

[Authorize(Policy = "EmployeeOnly")]
public class SalaryController : Controller
{
    public ActionResult Payslip()
    {
    }

    [Authorize(Policy = "HumanResources")]
    public ActionResult UpdateSalary()
    {
    }
}

Im obigen Beispiel kann jede Identität, die die EmployeeOnly-Richtlinie erfüllt, auf die Payslip-Aktion zugreifen, da diese Richtlinie auf dem Controller erzwungen wird. Um die UpdateSalary-Aktion aufzurufen, muss die Identität jedoch die EmployeeOnly-Richtlinie und die HumanResources-Richtlinie erfüllen.

Wenn Sie komplexere Richtlinien benötigen, z. B. die Übernahme eines Geburtsdatumsanspruchs, die Berechnung eines Alters daraus, und die Überprüfung, ob das Alter 21 oder höher ist, müssen Sie benutzerdefinierte Richtlinienhandler schreiben.

Wenn eine Identität erstellt wird, können ihr ein oder mehrere Ansprüche zugewiesen werden, die von einer vertrauenswürdigen Partei ausgestellt wurden. Ein Anspruch ist ein Name-Wert-Paar, das den Antragsteller repräsentiert, nicht jedoch die Aufgaben, die dieser ausführen kann. Beispielsweise können Sie über einen Führerschein verfügen, der von einer lokalen Führerscheinbehörde ausgestellt wurde. Ihr Führerschein enthält Ihr Geburtsdatum. In diesem Fall wäre der Anspruchsname DateOfBirth, der Anspruchswert wäre Ihr Geburtsdatum (z. B. 8th June 1970), und der Aussteller wäre die Führerscheinbehörde. Die anspruchsbasierte Autorisierung überprüft ganz grundsätzlich den Wert eines Anspruchs und erlaubt den Zugriff auf eine Ressource basierend auf diesem Wert. Wenn Sie beispielsweise einen Nachtclub besuchen möchten, kann der Autorisierungsprozess wie folgt aussehen:

Das Personal an der Tür wertet den Wert Ihres Geburtsdatumsanspruchs und die Vertrauensstellung des Ausstellers (der Führerscheinbehörde) aus, bevor es Ihnen Zugang gewährt.

Eine Identität kann mehrere Ansprüche mit verschiedenen Werten und mehrere Ansprüche desselben Typs enthalten.

Hinzufügen von Anspruchsüberprüfungen

Anspruchsbasierte Autorisierungsüberprüfungen sind deklarativ. Entwickler*innen betten sie in den Code für einen Controller oder eine Aktion innerhalb eines Controllers ein und geben Ansprüche an, die die aktuellen Benutzer*innen besitzen müssen. Optional können sie auch den Wert angeben, den der Anspruch für den Zugriff auf die angeforderte Ressource enthalten muss. Anspruchsanforderungen sind richtlinienbasiert. Entwickler*innen müssen eine Richtlinie erstellen und registrieren, die die Anspruchsanforderungen ausdrückt.

Der einfachste Typ einer Anspruchsrichtlinie sucht nach dem Vorhandensein eines Anspruchs, aber überprüft den Wert nicht.

Erstellen und registrieren Sie die Richtlinie. Dies erfolgt im Rahmen der Konfiguration des Autorisierungsdiensts, die normalerweise in ConfigureServices() Ihrer Datei Startup.cs enthalten ist.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
    });
}

In diesem Fall überprüft die EmployeeOnly-Richtlinie, ob für die aktuelle Identität ein EmployeeNumber-Anspruch vorhanden ist.

Sie wenden die Richtlinie dann mithilfe der Policy-Eigenschaft im [Authorize]-Attribut an, um den Richtliniennamen anzugeben.

[Authorize(Policy = "EmployeeOnly")]
public IActionResult VacationBalance()
{
    return View();
}

Das [Authorize]-Attribut kann auf den gesamten Controller angewandt werden. In diesem Fall wird nur den Identitäten, die der Richtlinie entsprechen, Zugriff auf eine Aktion auf dem Controller gewährt.

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public ActionResult VacationBalance()
    {
    }
}

Wenn Sie über einen Controller verfügen, der durch das [Authorize]-Attribut geschützt ist, aber anonymen Zugriff auf bestimmte Aktionen zulassen möchten, wenden Sie das AllowAnonymousAttribute-Attribut an.

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public ActionResult VacationBalance()
    {
    }

    [AllowAnonymous]
    public ActionResult VacationPolicy()
    {
    }
}

Die meisten Ansprüche weisen einen Wert auf. Sie können beim Erstellen der Richtlinie eine Liste mit zulässigen Werten angeben. Das folgende Beispiel ist nur für Mitarbeiter*innen erfolgreich, deren Mitarbeiternummer 1, 2, 3, 4 oder 5 lautet.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("Founders", policy =>
                          policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
    });
}

Hinzufügen einer generischen Anspruchsüberprüfung

Wenn der Anspruchswert kein einzelner Wert ist oder wenn eine Transformation erforderlich ist, verwenden Sie RequireAssertion. Weitere Informationen finden Sie unter Verwenden einer Funktion zum Erfüllen einer Richtlinie.

Auswerten mehrerer Richtlinien

Wenn Sie mehrere Richtlinien auf einen Controller oder eine Aktion anwenden, müssen alle Richtlinien erfüllt sein, damit Zugriff gewährt wird. Beispiel:

[Authorize(Policy = "EmployeeOnly")]
public class SalaryController : Controller
{
    public ActionResult Payslip()
    {
    }

    [Authorize(Policy = "HumanResources")]
    public ActionResult UpdateSalary()
    {
    }
}

Im obigen Beispiel kann jede Identität, die die EmployeeOnly-Richtlinie erfüllt, auf die Payslip-Aktion zugreifen, da diese Richtlinie auf dem Controller erzwungen wird. Um die UpdateSalary-Aktion aufzurufen, muss die Identität jedoch die EmployeeOnly-Richtlinie und die HumanResources-Richtlinie erfüllen.

Wenn Sie komplexere Richtlinien benötigen, z. B. die Übernahme eines Geburtsdatumsanspruchs, die Berechnung eines Alters daraus, und die Überprüfung, ob das Alter 21 oder höher ist, müssen Sie benutzerdefinierte Richtlinienhandler schreiben.