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 ausgegeben werden. 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 identity kann mehrere Ansprüche mit mehreren 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 prüft die EmployeeOnly-Richtlinie, ob ein EmployeeNumber-Anspruch auf die aktuelle Identität vorliegt.

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. Der Rest der App, der keine Richtlinien auf der Razor Page-Handler-Ebene benötigt, 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 vorangegangenen Beispiel kann jede Identität, die die EmployeeOnly-Richtlinie erfüllt, auf die Payslip-Aktion zugreifen, da diese Richtlinie auf dem Controller durchgesetzt wird. Um die UpdateSalary-Aktion aufzurufen, muss die Identität jedoch beide Richtlinien, die Richtlinie EmployeeOnly und die Richtlinie HumanResources, 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 ausgegeben werden. 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 identity kann mehrere Ansprüche mit mehreren 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 prüft die Richtlinie EmployeeOnly, ob ein EmployeeNumber-Anspruch auf der aktuellen identity vorliegt.

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. Zum Beispiel:

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

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

Im obigen Beispiel kann jede identity, die die EmployeeOnly-Richtlinie erfüllt, auf die Payslip-Aktion zugreifen, da diese Richtlinie auf dem Controller durchgesetzt wird. Um die UpdateSalary-Aktion jedoch ausführen zu können, muss die Identität sowohl die EmployeeOnly-Richtlinie als auch 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 ausgegeben werden. 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 identity kann mehrere Ansprüche mit mehreren 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 prüft die EmployeeOnly-Richtlinie, ob ein EmployeeNumber-Anspruch auf die aktuelle Identität vorliegt.

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. Zum 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.