title: How to pass an Object from AJAX to a Spring Controller with Spring Security
body: <p>I’m trying to pass an Object from an AJAX to a Spring Controller. I tried basically every solution I came across here on SO and a great number of other online resources but to no avail. I can’t figure out what am I doing wrong so I seek your help.
  I am working on a simple web shop and all I would like to do at this point is to pass login values(username and password) to the controller from a form which is in a modal on a html file.
  Here is my code:
  <strong>LoginCredentials.java</strong></p>
  
  <pre><code>public class LoginCredentials {
  
      private String username;
      private String password;
      // getters and setters
  }
  </code></pre>
  
  <p><strong>Index.html</strong> (the html part with most of bootstrap removed)</p>
  
  <pre><code>&lt;div id="loginModal" class="modal fade"&gt;
      &lt;div class="modal-body"&gt;
          &lt;form id="loginForm" method="POST"&gt;
              &lt;input type="text" class="form-control" id="username"&gt;
              &lt;input type="password" class="form-control" id="password"&gt;
              &lt;button type="submit"&gt; Login&lt;/button&gt;
          &lt;/form&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>Index.html</strong> (the script part)</p>
  
  <pre><code>&lt;script&gt;
  $(document).ready(function() {
      $('#login').on('click', function() {
          $('#loginModal').modal('toggle');
              $('#loginForm').submit(function(event) {
                  var formData = {
                      'username' : $('#username').val(),
                      'password' : $('#password').val()
                  };
  
                  var loginUrl = '/login';
  
                  $.ajax({
                      type : 'POST',
                      contentType : "application/json",                       
                      data : JSON.stringify(formData),
                      url : loginUrl,
                      success : function(payload) {
                          console.log('success block');
                          console.log(formData);
                      },
                      error : function(payload) {
                          console.log('this is the URL: ' + loginUrl);
                          console.log('this is the formData: ');
                          console.log(formData);
                          alert('Something went wrong');
                          }
                  });
                  event.preventDefault();
              });
          });
      });
  &lt;/script&gt;
  </code></pre>
  
  <p><strong>LoginController.java</strong></p>
  
  <pre><code>@RequestMapping(value = "/login", method = RequestMethod.POST)
  public void login(@RequestBody LoginCredentials credentials) {
      String username = credentials.getUsername();
      String password = credentials.getPassword();
      System.out.println("User: " + username + "\nPass: " + password);
      // logic to access the database
      }
  </code></pre>
  
  <p>What happens is that the code in the AJAX always end up in the error function. The url and the JSON values are picked up alright and displayed in the console. The ‘Network’ informs me of a 403 error…</p>
  
  <p><strong>Edit no1 - server side stack trace</strong></p>
  
  <pre><code>
    .   ____          _            __ _ _
   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    '  |____| .__|_| |_|_| |_\__, | / / / /
   =========|_|==============|___/=/_/_/_/
   :: Spring Boot ::        (v2.1.3.RELEASE)
  
  2019-07-25 11:18:07.092  INFO 8124 --- [  restartedMain] org.ogorodin.FishShopWebAppApplication   : Starting FishShopWebAppApplication on DESKTOP-3GFCDON with PID 8124 (C:\Users\igorv\source-eclipse\fish-shop-web-app\target\classes started by igorv in C:\Users\ogorodin\source-eclipse\fish-shop-web-app)
  2019-07-25 11:18:07.094  INFO 8124 --- [  restartedMain] org.ogorodin.FishShopWebAppApplication   : No active profile set, falling back to default profiles: default
  2019-07-25 11:18:07.129  INFO 8124 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
  2019-07-25 11:18:07.129  INFO 8124 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
  2019-07-25 11:18:07.959  INFO 8124 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
  2019-07-25 11:18:08.028  INFO 8124 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 63ms. Found 3 repository interfaces.
  2019-07-25 11:18:08.397  INFO 8124 --- [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$809c671f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
  2019-07-25 11:18:08.719  INFO 8124 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 443 (https) 8080 (http)
  2019-07-25 11:18:08.749  INFO 8124 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
  2019-07-25 11:18:08.750  INFO 8124 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.16]
  2019-07-25 11:18:08.756  INFO 8124 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_201\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jdk1.8.0_201/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_201/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_201/bin/../jre/lib/amd64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Java\jdk-10.0.1\bin;C:\Program Files\Java\jre-10.0.1\bin;C:\Program Files\Gradle\gradle-4.8.1\bin;C:\Users\ogorodin\.m2\wrapper\dists\apache-maven-3.5.3-bin\2c22a6s60afpuloj4v181qvild\apache-maven-3.5.3\bin;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\TortoiseGit\bin;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\nodejs\;C:\Program Files\MongoDB\Server\4.0\bin;C:\Program Files\Java\jdk1.8.0_191\bin;C:\Program Files\Java\jdk1.8.0_191\lib;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Maven\apache-maven-3.5.4\bin;C:\Users\ogorodin\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Microsoft VS Code\bin;C:\Users\ogorodin\AppData\Roaming\npm;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Users\igorv\eclipse\jee-2018-12\eclipse;;.]
  2019-07-25 11:18:08.853  INFO 8124 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
  2019-07-25 11:18:08.854  INFO 8124 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1725 ms
  2019-07-25 11:18:09.294  INFO 8124 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
  2019-07-25 11:18:09.667  INFO 8124 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
  2019-07-25 11:18:09.715  INFO 8124 --- [  restartedMain] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
      name: default
      ...]
  2019-07-25 11:18:09.765  INFO 8124 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate Core {5.3.7.Final}
  2019-07-25 11:18:09.766  INFO 8124 --- [  restartedMain] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
  2019-07-25 11:18:09.885  INFO 8124 --- [  restartedMain] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
  2019-07-25 11:18:10.009  INFO 8124 --- [  restartedMain] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
  2019-07-25 11:18:10.592  INFO 8124 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
  2019-07-25 11:18:11.066  INFO 8124 --- [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@48ab7426, org.springframework.security.web.context.SecurityContextPersistenceFilter@7ed4df6f, org.springframework.security.web.header.HeaderWriterFilter@771313fd, org.springframework.security.web.csrf.CsrfFilter@79eb5a49, org.springframework.security.web.authentication.logout.LogoutFilter@6758cf57, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@1712267a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@b0f5215, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4e467cdc, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@205da9be, org.springframework.security.web.session.SessionManagementFilter@147b37f, org.springframework.security.web.access.ExceptionTranslationFilter@4b97bdc5, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@42a952fa]
  2019-07-25 11:18:11.204  INFO 8124 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
  2019-07-25 11:18:11.455  WARN 8124 --- [  restartedMain] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
  2019-07-25 11:18:11.552  INFO 8124 --- [  restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page template: index
  2019-07-25 11:18:11.723  INFO 8124 --- [  restartedMain] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
  2019-07-25 11:18:11.792  INFO 8124 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
  2019-07-25 11:18:12.245  INFO 8124 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 443 (https) 8080 (http) with context path ''
  2019-07-25 11:18:12.247  INFO 8124 --- [  restartedMain] org.ogorodin.FishShopWebAppApplication   : Started FishShopWebAppApplication in 5.395 seconds (JVM running for 6.101)
  2019-07-25 11:18:20.338  INFO 8124 --- [-nio-443-exec-4] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
  2019-07-25 11:18:20.339  INFO 8124 --- [-nio-443-exec-4] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
  2019-07-25 11:18:20.347  INFO 8124 --- [-nio-443-exec-4] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
  Hibernate: SELECT products.id, products.title, products.the_type AS productType,stock.price, stock.quantity FROM products LEFT  JOIN stock ON products.id=stock.product_id
  </code></pre>
  
  <p>Edit no2 - <strong>SecurityConfig.java</strong></p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private UserPrincipalDetailsService userPrincipalDetailsService;
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.authenticationProvider(authenticationProvider());
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests()
              .antMatchers("/").permitAll()
              .antMatchers("/login/**").permitAll() // this is the line I added
              .antMatchers("/admin/**").hasRole("ADMIN")
              .antMatchers("/api/**").hasRole("ADMIN")
              .antMatchers("/employee/**").hasAnyRole("EMPLOYEE", "ADMIN")
          .and().httpBasic();
      }
  
      @Bean
      DaoAuthenticationProvider authenticationProvider() {
          DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
          daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
          daoAuthenticationProvider.setUserDetailsService(this.userPrincipalDetailsService);
          return daoAuthenticationProvider;       
      }
  
      @Bean
      PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
  }
  
  </code></pre>
  
  <p>If I forgot to mention something that might be important to this issue please ask for additional information and I will edit this post. I tried to make this post as short as I could.
  I thank you for any help. Cheers!</p>