Spring Tools 4 Update

Am 22.01.2020 wurde das neue Update der beliebten Spring Tools 4 Suite veröffentlicht. Im allgemeinen sind Verbesserungen und Fehlerbeseitigung in Eclipse vorhanden. Ausnahme bildet der Hover Mechanismus, der nun auch Connection Failures anzeigen kann.

Spring Boot

  • Live hover können nun Connection Failures anzeigen

Eclipse

  • Completions werden nun asynchron durchgeführt
  • Early access builds für Eclipse 4.15 verfügbar
  • Bei der Autovervollständigung für Parameter in @Value Annotationen wurde immer ein zusätzliches NewLine eingefügt
  • Das Spring Boot Dashboard konnte Projekte die ein Leerzeichen enthalten nicht starten
  • Eine NPE in PropertiesJavaDefinitionHandler.adjustedHighlightRangeForKey wurde gefixt
  • Neueste m2e Snapshot um Probleme mit JUnit 5 Tests zu beseitigen

Spring Tool Suite

Mit dem neuen Release 4.3.0 von Spring Tool Suite, ist Pivotal wieder gut gelungen.

Neuerungen

Neben dem Update auf Eclipse 2019-06 (Release News) sind auch wieder jede Menge Bugfixes dabei (Changelog).

Änderungen in STS4

Theia ist nun in die Liste der offiziell unterstützten Editoren aufgenommen worden. Dafür wurde die Unterstützung für ATOM (ab Spring Tools 4.3.0) gestrichen und ist nun kein unterstützter Client mehr.

Spring Boot

  • Verbesserung: Die Startugeschwindigkeit wurde durch Optimierung der Classpath Meldungen verbessert
  • Verbesserung: Symbole werden neu erstellt, wenn ein abhängiger Typ sich ändert
  • Bugfix: Langsame Codevervollständigung (mehr als eine Sekunde) wurde behoben
  • Bugfix: Der Content-Assisten für Spring XML funktioniert nun auch wieder in VS Code und Theia Editoren
  • Bugfix: Ein ClassCast Exception in dem Spring Boot LanguageServer wurde behoben
  • Bugfix: Anonyme Inner Types hatten keine Boot Hints

Eclipse

  • Bugfix: Das schelle neustarten einer Anwendung im Boot Dashboard erzeugt keine Fehler mehr
  • Bugifx: Merkwürdige Exceptions beim Löschen einer CF Anwendung, wenn der SSH Tunnel noch aktiv war, wurde behoben

Sichern einer Anwendung mit Spring Security 5.0

1. Hinzufügen der Dependencies

"org.springframework.boot:spring-boot-starter-sercurity",
"org.springframework.security:spring-security-oauth2-resource-server"

Mit dem Hinzufügen der Dependency spring-boot-starter-sercurity werden automatisch alle Endpoints gesichert.

Es muss spring-security-oauth2-resource-server Libary eingebunden werden, damit die Anwendung mit JWT encoded Barear Token gesichert werden kann. Dieses muss deklariert werden, dann verwandelt sich die Anwendung in einen Resource Server. Wenn ein Authorization Header in einem Request vorhanden und in diesem Barear Schema und das Token vorhanden ist, dann wird das JWT geparst und festgestellt ob der Request authorisiert war oder nicht.

2. Anpassen der application.yaml

Die application.yaml muss angepasst werden. Es muss die URI angegeben werden wo der uaa Server läuft. Hier in diesem Beispiel läuft der Server auf dem Localhost auf Port 8090.

   security:
     oauth2:
       resourceserver:
         jwt:
           issuer-uri: http://localhost:8090/uaa/oauth/token 

Beim Starten der Anwendung werden von der standarisierten URI http://localhost:8090/uaa/oauth/token/.well-known/openid-configuration weitere Konfigrationseinstellungen geladen. In den Konfigurationseinstellungen wird u.a. auch die URI für jwks-Token angegeben.

