Функция резервного копирования Websockets не работает в AWS
Мы сталкиваемся с проблемами, чтобы сделать запасной вариант работающим в среде AWS.
Сведения о настройке и общие сведения У нас есть веб-службы Spring REST, работающие в облачной среде AWS. Все сервисы работают под управлением tomcat 8. SSL завершается на ELB. Мы работаем с поставщиком, предоставляющим нам услуги AWS, который добавил еще один компонент (WAF) перед ELB, который не поддерживает веб-сокет. Поэтому вместо websocket мы тестировали потоковую передачу как запасной вариант. Мы используем пружинную websocket с помощью sockJS.
Опция резервирования также не работает, что дает нам следующее исключение
2015-12-07 18:07:43,859 [http-nio-8080-exec-5] DEBUG - Closing due to transport error for XhrStreamingSockJsSession[id=aahouqlj]
2015-12-07 18:07:43,859 [http-nio-8080-exec-5] DEBUG - Transport error in XhrStreamingSockJsSession[id=aahouqlj]
java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
>---at org.springframework.util.Assert.isTrue(Assert.java:65) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.http.server.ServletServerHttpAsyncRequestControl.<init>(ServletServerHttpAsyncRequestControl.java:58) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:213) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:202) [spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler.java:68) [spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58) [spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:272) [spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:407) [spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:90) [spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [servlet-api.jar:?]
>---at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:?]
>---at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.23]
>---at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.0.23]
>---at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.23]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at com.company.iac.common.security.AuthenticationFilter.successfulAuthentication(AuthenticationFilter.java:184) [iac-common-0.1.jar:0.1]
>---at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:235) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at com.company.iac.common.security.AuthenticationFilter.doFilter(AuthenticationFilter.java:132) [iac-common-0.1.jar:0.1]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
-at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
>---at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.23]
>---at com.company.iac.common.filter.CloudCORSFilter.doFilter(CloudCORSFilter.java:87) [iac-common-0.1.jar:0.1]
>---at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.23]
>---at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [catalina.jar:8.0.23]
>---at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.23]
>---at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:262) [catalina.jar:8.0.23]
>---at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617) [catalina.jar:8.0.23]
>---at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.23]
>---at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [catalina.jar:8.0.23]
>---at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-coyote.jar:8.0.23]
>---at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) [tomcat-coyote.jar:8.0.23]
>---at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) [tomcat-coyote.jar:8.0.23]
>---at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) [tomcat-coyote.jar:8.0.23]
>---at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_45]
>---at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_45]
>---at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.23]
>---at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]
2015-12-07 18:07:43,866 [http-nio-8080-exec-5] DEBUG - Resolving exception from handler [org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler@2cc2e2a8]: org.springframework.web.socket.sockjs.SockJsException: Uncaught failure in SockJS request, uri=https://devstaging.pr.apps.company.com:443/events/pr/664/aahouqlj/xhr_streaming?t=1449511663834; nested exception is org.springframework.web.socket.sockjs.SockJsTransportFailureException: Failed to open session; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
2015-12-07 18:07:43,866 [http-nio-8080-exec-5] DEBUG - Resolving exception from handler [org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler@2cc2e2a8]: org.springframework.web.socket.sockjs.SockJsException: Uncaught failure in SockJS request, uri=https://devstaging.pr.apps.company.com:443/events/pr/664/aahouqlj/xhr_streaming?t=1449511663834; nested exception is org.springframework.web.socket.sockjs.SockJsTransportFailureException: Failed to open session; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
Caused by: org.springframework.web.socket.sockjs.SockJsTransportFailureException: Failed to open session; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
>---at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:220) ~[spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler.java:68) ~[spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58) ~[spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:272) ~[spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:407) ~[spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:90) ~[spring-websocket-4.1.7.RELEASE.jar:4.1.7.RELEASE]
>---... 63 more
Мы используем весеннюю версию 4.1.7. Я мог видеть, что filterchain и сервлет по умолчанию поддерживают асинхронную поддержку. Весенний конфиг безопасности выглядит так
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().logout().disable().anonymous().disable().authorizeRequests()
.anyRequest().permitAll().and().addFilterBefore(authenticationFilter() , ExceptionTranslationFilter.class).
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
Фильтр авторизации расширяет AbstractAuthenticationProcessingFilter
открытый класс AuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public AuthenticationFilter(AuthenticationManager authenticationManager) {
super(new DummyRequestMatcher());
this.setAuthenticationManager(authenticationManager);
}
Нужно ли в auth Filter включать асинхронную поддержку? Если да, то я не нашел способ сделать это. Я предполагаю, что springsecurityfilters по умолчанию установил асинхронный флаг.
Вы видите что-нибудь еще, что я пропускаю?
1 ответ
Было несколько проблем. Первая проблема была с клапаном, который мы представили. Это действует как фильтр, поэтому нам нужно установить флаг async в true(). Документация Tomcat не говорит об этом, но обнаружила, что это от стека перепускного клапана также является фильтром. Вторая проблема была с объектом аутентификации из пружинной защиты. Мы пропустили реализацию метода equals и, следовательно, перед подключением (xhr_send) вызов не удался с ошибкой 404.