사용자의 IP 주소를 로깅하고 특정 IP 주소를 차단하는 필터를 구현합니다.
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class IpLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String clientIp = request.getRemoteAddr();
System.out.println("Client IP: " + clientIp);
// 특정 IP 차단 로직
if ("192.168.1.1".equals(clientIp)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied for this IP");
return;
}
// 다음 필터로 요청 전달
filterChain.doFilter(request, response);
}
}
http.addFilterBefore(new IpLoggingFilter(), UsernamePasswordAuthenticationFilter.class);
요청 처리에 걸리는 시간을 측정하여 성능 모니터링을 위한 데이터를 기록합니다.
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestTimingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
// 요청 처리
filterChain.doFilter(request, response);
long duration = System.currentTimeMillis() - startTime;
System.out.println("Request URI: " + request.getRequestURI() + " | Duration: " + duration + " ms");
}
}
http.addFilterAfter(new RequestTimingFilter(), UsernamePasswordAuthenticationFilter.class);
CORS 설정을 위해 응답 헤더에 적절한 정보를 추가합니다.
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// CORS 헤더 추가
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
// Preflight 요청 처리
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
// 다음 필터로 요청 전달
filterChain.doFilter(request, response);
}
}
http.addFilterBefore(new CorsFilter(), UsernamePasswordAuthenticationFilter.class);
특정 요청 헤더의 값이 올바른지 검증하는 필터를 구현합니다.
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HeaderValidationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String customHeader = request.getHeader("X-Custom-Header");
if (customHeader == null || !"ExpectedValue".equals(customHeader)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid or missing header: X-Custom-Header");
return;
}
// 다음 필터로 요청 전달
filterChain.doFilter(request, response);
}
}
http.addFilterAt(new HeaderValidationFilter(), BasicAuthenticationFilter.class);
API 요청에서 API 키를 검사하여 인증하는 필터를 구현합니다.
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ApiKeyAuthFilter extends OncePerRequestFilter {
private static final String API_KEY = "my-secure-api-key";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String apiKey = request.getHeader("X-API-KEY");
if (apiKey == null || !API_KEY.equals(apiKey)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid API Key");
return;
}
// 다음 필터로 요청 전달
filterChain.doFilter(request, response);
}
}
http.addFilterBefore(new ApiKeyAuthFilter(), UsernamePasswordAuthenticationFilter.class);
요청의 내용을 로깅하거나, 특정 데이터가 포함되어 있는지 확인합니다.
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.BufferedReader;
import java.io.IOException;
public class RequestBodyLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
StringBuilder requestBody = new StringBuilder();
try (BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
requestBody.append(line).append("\n");
}
}
System.out.println("Request Body: " + requestBody);
// 다음 필터로 요청 전달
filterChain.doFilter(request, response);
}
}