반응형
이전글 : Survlet 기반 Application 아키텍쳐(1)
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().permitAll()
)
.httpBasic(withDefaults());
return http.build();
}
SecurityFilterChain를 사용하는 이유는 HttpSecurity를 통해 HTTP보안 설정 구성하기 위함이다.
보안 필터는 SecurityFilterChain API를 통해 FilterChainProxy에 삽입된다. 필터들은 인증, 권한 부여, 취약점 보호 등 다양한 목적으로 특정 순서대로 실행된다. 예를 들어 인증을 수행하는 필터가 권한 부여를 수행하는 필터보다 먼저 호출되도록 보장한다. 따라서 Spring Security의 필터 순서를 알고 고려할 필요는 없지만, 순서를 아는 것이 유익할 수 있다.
( cf.) : FilterOrderRegisteration Code )
FilterChain에 Custom Filter추가하기
1. 필터 생성하기
public class TenantFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// request header로 부터 tenant id 가져오기
String tenantId = request.getHeader("X-Tenant-Id");
// tenant id로 접근 가능한지 구분
boolean hasAccess = isUserAllowed(tenantId);
if (hasAccess) {
// 접근 가능하다면 doFilter수행
filterChain.doFilter(request, response);
return;
}
// 접근 불가능 하다면 예외처리
throw new AccessDeniedException("Access denied");
}
}
tip . 한 요청에 1번만 동작한다면 Filter을 implemet하는 것 보다 OncePerRequestFilter를 상속받는 것이 낫다.
2. Security Filter Chain에 Filter추가하기
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
// AuthorizationFilter가 동작이후에 TenantFilter가 동작하게 추가
.addFilterBefore(new TenantFilter(), AuthorizationFilter.class);
return http.build();
}
Builder 종류
- .addFilterBefore(A, B); // A필터 전에 B필터 추가
- .addFilterAfter(A, B); // A필터 후에 B필터 추가
- .addFilterAt(A, B); // A필터가 B필터 동작 위치에서 동작
주의점 1)
주의점 2)
스프링 부트는 자동으로 내장 컨테이너에 필터를 등록할 수 있으며, 이로 인해 필터가 중복으로 호출될 수 있다. 중복 호출을 피하려면 FilterRegistrationBean을 선언하고 enabled 속성을 false로 설정하여 스프링 부트가 컨테이너에 필터를 등록하지 않도록 해야한다.
@Bean
public FilterRegistrationBean<TenantFilter> tenantFilterRegistration(TenantFilter filter) {
FilterRegistrationBean<TenantFilter> registration = new FilterRegistrationBean<>(filter);
registration.setEnabled(false);
return registration;
}
반응형
'Backend > Spring | SpringBoot' 카테고리의 다른 글
[Spring Security] JPA를 이용한 DB 사용자 인증 (0) | 2024.03.20 |
---|---|
[Spring Security] 인증 표현식 (0) | 2024.03.20 |
[Spring Security] Survlet 기반 Application 아키텍쳐(1) (0) | 2024.03.19 |
[Spring Security] SpringSecurityConfig 적용 (0) | 2024.03.18 |
[Spring Security] Spring Security 적용 (0) | 2024.03.15 |