카카오 SNS 로그인 시 Connection reset

19:19:58.188 [ajp-nio-18009-exec-102] ERROR o.s.b.w.s.support.ErrorPageFilter - Forwarding to error page from request [/com/sns/kakaotalk/callback.do] due to exception [I/O error on POST request for “https://kauth.kakao.com/oauth/token”: Connection reset; nested exception is java.net.SocketException: Connection reset]
org.springframework.web.client.ResourceAccessException: I/O error on POST request for “https://kauth.kakao.com/oauth/token”: Connection reset; nested exception is java.net.SocketException: Connection reset
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:579)
at kr.or.kbiz.web.common.sns.KakaoTalkController.getToken(KakaoTalkController.java:139)
at kr.or.kbiz.web.common.sns.KakaoTalkController.callback(KakaoTalkController.java:109)
at sun.reflect.GeneratedMethodAccessor2402.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at kr.or.kbiz.security.filter.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66)
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:528)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.ha.session.JvmRouteBinderValve.invoke(JvmRouteBinderValve.java:182)
at org.apache.catalina.ha.tcp.ReplicationValve.invoke(ReplicationValve.java:322)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:476)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:810)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
… 105 common frames omitted

===============================================
기존까지 잘 되다가 3.24일 오전부터 카카오로 SNS 로그인 시 해당 로그가 출력되며 로그인이 되지 않습니다.

카카오측과 socket 부분에 read write 문제가 생겨 close가 되지 않는 것 같은데 확인 가능할까요?

안녕하세요~
확인을 위해 앱 ID 알려주세요~


앱ID
https://developers.kakao.com/ 의 내 애플리케이션>앱 설정>요약 정보 : 기본정보에 있는 앱 ID
숫자로된 ID 입니다~
ex) 123456

355581 입니다

361953 이 ID도 확인 부탁드립니다

@jongseop94

위에 기재해주신 에러 로그가 몇일 로그인가요?

361953 디벨로퍼스앱은 /oauth/token 호출 이력을 보니 Java/1.8.0_271로 정상호출되고 있는 것으로 보이는데요.
355581 디벨로퍼스앱은 /oauth/token 호출 이력이 없습니다.

위에 기재해주신 에러는 355581 디벨로퍼스앱 호출 시, 발생하나요?

확인해보니 355581 은 카카오 지도 api여서 호출 시 문제가 발생하진 않는 것으로 보이구요

361953 ID가 로그인 관련 API인데 token을 불러오는 과정에서 오류가 발생합니다.

로컬 환경에서는 잘 작동하고 개발, 운영 즉 서버에서 호출 시 오류가 발생해요

Connection reset; nested exception is java.net.SocketException 에러는 일반적으로 호출하는 쪽 에러인데요.

간헐적인 상황이 아니라 항상 에러 발생한다면
TLS버전 문제일 수 있어요. 운영 서버의 Java 버전 확인해주시겠어요?

Auth서버 및 API서버는 어떤 SSL 버젼을 지원하나요?

1.8.0_221 입니다

Dhttps.protocols 설정 변경하셔서 호출 해보시겠어요?

  • TLSv1 ~ 1.3 호출 가능하고 SSLv2, 3 은 보안상 호출 불가능합니다.

https://www.ssllabs.com/ssltest/analyze.html?d=www.kbiz.or.kr

담당 사이트 SSL Server Test 결과 입니다. 확인 가능하실까요?

API호출하시는 방식으로 아래 주소 호출하셔서 정상 호출 되는지 테스트 해주시겠어요?

kakao.com 에서 사용하는 SSL루트 인증서 제공 업체 테스트 URL인데요. TLSv1.2이상 접근 허용하는 것으로
정상 접근된다면 TLS문제는 아닌걸로 보고 다른 방향 검토해보면 될 것 같습니다.

host: global-root-g2.chain-demos.digicert.com
port: 443

링크가 깨진 것 같네요. 링크 확인해서 다시 남겨 놓을게요.
1개의 좋아요

https://kauth.kakao.com/oauth/token 을 호출하고 있는데
이 url을 말씀해주신 url로 변경해서 해보란 말씀이실까요?

