From 9d9d6d8a601b4a69f9c0a0a067561739a11a6a89 Mon Sep 17 00:00:00 2001 From: PaulK Date: Tue, 18 Mar 2025 15:52:06 +0100 Subject: [PATCH] Funktionierende SecurityConfig --- .../security/JwtAuthenticationFilter.java | 52 +++++++++++++++++++ .../com/example/hangry/security/JwtUtil.java | 42 --------------- .../hangry/security/SecurityConfig.java | 4 +- .../example/hangry/services/JwtService.java | 32 +++++++++++- 4 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 src/main/java/com/example/hangry/security/JwtAuthenticationFilter.java delete mode 100644 src/main/java/com/example/hangry/security/JwtUtil.java diff --git a/src/main/java/com/example/hangry/security/JwtAuthenticationFilter.java b/src/main/java/com/example/hangry/security/JwtAuthenticationFilter.java new file mode 100644 index 0000000..ca28a48 --- /dev/null +++ b/src/main/java/com/example/hangry/security/JwtAuthenticationFilter.java @@ -0,0 +1,52 @@ +package com.example.hangry.security; + +import com.example.hangry.User; +import com.example.hangry.UserRepository; +import com.example.hangry.services.JwtService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.ArrayList; + + +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + + private final JwtService jwtService; + private final UserRepository userRepository; + + public JwtAuthenticationFilter(JwtService jwtService, UserRepository userRepository) { + this.jwtService = jwtService; + this.userRepository = userRepository; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + String authHeader = request.getHeader("Authorization"); + if (authHeader != null && authHeader.startsWith("Bearer ")) { + String token = authHeader.substring(7); + String email = jwtService.extractEmail(token); + if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) { + User user = userRepository.findByEmail(email); + if (user != null && jwtService.validateToken(token, user)) { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + } + filterChain.doFilter(request, response); + } + +} diff --git a/src/main/java/com/example/hangry/security/JwtUtil.java b/src/main/java/com/example/hangry/security/JwtUtil.java deleted file mode 100644 index b001210..0000000 --- a/src/main/java/com/example/hangry/security/JwtUtil.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.example.hangry.security; - -import io.jsonwebtoken.*; -import io.jsonwebtoken.security.Keys; -import org.springframework.stereotype.Component; - -import java.security.Key; -import java.util.Date; - -@Component -public class JwtUtil { - private final String SECRET_KEY = "geheimeschluesselgeheimeschluessel"; // Sollte mind. 256 Bit lang sein - private final long EXPIRATION_TIME = 1000 * 60 * 60; // 1 Stunde gültig - - private final Key key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); - - //Token generieren - public String generateToken(String username) { - return Jwts.builder() - .setSubject(username) // Benutzername in das Token schreiben - .setIssuedAt(new Date()) // Zeitpunkt der Erstellung - .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // Ablaufzeit setzen - .signWith(key, SignatureAlgorithm.HS256) // Signieren mit geheimer Schlüssel - .compact(); - } - - //Token validieren - public boolean validateToken(String token) { - try { - Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); - return true; - } catch (JwtException | IllegalArgumentException e) { - return false; - } - } - - //Benutzername aus Token extrahieren - public String extractUsername(String token) { - return Jwts.parserBuilder().setSigningKey(key).build() - .parseClaimsJws(token).getBody().getSubject(); - } -} diff --git a/src/main/java/com/example/hangry/security/SecurityConfig.java b/src/main/java/com/example/hangry/security/SecurityConfig.java index da458b2..2afa777 100644 --- a/src/main/java/com/example/hangry/security/SecurityConfig.java +++ b/src/main/java/com/example/hangry/security/SecurityConfig.java @@ -7,14 +7,16 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity // Aktiviert Spring Security public class SecurityConfig { @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception { http + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .csrf(AbstractHttpConfigurer::disable) // Neue Syntax für CSRF-Disable .authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/register", "/api/auth/login").permitAll() // Registrierung & Login erlauben diff --git a/src/main/java/com/example/hangry/services/JwtService.java b/src/main/java/com/example/hangry/services/JwtService.java index 7ff7189..3a1fa4a 100644 --- a/src/main/java/com/example/hangry/services/JwtService.java +++ b/src/main/java/com/example/hangry/services/JwtService.java @@ -1,17 +1,20 @@ package com.example.hangry.services; import com.example.hangry.User; +import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; +import org.springframework.cglib.core.internal.Function; import org.springframework.stereotype.Service; + import java.security.Key; import java.util.Date; @Service public class JwtService { - private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); + private static final String SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256).toString(); private static final long EXPIRATION_TIME = 1000 * 60 * 60 * 24; // 24 Stunden public String generateToken(User user) { @@ -19,7 +22,32 @@ public class JwtService { .setSubject(user.getEmail()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) - .signWith(SECRET_KEY) + .signWith(getSigningKey(), SignatureAlgorithm.HS256) .compact(); } + + public T extractClaim(String token, Function claimsResolver) { + final Claims claims = extractAllClaims(token); + return claimsResolver.apply(claims); + } + + private Claims extractAllClaims(String token) { + return Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody(); + } + + private Key getSigningKey() { + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } + public String extractEmail(String token) { + return extractClaim(token, Claims::getSubject); // Subject = E-Mail + } + public boolean validateToken(String token, User user) { + final String email = extractEmail(token); + return email.equals(user.getEmail()) && !isTokenExpired(token); + } + private boolean isTokenExpired(String token) { + return extractClaim(token, Claims::getExpiration).before(new Date()); + } + + }