관리 메뉴

제뉴어리의 모든것

UsernamePasswordAuthenticationFilter 를 상속받아 재구현 할때 조심할것 본문

BugNote

UsernamePasswordAuthenticationFilter 를 상속받아 재구현 할때 조심할것

제뉴어리맨 2022. 10. 19. 23:41

상황

JWT로 권한부여와 요청에대한 검증을 하려고 구현중일때,

레퍼런스 코드를 보고 구현하고 있는데

UsernamePasswordAuthenticationFilter를 상속받아 임의의 클래스를 만들고

인증이 성공했을때 토큰만 발행하면 되기 때문에 아래의 성공시 콜백 메소드만 재정의 하고

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                        FilterChain chain, Authentication authResult) throws IOException, ServletException {
		//토큰 생성하여 발행 코드 필요
}

 

아래의 인증 구현 메소드를 굳이 따로 Overriding 할 필요가 있을까란 생각을 했다.

    @SneakyThrows //예외처리를 명시적으로 해주는 애노테이션
    @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
	   
       //Username과 Password를 DTO 클래스로 역직렬화(Deserialization)하기 위해 ObjectMapper 인스턴스 생성
        ObjectMapper objectMapper = new ObjectMapper();

        //request로 들어온 Username과 Password를 LoginDto 객체로 만듦 (역 직렬화)
        LoginDto loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class);

        //리턴할 Authentication 구현 객체 생성
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());

        //검증 과정 거친 뒤 인증된 Authentication 리턴
        return authenticationManager.authenticate(authenticationToken);
}

단순히 AuthenticationManager에게 인증을 하라고 위임만 하기 때문이다.

그런데, 위에 메소드를 구현하지 않으면 

UsernamePasswordAuthenticationFilter 를 내가 구현한 클래스로 작동하지 않으면서(이건 어찌보면 당연하다)

아래에 주석이 적힌 라인에서 AuthenticationManager가 Null일면서 에러가 발생한다.

@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException {
		if (this.postOnly && !request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}
		String username = obtainUsername(request);
		username = (username != null) ? username.trim() : "";
		String password = obtainPassword(request);
		password = (password != null) ? password : "";
		UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
				password);
		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest); // 에러지점
	}

 

상속받았음에도 재정의 하지 않아서 내가 구현한 attemptAuthentication() 가 작동하지 않는것은 의도한것인데

왜 AuthenticationManager가 상위 클래스에서 Null인지는 모르겠다..

더 알아봐야할듯하다..

 

 

 

결론

UsernamePasswordAuthenticationFilter 를 상속받아 구현한다면,

attemptAuthentication() 메소드는 꼭 구현하여야 한다.