변경이라기 보다는 API 호출 테스트 부탁드립니다.
SSL버전 문제인지 정확한 판단을 위해 카카오가 아닌 API호출 해보면
요청측 Network Outbound 문제인지 파악이 가능할 것 같아요.

(1) 간헐적 Connection reset에러라면 요청 측 코드가 잘 못된 것이고
(2) 항상 Connection reset에러라면
(2-1) SSL버전이 잘못된 경우
(2-2) 요청측에서 카카오측으로 가는 Network Outbound 를 막은 경우

정도일 것 같습니다. 해당 관점으로 문제 파악해보시면 좋을 것 같아요.

카카오 로그인 등 카카오 api를 위한 방화벽 허용

20220329140433
호출했을 때 200 떨어지는 것 확인했습니다.

간혈적인 문제는 아닌 것 같습니다.
03.23일 까지 정상동작하다가 24일 오전부터 갑자기 안되고 있거든요

혹시 의심되는 부분이 있을까요? 로컬에서는 제대로 호출하고 있습니다.

호출하시는 서버 환경 문제인듯한데요.

기존에 정상 작동 하셨다하시니… 유추하기가 어렵네요.

혹시, 24일 즈음해서 서버 또는 네트워크, 방화벽 설정 변화는 없나요?
(March 24th 2022, 00:04:26.883 까지 운영 서버에서 정상 호출 했었습니다. 그 이후 뭔가 변화가 있을 것 같아요.)
(개발과 운영의 IP대역이 같은데, 개발서버를 운영IP로 설정해서 정상 작동 테스트 가능하실까요?)

361953 디벨로퍼스앱의 로그상 아래와 같이 호출하신 것으로 보이는데 별다른 특이점이나 차이점은 없네요.

개발: User-Agent (Java/1.8.0_271), IP ***.46.***.243
운영: User-Agent (Java/1.8.0_221), IP ***.46.***.252

답변 감사합니다.

따로 작업한게 없다고들 하시는데
카카오측에서 공인 IP 를 막거나 그런 일은 없는 거죠,?

https://devtalk.kakao.com/t/api/79752?source_topic_id=93951
이 url에 등록된 도메인, port 등 모두 차단된게 없다고 하네요

카카오 kauth관련 IP와 소유하신 운영, 개발 IP간의 차단 여부 조회를 해봤지만 카카오측에서도 차된되어 있지 않았습니다.

203.133.166.32
27.0.237.15
***.46.***.243
***.46.***.252

Connection reset; nested exception is java.net.SocketException 에러는 서버측 차단에 의해 발생하지 않고 호출자측에서 호출 하지 못하는 경우 발생하는 에러로

서버측 차단인 경우 reset by peer; 에러가 발생하는 것으로 알고 있습니다.
지금까지 문의 받은 Connection reset에러는 (1) SSL버전 문제 이거나 (2) 호출자 측 네트워크(정확히 어떤 문제인지는 전달 받지 못했어요) 문제로 피드백 받았었는데요.

아래와 같이 호출 하시고 피드백 주시겠어요?

  • 아래 두 주소 API호출

https://kauth.kakao.com/.well-known/jwks.json
https://test-kapi.kakao.com/test-ca-certificates

  • 아래 주소 Curl과 웹브라우저로 호출

https://kauth.kakao.com/oauth/token

로컬 : {“error”:“invalid_client”,“error_description”:“Bad client credentials”,“error_code”:“KOE010”}
개발 : curl: (35) TCP connection reset by peer
운영 : curl: (35) TCP connection reset by peer

명령어로 확인해보니 위와 같이 출력됩니다 개발서버와 운영서버의 문제일까요?

말씀해주신대로 두 주소 API 호출 시 로컬에서는 200 OK 및 토큰값이 출력되지만

개발, 운영에서는 connection reset이 출력되네요. SSL 인증서 문제로 보이는데 맞을까요?

개발환경은 잘된다고 알고 있었는데요. 개발환경에 변화가 있나요?

 개발: User-Agent (Java/1.8.0_271), IP ***.46.***.243

개발환경에서 java 로 호출 시, 정상 작동하고 있나요?

개발, 운영 서버 IP알려주시겠어요?