Spring Security: Überprüfen Sie, ob ein Benutzer eine Rolle in Java hat

1. Einleitung

In Spring Security muss manchmal überprüft werden, ob ein authentifizierter Benutzer eine bestimmte Rolle spielt. Dies kann nützlich sein, um bestimmte Funktionen in unseren Anwendungen zu aktivieren oder zu deaktivieren .

In diesem Tutorial sehen Sie verschiedene Möglichkeiten, um Benutzerrollen in Java für Spring Security zu überprüfen.

2. Überprüfen der Benutzerrolle in Java

Spring Security bietet verschiedene Möglichkeiten, um Benutzerrollen in Java-Code zu überprüfen . Wir werden uns jeden von ihnen unten ansehen.

2.1. @PreAuthorize

Die erste Möglichkeit, in Java nach Benutzerrollen zu suchen, besteht darin, die von Spring Security bereitgestellte Annotation @PreAuthorize zu verwenden . Diese Anmerkung kann auf eine Klasse oder Methode angewendet werden und akzeptiert einen einzelnen Zeichenfolgenwert, der einen SpEL-Ausdruck darstellt.

Bevor wir diese Annotation verwenden können, müssen wir zuerst die globale Methodensicherheit aktivieren. Dies kann in Java-Code erfolgen, indem die Annotation @EnableGlobalMethodSecurity zu einer beliebigen Konfigurationsklasse hinzugefügt wird .

Anschließend bietet Spring Security zwei Ausdrücke, die wir mit der Annotation @PreAuthorize verwenden können , um Benutzerrollen zu überprüfen:

@PreAuthorize("hasRole('ROLE_ADMIN')") @GetMapping("/user/{id}") public String getUser(@PathVariable("id") String id) { ... }

Wir können auch mehrere Rollen in einem einzigen Ausdruck überprüfen:

@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MANAGER')") @GetMapping("/users") public String getUsers() { ... }

In diesem Fall ist die Anforderung zulässig, wenn der Benutzer eine der angegebenen Rollen hat.

Wenn die Methode aufgerufen wird, ohne die richtige Rolle zu haben, löst Spring Security eine Ausnahme aus und leitet zur Fehlerseite weiter.

2.2. Sicherheitskontext

Die nächste Möglichkeit, nach Benutzerrollen im Java-Code zu suchen, ist die SecurityContext- Klasse.

Standardmäßig verwendet Spring Security eine threadlokale Kopie dieser Klasse. Dies bedeutet, dass jede Anfrage in unserer Anwendung einen Sicherheitskontext hat, der Details des Benutzers enthält, der die Anfrage stellt .

Um es zu verwenden, rufen wir einfach die statischen Methoden in SecurityContextHolder auf :

Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ADMIN"))) { ... }

Beachten Sie, dass wir hier den einfachen Autoritätsnamen anstelle des vollständigen Rollennamens verwenden.

Dies funktioniert gut, wenn wir genauere Prüfungen benötigen - zum Beispiel einen bestimmten Teil einer einzelnen Methode. Dieser Ansatz funktioniert jedoch nicht, wenn wir in Spring Security den globalen Kontextinhabermodus verwenden .

2.3. UserDetailsService

Die dritte Möglichkeit, Benutzerrollen in Java-Code nachzuschlagen, ist die Verwendung des UserDetailsService . Dies ist eine Bohne, die wir überall in unsere Anwendung injizieren und bei Bedarf aufrufen können:

@GetMapping("/users") public String getUsers() { UserDetails details = userDetailsService.loadUserByUsername("mike"); if (details != null && details.getAuthorities().stream() .anyMatch(a -> a.getAuthority().equals("ADMIN"))) { // ... } }

Auch hier müssen wir den Autoritätsnamen verwenden, nicht den vollständigen Rollennamen mit Präfix.

Der Vorteil dieses Ansatzes besteht darin, dass wir die Rollen für jeden Benutzer überprüfen können , nicht nur für denjenigen, der die Anforderung gestellt hat.

2.4. Servlet-Anfrage

Wenn wir Spring MVC verwenden, können wir Benutzerrollen in Java auch mithilfe der HttpServletRequest- Klasse überprüfen :

@GetMapping("/users") public String getUsers(HttpServletRequest request) { if (request.isUserInRole("ROLE_ADMIN")) { ... } }

3. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten gesehen, mithilfe von Java-Code mit Spring Security nach Rollen zu suchen.

Wie immer finden Sie die Codebeispiele aus diesem Artikel auf GitHub.