Sicherheit ist ein essenzieller Aspekt von RESTful Webservices, insbesondere wenn sensible Daten über das Internet übertragen werden. In Spring Boot bietet das Spring Security Framework robuste Mechanismen zur Sicherung von Anwendungen, indem es Authentifizierung, Autorisierung, Schutz vor gängigen Angriffen (wie CSRF und XSS), sowie Verschlüsselung und sicheres Datenmanagement unterstützt.
In diesem Kapitel werden wir uns auf verschiedene Sicherheitsaspekte in Spring Boot REST Services konzentrieren und zeigen, wie Sie gängige Bedrohungen abwehren und Ihre API absichern können.
Die Sicherheit von RESTful Webservices lässt sich in zwei Hauptbereiche unterteilen:
Neben diesen beiden zentralen Aspekten müssen moderne APIs Schutzmaßnahmen gegen verschiedene Arten von Angriffen bieten, wie z.B.:
Spring Boot verwendet Spring Security als zentrales
Sicherheitsframework. Um Sicherheitsfunktionen in Spring Boot zu
aktivieren, fügen Sie die Spring Security-Abhängigkeit in Ihrer
pom.xml hinzu:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>Sobald diese Abhängigkeit hinzugefügt wird, schützt Spring Boot automatisch alle Endpunkte der Anwendung und fordert eine Authentifizierung an. Weitere Anpassungen können über eine Sicherheitskonfigurationsklasse vorgenommen werden.
Die gängigsten Methoden zur Authentifizierung in Spring Boot REST Services sind:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable() // CSRF-Schutz ausschalten (nur für APIs)
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Öffentliche Endpunkte
.anyRequest().authenticated() // Authentifizierung für alle anderen Endpunkte
.and()
.httpBasic(); // Basic Authentication aktivieren
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User
.withUsername("admin")
.password("password")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // Keine Passwortverschlüsselung (nur zu Demo-Zwecken)
}
}In diesem Beispiel wird Basic Authentication für alle
nicht-öffentlichen Endpunkte aktiviert. Benutzer mit dem Benutzernamen
admin und dem Passwort password können auf die
geschützten Endpunkte zugreifen.
Für die Absicherung von APIs bietet sich die Verwendung von JWT an, da diese Authentifizierungsmethode effizienter und sicherer als Basic Authentication ist.
Generieren eines JWT:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private String SECRET_KEY = "my_secret_key";
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // Token für 10 Stunden
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}Validierung eines JWT:
public boolean validateToken(String token, String username) {
String extractedUsername = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
return (extractedUsername.equals(username) && !isTokenExpired(token));
}
private boolean isTokenExpired(String token) {
Date expiration = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();
return expiration.before(new Date());
}Absicherung von Endpunkten mit JWT: Bei jeder
Anfrage wird das JWT-Token im Authorization-Header
mitgesendet.
curl -H "Authorization: Bearer <JWT-Token>" http://localhost:8080/productsCross-Site Request Forgery (CSRF) ist ein Angriff, bei dem ein böswilliger Benutzer eine authentifizierte Sitzung eines Benutzers ausnutzt, um unerwünschte Aktionen auszuführen. In REST-APIs wird der CSRF-Schutz in der Regel deaktiviert, da diese APIs stateless sind und die Authentifizierung über Tokens (z.B. JWT) erfolgt.
http
.csrf().disable() // Deaktiviert CSRF-SchutzCross-Site Scripting (XSS) ist eine Angriffsmethode, bei der bösartiger JavaScript-Code in Webseiten eingeschleust wird. Um APIs vor XSS-Angriffen zu schützen, sollten alle Eingaben auf Benutzerseite validiert und auf der Serverseite überprüft werden. In Spring Boot sollten insbesondere die folgenden Schritte beachtet werden:
@Valid oder
@Validated).Beispiel für die Validierung von Benutzereingaben:
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class ProductDto {
@NotBlank(message = "Name darf nicht leer sein.")
@Size(max = 100, message = "Name darf nicht länger als 100 Zeichen sein.")
private String name;
// Weitere Felder mit Validierungen
}Um sicherzustellen, dass alle Anfragen und Antworten verschlüsselt werden, sollten RESTful Webservices immer über HTTPS (SSL/TLS) laufen. Dies schützt vor Man-in-the-Middle-Angriffen, bei denen Daten während der Übertragung abgefangen oder manipuliert werden könnten.
Generieren Sie ein SSL-Zertifikat (z.B. mit
keytool oder Let’s Encrypt).
Fügen Sie das Zertifikat in Ihre
application.properties ein:
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=secretEs ist wichtig, bewährte Sicherheitspraktiken zu befolgen, um RESTful Webservices sicher zu gestalten:
Die Sicherheit von RESTful Webservices ist von entscheidender Bedeutung, um Daten vor unbefugtem Zugriff und Manipulation zu schützen. Mit den integrierten Funktionen von Spring Security in Kombination mit Best Practices für die Web-Sicherheit können Sie robuste und sichere APIs entwickeln. Durch die Implementierung von Authentifizierungs- und Autorisierungsmechanismen, den Schutz vor gängigen Angriffen wie CSRF und XSS, sowie die Nutzung von HTTPS können Sie sicherstellen, dass Ihre REST-Services den modernen Sicherheitsanforderungen entsprechen.