I am developing a Cordova application.
When I submit an $.ajax POST request from the Cordova app running on my physical device (not emulator) I receive a status code 403 forbidden.
I can make a GET request from the device no problem. I can also login using a POST (receiving a 302 Found Response).
Requests from Chrome are handled perfectly.
I am using Spring / Tomcat. I have added CORS filter to my tomcat web.xml, and have added allow-origins * to my config.xml in Cordova.
Below is the log extracts produced when I make the POST request, first from Chrome, secondly from my Device.
Chrome Request:
org.springframework.security.web.FilterChainProxy: /submit-check at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' org.springframework.security.web.context.HttpSessionSecurityContextRepository: No HttpSession currently exists org.springframework.security.web.context.HttpSessionSecurityContextRepository: No SecurityContext was available from the HttpSession: null. A new one will be created. org.springframework.security.web.FilterChainProxy: /submit-check at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter' org.springframework.security.web.header.writers.HstsHeaderWriter: Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@461e0eb8 org.springframework.security.web.FilterChainProxy: /submit-check at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter' org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/submit-check'; against '/j_spring_security_logout' org.springframework.security.web.FilterChainProxy: /submit-check at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/submit-check'; against '/j_spring_security_check' org.springframework.security.web.FilterChainProxy: /submit-check at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' org.springframework.security.web.authentication.AnonymousAuthenticationFilter: Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' org.springframework.security.web.FilterChainProxy: /submit-check at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter' org.springframework.security.web.session.SessionManagementFilter: Requested session ID 2BB345F22D731DB9A10B0BB65950502D is invalid. org.springframework.security.web.FilterChainProxy: /submit-check at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/submit-check'; against '/**.html' org.springframework.security.web.access.intercept.FilterSecurityInterceptor: Public object - authentication not attempted org.springframework.security.web.FilterChainProxy: /submit-check reached end of additional filter chain; proceeding with original chain org.springframework.web.servlet.DispatcherServlet: DispatcherServlet with name 'dispatcher' processing POST request for [/ab/submit-check] org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: Looking up handler method for path /submit-check org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: Returning handler method [public org.springframework.web.servlet.ModelAndView com.gm.ab.controller.MobileNavigation.save(java.lang.String)] org.springframework.beans.factory.support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'mobileNavigation' org.springframework.web.servlet.DispatcherServlet: Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling org.springframework.web.servlet.DispatcherServlet: Successfully completed request org.springframework.security.web.access.ExceptionTranslationFilter: Chain processed normally org.springframework.security.web.context.HttpSessionSecurityContextRepository: SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. org.springframework.security.web.context.SecurityContextPersistenceFilter: SecurityContextHolder now cleared, as request processing completed
Cordova Request
org.springframework.security.web.FilterChainProxy: /submit-check at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' org.springframework.security.web.context.HttpSessionSecurityContextRepository: No HttpSession currently exists org.springframework.security.web.context.HttpSessionSecurityContextRepository: No SecurityContext was available from the HttpSession: null. A new one will be created. org.springframework.security.web.FilterChainProxy: /submit-check at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter' org.springframework.security.web.header.writers.HstsHeaderWriter: Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@461e0eb8 org.springframework.security.web.FilterChainProxy: /submit-check at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter' org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/submit-check'; against '/j_spring_security_logout' org.springframework.security.web.FilterChainProxy: /submit-check at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/submit-check'; against '/j_spring_security_check' org.springframework.security.web.FilterChainProxy: /submit-check at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' org.springframework.security.web.authentication.AnonymousAuthenticationFilter: Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: 192.168.1.5; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' org.springframework.security.web.FilterChainProxy: /submit-check at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter' org.springframework.security.web.session.SessionManagementFilter: Requested session ID F26DAEDA16CA5DAE443ABF8A4ADD836F is invalid. org.springframework.security.web.FilterChainProxy: /submit-check at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' org.springframework.security.web.FilterChainProxy: /submit-check at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/submit-check'; against '/**.html' org.springframework.security.web.access.intercept.FilterSecurityInterceptor: Public object - authentication not attempted org.springframework.security.web.FilterChainProxy: /submit-check reached end of additional filter chain; proceeding with original chain org.springframework.security.web.access.ExceptionTranslationFilter: Chain processed normally org.springframework.security.web.context.HttpSessionSecurityContextRepository: SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. org.springframework.security.web.context.SecurityContextPersistenceFilter: SecurityContextHolder now cleared, as request processing completed
The logs are identical, except for these lines which are in the request originating from Chrome:
org.springframework.web.servlet.DispatcherServlet: DispatcherServlet with name 'dispatcher' processing POST request for [/ab/submit-check] org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: Looking up handler method for path /submit-check org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: Returning handler method [public org.springframework.web.servlet.ModelAndView com.gm.ab.controller.MobileNavigation.save(java.lang.String)] org.springframework.beans.factory.support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'mobileNavigation' org.springframework.web.servlet.DispatcherServlet: Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling org.springframework.web.servlet.DispatcherServlet: Successfully completed request
For some reason the request originating from Cordova is not being sent to Spring's DispatcherServlet and I am at a loss as to why not.
I have installed Weinre to remote debug and the request data sent by Chrome and Cordova seems to be identical (though Weinre misses off most of the header information).
Managed to fix this.
The issue was having a CORS filter in my tomcat web.xml (the tomcat global web.xml in conf). For a Cordova app that doesn't need to be there.
Cordova sends a request through having header "Origin : file://". If the CORS filter is set in Tomcat then the request will fail.
Removing the CORS filter from the web.xml works and I can now POST data.
来源:https://stackoverflow.com/questions/24973290/cordova-post-request-forbidden-403-not-reaching-dispatcher-servlet