필터란
HTTP 요청 및 응답의 처리를 변환하거나 수정할 수 있는 컴포넌트이다. 필터는 주로 다음과 같은 작업을 수행한다.
- 요천 전 처리 : 클라이언트의 요청이 컨트롤러에 도달하기 전에 요청을 검사하고 수정한다.
- 응답 후 처리 : 컨트롤러의 응답이 클라리언트데 전달되기 전에 응답을 검사하고 수정한다.
- 로깅 : 요청 및 응답 로그를 기록한다.
- 인증 및 권한 검사 : 요청이 적절한 인증 및 권한을 가졌는지 확인한다.
- 데이터 압축 : 응답 데이터를 압축하여 클라이언트에 전달한다.
- 캐싱 : 요청 결과를 캐싱하여 성능을 향상시킨다.
필터의 동작 원리
필터는 체인(chain) 구조로 동작한다. 클라이언트의 요청이 들어오면, 요청은 필터 체인의 첫 번째 필터로 전달되고, 각 필터는 자신의 작업을 수행한 후 다음 필터로 요청을 전달한다. 마지막 필터까지 요청이 도달하면, 컨트롤러에 의해 실제 요청 처리가 이루어진다. 응답 또한 필터 체인을 통해 클라이언트로 전달된다.
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class SimpleFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 필터 초기화 작업
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 요청 처리 전 로직
System.out.println("Request received at " + new java.util.Date());
// 다음 필터 또는 서블릿으로 요청 전달
chain.doFilter(request, response);
// 응답 처리 후 로직
System.out.println("Response sent at " + new java.util.Date());
}
@Override
public void destroy() {
// 필터 종료 작업
}
}
Spring Boot에서의 필터
Spring Boot에서는 필터를 쉽게 설정하고 사용할 수 있다. Spring boot에서는 주로 @Component 어노테이션을 사용하여 필터를 등록하거나, FilterRegisrationBean을 사용하여 필터를 구성한다.
@Component 를 사용한 필터 등록
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.Filter;
import java.io.IOException;
@Component
public class CustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 필터 초기화 작업
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 요청 처리 전 로직
System.out.println("Request received at " + new java.util.Date());
// 다음 필터 또는 서블릿으로 요청 전달
chain.doFilter(request, response);
// 응답 처리 후 로직
System.out.println("Response sent at " + new java.util.Date());
}
@Override
public void destroy() {
// 필터 종료 작업
}
}
FilterRegistrationBean을 사용한 필터 구성
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<CustomFilter> customFilter() {
FilterRegistrationBean<CustomFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CustomFilter());
registrationBean.addUrlPatterns("/api/*");
registrationBean.setOrder(1); // 필터의 순서 설정
return registrationBean;
}
}
Filter 종류
OncePerRequestFilter
Spring에서 제공하는 필터로, 요청당 한 번만 실행되도록 보장하는 필터. 이를 통해 중복 실행 문제를 방지할 수 있다. 주로 보안 관련 작업에 사용된다.
@Component
public class CustomOncePerRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
System.out.println("Request URI is: " + request.getRequestURI());
filterChain.doFilter(request, response);
}
}
DelegationFilterProxy
Spring의 빈을 필터로 사용할 수 있게 해주는 편리한 클래스. 주로 Spring Security와 함께 사용한다.
@Bean
public FilterRegistrationBean<DelegatingFilterProxy> securityFilterChain() {
FilterRegistrationBean<DelegatingFilterProxy> registrationBean = new FilterRegistrationBean<>();
DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy("springSecurityFilterChain");
registrationBean.setFilter(delegatingFilterProxy);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
Spring Security Filters
Spring Security는 웹 어플리케이션의 보안을 강화하기 위해 여러 필터를 제공한다.
1. UsernamePasswordAuthenticationFilter
폼 기반 로그인을 처리하는 필터. 사용자가 로그인 폼을 통해 사용자 이름과 비밀번호를 제출하면, 이 필터가 요청을 가로채서 인증을 시도한다.
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 요청에 대한 권한 설정
.authorizeRequests()
.anyRequest().authenticated() // 모든 요청에 대해 인증을 요구
.and()
// 폼 기반 로그인 설정
.formLogin()
.loginPage("/login") // 로그인 페이지 URL
.permitAll(); // 로그인 페이지는 모든 사용자가 접근 가능
}
}
2. BasicAuthenticationFilter
HTTP Basic 인증을 처리하는 필터. Authorization 헤더에 포함된 사용자 이름과 비밀번호를 사용하여 인증
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 요청에 대한 권한 설정
.authorizeRequests()
.anyRequest().authenticated() // 모든 요청에 대해 인증을 요구
.and()
// HTTP Basic 인증 설정
.httpBasic();
}
}
3. CsrfFilter
CSRF(Cross-Site Request Forgery) 공격을 방지하는 필터. CSRF 토큰을 검증하여 요청의 유효성을 확인한다.
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 요청에 대한 권한 설정
.authorizeRequests()
.anyRequest().authenticated() // 모든 요청에 대해 인증을 요구
.and()
// HTTP Basic 인증 설정
.httpBasic();
}
}
4. ExceptionTranslationFilter
인증 및 권한 예외를 처리하는 필터. 인증 또는 권한 예외가 발생할 때 적절한 오류 페이지나 메세지를 반환한다.
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.accessDeniedPage("/accessDenied"); // 접근 권한이 없을 때 리다이렉트될 페이지 설정
}
}
5. FilterSecurityInterceptor
최종 보안 필터로, URL 기반 접근제어를 제공. 보안 체인의 마지막 필터로 동작하며, 권한 검사를 수행한다.
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 요청에 대한 권한 설정
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // /admin/** 경로는 ADMIN 역할이 있어야 접근 가능
.antMatchers("/user/**").hasRole("USER") // /user/** 경로는 USER 역할이 있어야 접근 가능
.anyRequest().authenticated() // 그 외의 모든 요청은 인증 필요
.and()
.formLogin()
.permitAll();
}
}
'Spring Boot' 카테고리의 다른 글
[Spring Boot] 암호화/복호화(AES, RSA, BCrypt) (2) | 2024.07.24 |
---|---|
[Spring Boot] 어노테이션(Annotation) (0) | 2024.07.24 |
[Spring Boot] 트랜잭션(Transaction) (0) | 2024.07.19 |
[Spring Boot] Controller, Service, Mapper, DTO (0) | 2024.07.18 |
[Spring Boot] Batch 기본 개념 (0) | 2024.07.18 |