a dev's blog

Some thoughts about thoughts.

Die Spring-Security-Taglib in Spring-Boot

2016-02-24 Development Java Spring

Intro

Spring-Security ist schon ein sehr schönes Stück Software. Und nutzt man JSPs oder Thymeleaf zum Darstellen seines View-Layers, können Verrechtungen von Links oder ganzen Code-Blöcken sehr elegant und kurz gefasst werden.

Setup

Zunächst einmal habe ich ein kleines Beispielprojekt auf Github, was du nutzen kannst um dir einen besseren Überblick zu verschaffen oder um die ganze Sache mal auszuprobieren.

Ich gehe davon aus, dass du ein Projekt mit Spring-Boot, Spring-Security und Thymeleaf starten willst. Dazu brauchst du zunächst einmal die folgenden Dependencies:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Um jetzt die Spring-Security-Taglib einzubinden, setzen wir noch folgende Dependecy drauf:

<dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-springsecurity4</artifactId>
  <version>2.1.2.RELEASE</version>
</dependency>

Zu den Tags

Mit der Einbindung der Thymeleaf-Extras für Spring-Security kannst du jetzt Spring-Security Tags in dein Template einbauen. Dazu machst du erstmal den XML-Namespace sec bekannt, wie ich im folgenden Beispiel in Zeile 3 demonstriere. Außerdem findest du in dem Beispiel die beiden Tags, die Spring-Security standardmäßig zur Verfügung stellt:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sec="http://www.springframework.org/security/tags">

<body>
    <h1 sec:authentication="name">[username]</h1>

    <div sec:authorize="hasAnyRole('ROLE_ADMIN','ROLE_PREVIOUS_ADMINISTRATOR')">
        Very secret user information which is just visible for admins!
    </div>
</body>

</html>

authentication-Tag

Willst du eine Property des Authentication-Objekts abfragen, kannst du das über das authentication-Tag tun. Dabei kannst du darauf vertrauen, dass Authentication das Interface Pricipal, welches im Java-Security-Standard enthalten ist, erweitert. Daher kannst du beispielsweise direkt, und wie ich im o.g. Beispiel zeige, auf die Property name zugreifen. Du kannst aber auch über die Property pricipal auf eine Instanz eines UserDetails-Objekts aus dem Spring-Security-Framework zugreifen und damit an den Benutzernamen oder ähnliches zu kommen. In der Regel ist das eh ein Objekt einer Klasse, die von dir in deinem eigenen UserDetailsService festgelegt wird. Ein Zugriff auf den Benutzernamen via principal-Property sieht dabei wie folgt aus:

<h1 sec:authentication="principal.username">[username]</h1>

authorize-Tag

Mit dem authorize-Tag kannst du Elemente deines Templates verrechten, damit nur die User Zugriff darauf haben, die auch die notwendigen Berechtigungen haben. Im Beispiel oben habe ich ein div erstellt, das der User nur dann siehst, wenn er zu den Administratoren der Anwendung gehört. Dies wird entweder an seiner primären oder an seiner vorherigen Nutzerrolle festgemacht. Letzters ist nur relevant, falls er sich als Administrator eingeloggt hat, danach aber in die Rolle eines bestimmten Users geschlüpft ist. Wie das funktioniert habe ich in dem Blog-Post User-Impersonation mit Spring-Boot und Spring-Security erklärt.

Mit dem authorize-Tag ist es allerdings auch möglich eine implizite Abfrage der Berechtigungen abzurufen. Gehen wir mal davon aus, du würdest eine Webseite mit einem Premium-Bereich betreiben, auf den nur zahlende User zugriff haben. Dieser Bereich ist über den Endpunkt /premium zu erreichen. Wenn du jetzt irgendwo auf der Seite ein Stück Content darstellen möchtest, dass nur den Usern dargestellt werden soll, die das Recht besitzen den Premium-Endpunkt aufzurufen, so kannst du das wie folgt erreichen:

<div sec:authorize url="/premium">
  Welcome premium user. These news are just for you...
</div>

Technisch wird das über Dummy-Web-Request bewerkstelligt, der automatisch mit dem aktuellen User-Context an den angegebenen Endpunkt abgefeuert wird. Je nach Antwort wird der Content dann dargestellt oder ausgeblendet.

Fazit

Mit der Taglib von Spring-Security bist du in der Lage schnell und einfach Elemente deiner Webapplikation zu verrechten. Mehr gibts da wohl nicht zu sagen. Es kann nicht mehr, aber auch nicht weniger.

Cheers!