정의

사용자의 로그인 요청을 최초로 수신하는 엔트리포인트

인증되지 않은 Authentication 객체를 생성해 AuthenticationManager에게 전달하며,

이후 인증이 완료된 상태로 돌려받아 SecurityContext에 저장하는 역할을 담당

(JWT토큰 방식을 사용할 경우 stateless이므로 SecurityContext 저장 과정이 필요 없음)

코드 예시

@RequiredArgsConstructor
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private final AuthenticationManager authenticationManager;
    private final JwtTokenService jwtTokenService;

    // 로그인 요청을 받으면 여기로 들어오고 authenticationManager에게 처리 위임
    @SneakyThrows
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){
        ObjectMapper objectMapper = new ObjectMapper();
        LoginDto loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class);

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                loginDto.email(), loginDto.password()
        );

        return authenticationManager.authenticate(authenticationToken);
    }

    // authenticationManager가 처리를 마치고 여기로 돌려줌 -> 토큰 발행해서 응답 나감
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain filterChain,
                                            Authentication authResult
                                            ) throws ServletException, IOException {
        Member member = (Member) authResult.getPrincipal();

        String accessToken = jwtTokenService.generateAccessToken(member, TokenPrefix.BEARER);
        String refreshToken = jwtTokenService.generateRefreshToken(member);

        response.setHeader("Authorization", accessToken);
        response.setHeader("Refresh", refreshToken);

        // AuthenticationSuccessHandler 추가 호출
        this.getSuccessHandler().onAuthenticationSuccess(request, response, authResult);
    }
}

이 클래스는 스프링 시큐리티 보안 필터 중 하나로 반드시 시큐리티 필터 체인에 등록해줘야 작동함

Security Filter Chain 구성

해당 문서의 CustomFilterConfigurer 적용 부분 참조