title: Cordova POST - Request Forbidden 403. Not reaching Dispatcher Servlet
body: <p>I am developing a Cordova application.</p>
  
  <p>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.</p>
  
  <p>I can make a GET request from the device no problem. I can also login using a POST (receiving a 302 Found Response).</p>
  
  <p>Requests from Chrome are handled perfectly. </p>
  
  <p>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.</p>
  
  <p>Below is the log extracts produced when I make the POST request, first from Chrome, secondly from my Device.</p>
  
  <p><strong>Chrome Request:</strong></p>
  
  <blockquote>
    <p>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</p>
  </blockquote>
  
  <p><strong>Cordova Request</strong></p>
  
  <blockquote>
    <p>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</p>
  </blockquote>
  
  <p>The logs are identical, except for these lines which are in the request originating from Chrome:</p>
  
  <blockquote>
    <p>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</p>
  </blockquote>
  
  <p>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.</p>
  
  <p>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).</p>