@@ -0,0 +1,94 @@
+package nextstep.app.config;
+
+import jakarta.servlet.Filter;
+import nextstep.app.domain.Member;
+import nextstep.app.domain.MemberRepository;
+import nextstep.security.UserDetailService;
+import nextstep.security.UserDetails;
+import nextstep.security.config.AuthenticationManager;
+import nextstep.security.config.AuthenticationProvider;
+import nextstep.security.config.BasicAuthenticationProvider;
+import nextstep.security.config.DaoAuthenticationProvider;
+import nextstep.security.config.DefaultSecurityFilterChain;
+import nextstep.security.config.FilterChainProxy;
+import nextstep.security.config.ProviderManager;
+import nextstep.security.config.SecurityContextHolderFilter;
+import nextstep.security.config.SecurityFilterChain;
+import nextstep.security.filter.BasicAuthFilter;
+import nextstep.security.filter.UsernamePasswordAuthFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.filter.DelegatingFilterProxy;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.List;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+    private final MemberRepository memberRepository;
+
+    public WebConfig(MemberRepository memberRepository) {
+        this.memberRepository = memberRepository;
+    }
+
+    @Bean
+    public DelegatingFilterProxy delegatingFilterProxy() {
+        return new DelegatingFilterProxy(filterChainProxy());
+    }
+
+    @Bean
+    public FilterChainProxy filterChainProxy() {
+        List<SecurityFilterChain> securityFilterChains = List.of(securityFilterChain());
+        return new FilterChainProxy(securityFilterChains);
+    }
+
+    @Bean
+    public SecurityFilterChain securityFilterChain() {
+        List<Filter> securityFilters = List.of(
+                new SecurityContextHolderFilter(),
+                new BasicAuthFilter(authenticationManager()),
+                new UsernamePasswordAuthFilter(authenticationManager())
+        );
+        return new DefaultSecurityFilterChain(securityFilters);
+    }
+
+    @Bean
+    public AuthenticationManager authenticationManager() {
+        List<AuthenticationProvider> providers = List.of(
+                daoAuthenticationProvider(),
+                basicAuthenticationProvider()
+        );
+        return new ProviderManager(providers);
+    }
+
+    @Bean
+    public BasicAuthenticationProvider basicAuthenticationProvider() {
+        return new BasicAuthenticationProvider(userDetailService());
+    }
+
+    @Bean
+    public DaoAuthenticationProvider daoAuthenticationProvider() {
+        return new DaoAuthenticationProvider(userDetailService());
+    }
+
+    @Bean
+    public UserDetailService userDetailService() {
+        return username -> {
+            Member member = memberRepository.findByEmail(username)
+                    .orElseThrow(() -> new IllegalArgumentException("해당하는 사용자를 찾을 수 없습니다."));
+            return new UserDetails() {
+                @Override
+                public String getUsername() {
+                    return member.getEmail();
+                }
+
+                @Override
+                public String getPassword() {
+                    return member.getPassword();
+                }
+            };
+        };
+    }
+
+}

리뷰: > Spring에서 관리하는 필터 (Security filter)의 경우 GenericFilterBean이나 OncePerRequestFilter같은걸 사용하던데 이건 스프링 의존성을 가지고 있어 Filter를 implement하는것보다 bean에 대한 추가적인 정보 등을 가져올 수 있더라고요.
궁금한게, delegatingFilterproxy는 tomcat에 등록되는 filter라 GenericFilterBean를 사용하는게 의미가 없어 보이는데,
filterchainproxy의 virtualfilterchain을 타고 어떻게 스프링과 이어지는 그 경계가 궁금합니다. (delegatingfilterproxy 필터 뒤에 톰켓을통해 등록하는 필터들이 돌기전에 security filter로 등록된 스프링관련 동작이 작동하는건가요?)

서블릿과 스프링 시큐리티의 경계 지점이 DelegatingFilterProxy이라고 볼 수 있습니다.
먼저 요청의 흐름을 보면

1. 클라이언트 요청 (Tomcat)
2. Tomcat 필터 체인 실행
3. DelegatingFilterProxy (Spring Security)
4. FilterChainProxy
5. SecurityFilterChain
6. Spring Security 필터 끝
7. Tomact 필터 실행

순서로 진행된다고 볼 수 있습니다.
즉, 질문주신 대로 톰캣을 통해 등록된 필터들이 동작하기 전에 스프링 시큐리티로 등록된 스프링 관련 동작이 먼저 수행되게 됩니다!