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).
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…