Richtlinien-basierte Autorisierung in einer serverseitigen Blazor-Webanwendung

Einführung

Aktuell habe ich eine perfekt laufende ASP.NET-Core-Webanwendung mit serverseitigem Blazor in .NET 5. Diese Anwendung nutzt Azure Active Directory (AAD) um Benutzer zu autorisieren und verwendet dabei das [Authorize]-Attribut, ohne weitere Parameter.

Microsoft schreibt in ihrer Dokumentation:

Wenn weder Roles noch Policy angegeben wird, verwendet [Authorize] die Standardrichtlinie und behandelt:

  • Authentifizierte (angemeldete) Benutzer als autorisiert.
  • Nicht authentifizierte (abgemeldete) Benutzer als nicht autorisiert.

Dies funktioniert soweit alles perfekt.

In meiner Startup-Klasse mache ich folgendes:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMicrosoftIdentityWebAppAuthentication(Configuration);

    ...
}

public void public void Configure(IApplicationBuilder app)
{
    ...

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

    ...
}

Und in meinen Blazor-Seiten, z. B. in „Index.razor“, mache ich folgendes:

@attribute [Authorize]

Obgleich es so aussieht als mache es keinen Unterschied, ob ich das Autorize-Attribut angebe oder nicht (ggf. weil ich in „App.razor“ eine <AuthorizeRouteView> nutze und nicht nur eine <RouteView>).

Mein Ziel

Ich möchte Richtlinien-basierte Autorisierung machen.

D. h. in meiner Blazor-Seite möchte ich beispielsweise das hier schreiben:

@attribute [Authorize(Policy = "my-policy")]

Der Weg

Um dies zu erreichen, habe ich die Startup-Klasse so erweitert:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMicrosoftIdentityWebAppAuthentication(Configuration);

    services.AddAuthorization(
        options =>
        {
            options.AddPolicy(
                "my-policy",
                policy => policy.Requirements.Add(
                    new MyPolicyAuthorizationRequirement()));
            });

    services.AddSingleton<IAuthorizationHandler, 
                          MyPolicyAuthorizationHandler>();
    ...
}

D. h. ich habe ein Aufruf zu AddAuthorization ergänzt und meine eigene Klasse ergänzt, die die Anforderung modelliert.

Außerdem habe ich via AddSingleton meinen Autorisierungshandler ergänzt.

Anschließend hat das Framework erfolgreich die Prüfung durchgeführt.