Spring Security - @PreFilter en @PostFilter

1. Overzicht

In dit artikel leren we hoe u de @PreFilter en @PostFilter annotaties om bewerkingen in een Spring-applicatie te beveiligen.

Bij gebruik samen met de geverifieerde hoofdinformatie, @PreFilter en @PostFilter stelt ons in staat om fijnmazige beveiligingsregels te definiëren met behulp van Spring Expression Language.

2. Introductie @PreFilter en @PostFilter

Simpel gezegd, de @PreFilter en @PostFilter annotaties zijn gebruikt om lijsten met objecten te filteren op basis van aangepaste beveiligingsregels die we definiëren.

@PostFilter definieert een regel voor het filteren van de retourlijst van een methode, door die regel toepassen op elk element in de lijst. Als de geëvalueerde waarde waar is, wordt het item in de lijst bewaard. Anders wordt het item verwijderd.

@PreFilter werkt op een vergelijkbare manier, maar de filtering wordt toegepast op een lijst die als invoerparameter wordt doorgegeven aan de geannoteerde methode.

Beide annotaties kunnen worden gebruikt op methoden of typen (klassen en interfaces). We gebruiken ze alleen voor methoden in dit artikel.

Deze annotaties zijn standaard niet actief - we moeten ze inschakelen met de @EnableGlobalMethodSecurity annotatie en prePostEnabled = true - in onze beveiligingsconfiguratie:

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity (prePostEnabled = true) openbare klasse WebSecurityConfig breidt WebSecurityConfigurerAdapter uit {// ...}

3. Beveiligingsregels schrijven

Om de beveiligingsregels in deze twee annotaties te schrijven, maken we gebruik van Spring-EL-expressies; we kunnen ook het ingebouwde object gebruiken filterObject om een ​​verwijzing te krijgen naar het specifieke lijstelement dat wordt getest.

Spring Security biedt vele andere ingebouwde objecten om zeer specifieke en exacte regels te maken.

Bijvoorbeeld, we kunnen gebruiken @PreFilter om te controleren of het cessionaris eigendom van een Taak object is gelijk aan de naam van de momenteel geauthenticeerde gebruiker:

@PostFilter ("filterObject.assignee == authentication.name") Lijst findAll () {...}

We hebben de @PostFilter annotatie hier omdat we willen dat de methode wordt uitgevoerd en alle taken eerst krijgt, en ze geven elke afzonderlijke taak uit de lijst door aan onze filterregel.

Dus als de geverifieerde gebruiker is Michael, de definitieve lijst met taken die worden geretourneerd door de vind alle methode zou alleen de taken bevatten die zijn toegewezen aan Michael, zelfs als er taken aan de database zijn toegewezen Jim en pam.

Laten we de regel nu een beetje interessanter maken. Stel dat als een gebruiker een manager is, hij alle taken kan zien, ongeacht aan wie ze zijn toegewezen:

@PostFilter ("hasRole ('MANAGER') of filterObject.assignee == authentication.name") Lijst findAll () {// ...}

We hebben de ingebouwde methode gebruikt hasRole om te controleren of de geauthenticeerde gebruiker de rol van MANAGER heeft. Als hasRole geeft true terug, de taak wordt bewaard in de laatste lijst. Dus als de gebruiker een manager is, retourneert de regel true voor elk item in de lijst. De uiteindelijke lijst bevat dus alle items.

Laten we nu een lijst filteren die als parameter wordt doorgegeven aan een sparen methode gebruiken @PreFilter:

@PreFilter ("hasRole ('MANAGER') of filterObject.assignee == authentication.name") Herhaalbare opslag (Herhaalbare entiteiten) {// ...}

De beveiligingsregel is dezelfde als die we hebben gebruikt op de @PostFilter voorbeeld. Het belangrijkste verschil hier is dat de lijstitems worden gefilterd voordat de methode wordt uitgevoerd, waardoor we enkele items uit de lijst kunnen verwijderen, waardoor ze niet in de database kunnen worden opgeslagen.

Zo Jim, die geen manager is, kan proberen een lijst met taken op te slaan, waarvan sommige zijn toegewezen pam. Maar alleen die taken die zijn toegewezen aan Jim worden opgenomen, de andere worden genegeerd.

4. Prestaties op grote lijsten

@PreFilter is echt gaaf en gemakkelijk te gebruiken, maar het kan inefficiënt zijn bij het omgaan met zeer grote lijsten, aangezien de ophaaloperatie alle gegevens zal ophalen en daarna het filter zal toepassen.

Stel je voor dat we bijvoorbeeld duizenden taken in onze database hebben en we willen de vijf taken terughalen die momenteel zijn toegewezen aan pam. Als we @PreFilter, de databasebewerking haalt eerst alle taken op en herhaalt ze allemaal om de taken eruit te filteren die niet zijn toegewezen aan pam.

5. Conclusie

In dit korte artikel wordt uitgelegd hoe u een eenvoudige, maar veilige applicatie kunt maken met behulp van Spring Security's @PreFilter en @PostFilter annotaties.

Bekijk het volledige codevoorbeeld in deze Github-repository.


$config[zx-auto] not found$config[zx-overlay] not found