Код: Выделить всё
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");
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... -to-itself
Мобильная версия