Код: Выделить всё
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Value("${authentication-test.auth.tokenSecret}")
private String jwtSecret;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
System.out.println("FilterChain Called********************************");
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/api/auth/signin", "/api/auth/test", "/swagger-ui/index.html", "/actuator/health").permitAll()
.anyRequest().authenticated())
.formLogin(form -> form.loginPage("/login").permitAll())
.addFilterAfter(deviceFingerprintFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
public DeviceFingerprintFilter deviceFingerprintFilter() {
return new DeviceFingerprintFilter(jwtSecret);
}
public RateLimitingFilter rateLimitingFilter() {
return new RateLimitingFilter();
}
}
Код: Выделить всё
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class DeviceFingerprintFilter extends OncePerRequestFilter {
private final String jwtSecret;
public DeviceFingerprintFilter(String jwtSecret) {
this.jwtSecret = jwtSecret;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// Check if the user is authenticated
if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated() && !isExcludedUri(request.getRequestURI())) {
System.out.println("++++++++++++++++>>>>>>>>>>>>>> " + request.getRequestURI());
String token = extractJwtFromRequest(request);
if (token != null) {
try {
// Configure a JWT parser to verify the token and retrieve the claims
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret.getBytes(StandardCharsets.UTF_8))
.build()
.parseClaimsJws(token.replace("Bearer ", ""))
.getBody();
String deviceFingerprintFromToken = claims.get("User-Fingerprint", String.class);
String currentUserAgent = request.getHeader("User-Agent");
String currentIpAddr = request.getRemoteAddr();
String currentDeviceFingerprint = hashDeviceFingerprint(currentUserAgent, currentIpAddr);
if (deviceFingerprintFromToken.equals(currentDeviceFingerprint)) {
filterChain.doFilter(request, response);
} else {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid device fingerprint");
}
} catch (SignatureException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
}
} else {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing token");
}
} else {
filterChain.doFilter(request, response);
}
}
private String extractJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
private String hashDeviceFingerprint(String userAgent, String ipAddr) {
try {
String input = userAgent + ipAddr;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hashBytes);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-256 algorithm not available", e);
}
}
private boolean isExcludedUri(String uri) {
return uri.equals("/login") || uri.equals("/api/auth/signin") || uri.equals("/api/auth/test") ||
uri.equals("/swagger-ui/index.html") || uri.equals("/actuator/health");
}
}
Код: Выделить всё
2024-07-02T15:40:41.149+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-2] [66841169cd8b5e73217e0a96d17bbc0b-c778a75b31b38210] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-07-02T15:40:41.345+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-2] [66841169cd8b5e73217e0a96d17bbc0b-ed7fee28a1de34ad] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8038/api/auth/authtest?continue to session
2024-07-02T15:40:41.352+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-2] [66841169cd8b5e73217e0a96d17bbc0b-ed7fee28a1de34ad] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8038/login
2024-07-02T15:40:42.226+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [6684116a9fd6e7a3b8de6edb097b2e94-b8de6edb097b2e94] o.s.security.web.FilterChainProxy : Securing GET /login
2024-07-02T15:40:42.229+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [6684116a9fd6e7a3b8de6edb097b2e94-1813bead978a410c] o.s.security.web.FilterChainProxy : Secured GET /login
2024-07-02T15:40:42.266+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [6684116a9fd6e7a3b8de6edb097b2e94-1813bead978a410c] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-07-02T15:40:42.297+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [ ] o.s.security.web.FilterChainProxy : Securing GET /error
2024-07-02T15:40:42.303+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [6684116aa74ddbdc29f7ea4a027df018-caf5568c75153840] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-07-02T15:40:42.324+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [6684116aa74ddbdc29f7ea4a027df018-29f7ea4a027df018] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8038/error?continue to session
2024-07-02T15:40:42.325+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-1] [6684116aa74ddbdc29f7ea4a027df018-29f7ea4a027df018] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8038/login
2024-07-02T15:40:42.486+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [6684116a2166c682a42e072ad69210f0-a42e072ad69210f0] o.s.security.web.FilterChainProxy : Securing GET /login
2024-07-02T15:40:42.488+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [6684116a2166c682a42e072ad69210f0-755d44307f186095] o.s.security.web.FilterChainProxy : Secured GET /login
2024-07-02T15:40:42.491+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [6684116a2166c682a42e072ad69210f0-755d44307f186095] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-07-02T15:40:42.494+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [ ] o.s.security.web.FilterChainProxy : Securing GET /error
2024-07-02T15:40:42.496+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [6684116aff72acdebb99affb35222cf7-ba7d02d4d411bd7b] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-07-02T15:40:42.498+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [6684116aff72acdebb99affb35222cf7-bb99affb35222cf7] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8038/error?continue to session
2024-07-02T15:40:42.498+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-5] [6684116aff72acdebb99affb35222cf7-bb99affb35222cf7] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8038/login
2024-07-02T15:40:42.516+01:00 DEBUG 50451 --- [auth-service] [nio-8038-exec-4] [6684116a0b023ef587157ade80985c86-87157ade80985c86] o.s.security.web.FilterChainProxy : Securing GET /login
Я даже пытался проверить явность сказанного предыдущие страницы, но безрезультатно, буду очень признателен за любую помощь
Подробнее здесь: https://stackoverflow.com/questions/786 ... -to-itself
Мобильная версия