Laden...

Wie kann ich eine Policy mit mehreren Requirements und unterschiedlicher Ressource umsetzen?

Erstellt von emuuu vor 4 Jahren Letzter Beitrag vor 4 Jahren 818 Views
emuuu Themenstarter:in
286 Beiträge seit 2011
vor 4 Jahren
Wie kann ich eine Policy mit mehreren Requirements und unterschiedlicher Ressource umsetzen?

Guten Tag zusammen,

der Titel klingt etwas komplizierter als es eigentlich ist:
Ich möchte eine Policy erstellen die prüft, ob ein PATCH Vorgang erlaubt ist:


            options.AddPolicy("PatchDevice", policy =>
            {
                policy.Requirements.Add(new DeviceAssignedRequirement());
                policy.Requirements.Add(new DeviceAllowedPatchPathRequirement());
            });

Die erste Requirement kontrolliert, ob das Device dem User zugeordnet ist. Der Handler benötigt also die DeviceID (oder direkt das Device object).

Die zweite Requirement kontrolliert, ob path und operation erlaubt sind (z.B. nur Replace auf Path /X & /Y), benötigt also das JsonPatchDocument<DeviceUpdateDto>

Ich sehe momentan zwei Wege:
Entweder es in zwei Policies aufteilen oder eine übergeordnete Klasse schaffen in der für die jeweiligen Requirements alle notwendigen Ressourcen hinterlegt sind.

Gibt es hier noch andere, bessere Wege das umzusetzen?

Beste Grüße
emuuu

2+2=5( (für extrem große Werte von 2)

16.835 Beiträge seit 2008
vor 4 Jahren

Wenn Du Informationen aus dem Request brauchst, dann ist der primäre Weg ein IAuthorizationFilter.
Alternativ musst Du das Requirement manuell ausführen, dann kannst Du Parameter aus der Action mitgeben. Dafür gibts den IAuthorizationService.
Letzteres finde ich persönlich den angenehmeren Weg.

Aus REST-Sicht sollte ja aber die ID des Geräts Teil der URL sein, nicht Teil des API Modells.

emuuu Themenstarter:in
286 Beiträge seit 2011
vor 4 Jahren

Dafür gibts den IAuthorizationService

Den verwende ich schon:

var authorizationResult = await _authorizationService.AuthorizeAsync(_user, deviceID, "PatchDevice");

Innerhalb der Service-Klasse habe ich die Patch-Methode mit der ich o.g. aufrufe.

Das Problem ist halt hier der Punkt "DeviceID" für die zweite Requirement bräuchte ich das PatchDocument.

2+2=5( (für extrem große Werte von 2)

16.835 Beiträge seit 2008
vor 4 Jahren

Verwende nicht die Signatur mit dem PolicyName, sondern mit dem Requirement.
Dann kannst den Parameter mitgeben

var authorizationResult = await _authorizationService.AuthorizeAsync(_user, deviceId, new DeviceAllowedPatchPathRequirement(deviceId));

Alternativ eben das resource Objekt verwenden.

public class DeviceAllowedPatchPathRequirementHandler : 
    AuthorizationHandler<DeviceAllowedPatchPathRequirement, int>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   DeviceAllowedPatchPathRequirement requirement,
                                                   int resource)
    {
        var deviceId = resource;

        return Task.CompletedTask;
    }
}

Kannst dafür ja auch das Document verwenden.
Kannst Dir ne Klasse bauen und mitgeben was Du willst.

Aber:
Ich würde das insgesamt eher in die Business Logik legen und bei der Ausführung dann ggfls ne AuthorizeException werfen, wenn ich mir das so überlege.
Kommt aber im Endeffekt auf die Solution an: Prüfung innerhalb der Methode als "eingebauter Schutz" oder eben mit nem Schranken-System wie Du es nun machst; geht beides.