Maven-Repository für die Grundkonfiguration von Spring Boot-Unterrichtsprojekten mit den folgenden Artefakten:
Globales Parent-POM für alle Projekte; enthält keinen Code, sondern definiert die Spring Boot-Version (2.5.3) und die verfügbaren Spring Boot Starter. Dies sind:
- Web
- JPA
- REST Repositories
- Jersey (JAX-RS)
- Security
- AOP
- OAuth2-Client für Github, Google, Facebook und Okta
- Test
- Configuration Processor
Als weitere Abhängigkeiten sind enthalten:
- Spring Session
- AspectJ
- OAuth2-Client für Microsoft Azure AD
- Project Lombok
- JDBC-Treiber für H2, PostgreSQL, MS SQL Server, MariaDB und MySQL
- Embedded H2-Datenbank
- Hibernate ORM
- Ehcache
- JUnit5
- Mockito
- WireMock
Plugins:
- Spring Boot Maven Plugin
- Jib Maven Plugin (Goals
jib:dockerBuild
undjib:build
) - Keytool Maven Plugin (Goal
keytool:generateKeyPair
)
Wird dieses Artefakt im POM eines Projekts als Abhängigkeit angegeben, so werden folgende Spring Boot-Einstellungen wirksam:
@Autowired
kann man auch in Klassen verwenden, die keine Spring-Beans sind. Dazu annotiert man diese Klassen mit@Configurable
. Dies funktioniert für alle Klassen inner- oder unterhalb der Paketeserver
,repositories
undat.rennweg.htl.sew
.- Für dieses Verhalten wird Load-time weaving (LTW) verwendet, ohne dass ein externer Instrumentation-Agent benötigt wird.
- Der Server läuft auf
localhost:8080
(Propertiesserver.address
,server.port
). - Auf
http://localhost:8080/index.html
werden Hinweise ausgeliefert, wie man eigene Inhalte auf dem Server platziert.
Voraussetzungen:
- Man muss mit der Benutzer-
@Entity
das InterfaceUserInfo<ID>
implementieren. - Das zugehörige REST-Repository muss man zusätzlich auch von
UserInfoRepository<T, ID>
ableiten, z.B.@RepositoryRestResource public interface MyUserRepository extends PagingAndSortingRepository<MyUser, Long>, UserInfoRepository<MyUser, Long> { }
Dies bewirkt:
- Die Anmeldung erfolgt durch ein
POST
vonusername
undpassword
imapplication/x-www-form-urlencoded
-Format auf/login
(Propertysew.login
inapplication.properties
). Dieapplication/json
-Response enthält Details zur angemeldeten Benutzerin. - Bei jedem Anmeldeversuch ermittelt das
UserInfoRepository
den Benutzer zum Anmelde-Benutzernamen. Das Passwort muss dort als BCrypt-Hash gespeichert sein. - In der Login-Response wird das Zugriffstoken sowohl im
SESSION
-Cookie gesetzt als auch imx-auth-token
-Header übergeben. In den weiteren Requests wird es zum Schutz gegen XSS-Attacken aber nur imx-auth-token
-Header akzeptiert. - Die Benutzerdetails stehen später auch an
/api/me
zur Verfügung. - Zum Abmelden dient ein
POST
auf/logout
(Propertysew.logout
), der nur denx-auth-token
-Header enthält. - Nach 600 Sekunden Inaktivität (Property
sew.session-timeout
) wird man automatisch abgemeldet, und dasx-auth-token
wird ungültig.
Die OAuth2-Provider github
, google
, facebook
,
okta
, microsoft
und azure
(Azure Active Directory) werden unterstützt. Die Voraussetzungen sind
dieselben wie für die
Anmeldung mit Benutzernamen und Passwort.
Die Konfiguration erfolgt über die in src/main/resources/application-oauth2.properties.template
beispielhaft angeführten Properties. Dies bewirkt folgende Verhaltensänderungen gegenüber der
Anmeldung mit Benutzernamen und Passwort:
- Den Authentifizierungsvorgang startet man durch ein
GET
auf/oauth2/authorization/{provider}
. Daraufhin wird der Browser zur Anmeldeseite des OAuth2-Authentifizierungsservers umgeleitet. - Nach der Authentifizierung wird temporär auf
/login/oauth2/code/{provider}
umgeleitet. - Abschließend wird der ursprüngliche
GET
-Request auf den im Propertysew.oauth2-login-success
angegebenen Pfad umgeleitet (redirect URI). Das mitgelieferteSESSION
-Cookie muss man bei den weiteren Requests zur Authentifizierung alsx-auth-token
-Header mitsenden. - Nach der ersten erfolgreichen Authentifizierung wird eine Benutzer-Entity im
UserInfoRepository
gespeichert. Diese Entity steht alsprincipal
in@PreAuthorize
zur Verfügung.
- Alle Pfade sind ohne Authentifizierung zugänglich.
- Nur Methoden können mit
@PreAuthorize
abgesichert werden. - Auditing: stehen Benutzer in einer
@OneToMany
-Beziehung zu einer anderen@Entity
, so können sie dort mit@CreatedBy
oder@LastModifiedBy
annotiert werden. Dazu muss die andere Entity zusätzlich mit@EntityListeners(AuditingEntityListener.class)
annotiert werden.
In src/main/resources/application-db.properties.template
sind die Properties aufgezählt, die
für die Anbindung diverser Datenbanken benötigt werden.
Das REST-API ist unter dem Pfad /api
erreichbar (Property spring.data.rest.base-path
).
Um CORS zu ermöglichen, gibt man alle Allowed-Origins
als Liste in
sew.allowed-origins
an. Andernfalls werden XMLHttpRequest
s in Browsern wegen SOP
im Allgemeinen scheitern.
logging
erzeugt ausführliche Debugging-Protokolle.optimize
optimiert Datenbankzugriffe; jede cachebare@Entity
muss zusätzlich mit@javax.persistence.Cacheable
annotiert werden.