Über die URI (http://localhost:8090/uaa/token_keys) kann der PublicKey geladen werden, um z.B. die Signierung durch den Authorisationsserver zu überprüfen und ob das Token seit der Generierung im Server modifiziert worden ist.

Damit ist die minimale Konfiguration abgeschlossen, um die Anwendung in einen Resourceserver zu verwandeln.

Exkurs: JWT

JWT (jawt ausgesprochen) steht für JSON Web Token. Auf jwt.io gibt es einen Decoder der die beide Teile Header und Payload base64 decodiert und als JSON darstellt. Im Header wird der Algorythmus und der Typ (z.B. JWT) angegeben. In der Payload können die Attribute (hier Claims genannt) übertragen werden. JWT wird als Bearer Token im HTTP Authorization Header übertragen. Der Header und die Payload wird als Singnatur mit RSASHA256 angehangen.

UAA

OAuth Authorization Code FLow

Resource Owner –> Application –> Authorization Server –> Resource Server

  1. Der Resource Owner (Hier der Anwender) fragt bei der Application an.
  2. Die Application frag den Anwender nach den Rechten. Dieser gewährt der Anwendung diese.
  3. Die Authentifizierung und die Authorisierung werden an den Authorisationsserver geschickt.
  4. Der Authorisationsserver schickt der Anwendung einen Authorisationscode (OTC) zu. Dieser ist kurzlebig.
  5. Nun tauscht die Anwendung den OTC Code zusammen mit den Client Credentials (Das ist die Authentifizierung der Anwendung) mit dem Authorisationsserver für das Token aus.
  6. Der Authorisationsserver antwortet mit dem Token für die Anwendung.
  7. Nun kann die Anwendung mit dem Token auf den Resource Server nach einer Resource anfragen.
  8. Der Resource Server schickt nach Validierung des Tokens die angeforderte Resource an die Anwendung.

Das Token ist mächtig und daher verbleit es im Backend der Anwendung und wird somit geschützt. Sollte das Token offengelegt (geleakt) werden, so hat man den vollen Zugriff auf die API mit Rechten des Anwenders. Deshalb sollte die Gültigkeit des Token nur kurz sein und es regelmäßig aktualisiert werden.

OAuth Client Credentials Flow

Spring Tools 4.4.2

Es ist mal wieder eine neue Version von den Spring Tools 4 erschienen.

  • Verbesserung: Neue actions um connect,refresh,disconnect live hover Informationen von laufenden Spring Boot Projecten zu steuern. Diese sind nun auch in den Boot Dashboard Menüs vornahen
  • Verbesserung: Über das Kontextmenü sind weitere Voreinstellungen für live hover möglich
  • Verbesserung: Die Console-View kann nun mit der Dashboard Auswahl verknüpft werden
  • Fehlerbehebung: Live hover werden wieder bei neueren Versionen von Spring Boot angezeigt, wenn sie auf CF deployt worden sind
  • Fehlerbehebung: Für Properties Keys wurde die Sortierung in @Value Annotationparametern gefixt

Weitere Änderungen

Wie immer habe ich hier nicht alle Änderugen aufgeführt. Diese könnt ihr auf der Release Info sehen.

Custom Starter

Spring Boot beinhaltet eigene Starter. Ein Starter ist eine Sammlung von Dependencys die aufeinander abgestimmt sind. Diese werden über das Dependency Management von dem Parent POM bzw. über ein Gradle Plugin mit den passenden Versionen verwaltet. So kann man sehr einfach und fehlerfrei Dependencys in eine Spring Boot Anwendung einbringen.

Nun bietet Spring Boot aber nicht für alle 3rd Party Libraries einen Spring Boot Starter. Es werden aber (nach Pull Request) auf der GitHub Seite Custom Starters gelistet.

Spring-Boot-CLI Tools

Spring Boot bietet auch ein Kommandozeilewerkzeug. Die Installation unter Manjaro erfolgt mit

yaourt --noconfirm -S spring-boot-cli

sehr schnell.

Password encoden

Nun kann mit dem spring Kommando einen Hash für ein Passwort schnell auf der Kommandozeile erstellen:

$ spring encodepassword meinGeheimesPasswort
{bcrypt}$2a$10$ip/Y7fBiC4Eh7vyvltUuruJnUpZeDD44JU8rbrvFfV94QIIzZkFKm

DefaultNamingStrategy von Hibernate

Per default werden die Tabellen nach den Klassennamen und die Columns nach den Feldern benannt. Manchmal stört es einen oder es passt nicht zur der restlichen Struktur in der Datenbank.

Eine Custom NamingStrategy definieren

In diesem Beipsiel hat die Anwendung Tabellen die Über Hibernate verwaltet werden, sowie Tabellen die losgelöst davon im Schema vorhanden sind. Um diese Gruppen von Tabellen sauber zu trennen, kann man z.B. ein Prefix vor jeden Tabellenname einfügen und schon lassen sich schnell die Tabellen unterscheiden.

Tabellenname über @Table festelegen

Über die @Table Annoatation kann über den Parameter name der Tabellenname festgelegt werden. Dieses bietet natürlich größtmögliche flexibilität ist aber aufwändig, da jede Entität das angepasst werden muss.

@Table(name="hibernate_user")

Tabellenname über eine NamingStrategy festlegen

Wie oben beschrieben, wird es in den meisten Fällen nicht angebracht sein alles von Hand einzufügen. In Hibernate gibt es für den Zweck 2 Strategien, um die Generierung der Namen der Tabellen, Felder und Objekten zu beeinflussen. In diesem Beispiel interessiert uns die PhysicalnamingStrategy. Dazu implementieren wir das Interface PhysicalnamingStrategy wie folgt:

/**
 * Adds a prefix "hibernate_" to all tablenames.
 * @author sascha
 *
 */
public class PrefixNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return stringToIdentifier("hibernate_" + name);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    /**
     * String to Identifier
     */
    private Identifier stringToIdentifier(String name) {
        return Identifier.toIdentifier(name);
    }

Als Prefix habe ich hier hibernate_ hinzugefügt. Alle anderen Bezeichnungen werden 1:1 übernommen.

Einbindung über eine Bean

Damit die Strategy auch angewandt wird, muss diese gesetzt werden. Das kann man über die Properties oder eine Bean machen. Hier zeige ich kurz die Bean Variante:

@Bean
public PhysicalNamingStrategy physicalNamingStrategy() {
    return new PrefixNamingStrategy();
}

Dependency Management unter SpringBoot 2

Fügt man als Dependency spring-boot-starter-jooq ein, dann werden alle Abhängigeiten sowie Jooq als Abhängigkeiten eingefügt. Soweit so gut. Aber was ist, wenn man eine neuere Version von Jooq (zum Beispiel aufgrund eines Bugs) verwenden möchte?

Override Version

Unter Gradle kann man mit ext [jooq.version] die zu verwendende Version vorgeben.

// Override supported Jooq version 3.11.9
ext['jooq.version'] = '3.11.11'

Nun wird die aktuelle Version von Jooq 3.11.11 verwendet.

Milestone von Spring Boot 2.2.0M1

Um neue Feature zu testen, kann man auf die Milestone Repositories zurückgreifen. Da das Spring Boot Framework über ein Plugin eingebunden wird, muss das dem PluginManagement mit geteilt werden. Dazu muss man in der settings.gradle das Snapshot und/oder Milestone Repository hinzufügen. Ansonsten wird Spring Boot 2.2.0M1 Version von gradle nicht gefunden.

Plugin

Folgende Änderungen an der settings.gradle Datei sind nötig, um die Milestone Variante zu finden…

pluginManagement {
    repositories {
        maven { url 'https://repo.spring.io/snapshot' }
        maven { url 'https://repo.spring.io/milestone' }
        gradlePluginPortal()
    }
    resolutionStrategy {
        eachPlugin {
            if (requested.id.id == 'org.springframework.boot') {
                useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}")
            }
        }
    }
}

Dependencies

Jetzt kann regulär die Version 2.2.0.M1 eingebunden werden.

plugins {
    id 'java'
    id 'eclipse'
    id 'org.springframework.boot' version '2.2.0.M1'
    id 'io.spring.dependency-management' version "1.0.7.RELEASE"
}