java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode

  • Table Of Contents

문제 상황

잘못된 username, password 로 로그인 시도 시 스프링 시큐리티에서는 BadCredentialException 을 생성 하여 예외를 던지게 된다. 해당 예외를 따로 처리하지 않는 경우 클라이언트에는 401 UNAUTHORIZED 이 아닌 400 Bad Request 가 반환 되기 때문에, 이를 커스텀 에러 클래스 등으로 정의하여 별도로 처리하게 했다.

그런데, 이상하게도 POST Request 관련 에러를 뱉어낸다.

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/login": cannot retry due to server authentication, in streaming mode; nested exception is java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode

	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:743)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:669)
	at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:444)
	at org.springframework.boot.test.web.client.TestRestTemplate.postForEntity(TestRestTemplate.java:502)

  .. 중략 ..
  
Caused by: java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1638)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
	at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:55)
	at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:51)
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:765)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
	... 36 more

문제 파악

찾다 보니 여기를 찾게 되었다. 내용을 보니 401이 리턴되는 상황에서 기본 com.sun.* HTTP 클라이언트는 실패한 요청의 본문에 액세스할 수 없어 해당 문제가 발생하는 것 같다고 한다.

즉, 401 에러가 리턴되는 상황에서는 본문이 비어있기 때문에 액세스 할 수 없어 해당 문제가 발생하는 것이고 대안으로는 HttpComponentsClientHttpRequestFactory 사용 또는 Apache Http Client 사용을 추천하고 있다(링크)

해결

BadCredentialsException에 대한 처리 하지 않기

별도의 처리를 하지 않으면 Body를 다시 읽을 일이 없으므로 위와 같은 HttpRetryException는 발생하지 않는다.

BadCredentialsException에 대해 처리를 하고, Apache Http Client를 사용한다.

Apache Http Client를 사용하면 해당 에러를 회피할 수 있다.


© 2024. Chiptune93 All rights reserved.