title: Simple example of Spring Security with Thymeleaf
body: <p>hi I'm trying to follow a simple example about doing a simple login form page that i found in this page <code>http://docs.spring.io/autorepo/docs/spring-security/4.0.x/guides/form.html</code> </p>
  
  <p>the problem is that i´m getting this error everytime that i try to login i get this error: <code>Expected CSRF token not found. Has your session expired?</code> </p>
  
  <p>When i get this error i press the back button in my explorer and try a second time to log in and when i do that i get this error: <code>HTTP 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'</code></p>
  
  <p>in the tutorial page is this message: <code>We use Thymeleaf to automatically add the CSRF token to our form. If we were not using Thymleaf or Spring MVCs taglib we could also manually add the CSRF token using &lt;input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/&gt;</code> </p>
  
  <p>"so because i am using thymeleaf too i didnt add that tag to my page"</p>
  
  <p>i found another solution and it works and this solution is adding this to my security config class <code>.csrf().disable()</code> this solution works but i suppose that what this do is to disable csrf protection in my page and i dont want to disable this type of protection. </p>
  
  <p>this is my security-config class :</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class ConfigSecurity extends WebSecurityConfigurerAdapter {
  
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth
              .inMemoryAuthentication()
                  .withUser("user").password("password").roles("USER");
      }
  
  
      @Override
      protected void configure( HttpSecurity http ) throws Exception {
          http
  
          //.csrf().disable() is commented because i dont want disable this kind of protection 
          .authorizeRequests()
                  .anyRequest().authenticated()
                  .and()
              .formLogin()
                  .loginPage("/login")
                  .permitAll()
                  .and()
              .logout()                                    
                  .permitAll();
      }
  }
  </code></pre>
  
  <p>my security initialzer :</p>
  
  <pre><code>public class InitSecurity extends AbstractSecurityWebApplicationInitializer {
  
      public InicializarSecurity() {
          super(ConfigSecurity .class);
  
      }
  }
  </code></pre>
  
  <p>my app-config class where i have my thymeleaf configuration</p>
  
  <pre><code>@EnableWebMvc
  @ComponentScan(basePackages = {"com.myApp.R10"})
  @Configuration
  public class ConfigApp extends WebMvcConfigurerAdapter{
  
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          registry.addResourceHandler("/css/**").addResourceLocations("/css/**");
          registry.addResourceHandler("/img/**").addResourceLocations("/img/**");
          registry.addResourceHandler("/js/**").addResourceLocations("/js/**");
          registry.addResourceHandler("/sound/**").addResourceLocations("/sound/**");
          registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/**");
      }
  
      @Override
      public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
          configurer.enable();
      }
  
      @Bean
        public MessageSource messageSource() {
          ReloadableResourceBundleMessageSource messageSource = new       ReloadableResourceBundleMessageSource();
          messageSource.setBasenames("classpath:messages/messages");
          messageSource.setUseCodeAsDefaultMessage(true);
          messageSource.setDefaultEncoding("UTF-8");
          messageSource.setCacheSeconds(0);// # -1 : never reload, 0 always reload
          return messageSource;
      }
  //  THYMELEAF
  
          @Bean 
          public ServletContextTemplateResolver templateResolver() {
              ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
              resolver.setPrefix("/WEB-INF/views/pagLogin/");
              resolver.setSuffix(".html");
              resolver.setTemplateMode("HTML5");
              resolver.setOrder(0);
              resolver.setCacheable(false);
              return resolver;
          }
  
          @Bean 
          public SpringTemplateEngine templateEngine() {
              SpringTemplateEngine engine  =  new SpringTemplateEngine();
              engine.setTemplateResolver( templateResolver() );
              engine.setMessageSource( messageSource() );
  
  
  
              return engine;
          }
  
          @Bean 
          public ThymeleafViewResolver thymeleafViewResolver() {
              ThymeleafViewResolver resolver  =  new ThymeleafViewResolver();
  
              resolver.setTemplateEngine( templateEngine() );
              resolver.setOrder(1);
  
              resolver.setCache( false );
              return resolver;
          }
  
          @Bean
          public SpringResourceTemplateResolver thymeleafSpringResource() {
              SpringResourceTemplateResolver vista = new SpringResourceTemplateResolver();
              vista.setTemplateMode("HTML5");
              return vista;
          }
  }
  </code></pre>
  
  <p>my app-config initializer</p>
  
  <pre><code>public class InicializarApp extends AbstractAnnotationConfigDispatcherServletInitializer {
  
      @Override
      protected Class&lt;?&gt;[] getRootConfigClasses() {
          return null;
      }
  @Override
      protected Class&lt;?&gt;[] getServletConfigClasses() {
          return new Class[] { ConfigApp .class };
      }
  
      @Override
      protected String[] getServletMappings() {
          return new String[]{"/"};
      }
  
      @Override
      protected Filter[] getServletFilters() {
          return new Filter[] { new HiddenHttpMethodFilter() };
      }
  }
  </code></pre>
  
  <p>my login controller class</p>
  
  <pre><code>@Controller
  public class ControllerLogin {
  
  
  
      @RequestMapping(value = "/login", method = RequestMethod.GET)
      public String pageLogin(Model model) {
  
  
  
           return "login";
      }
  </code></pre>
  
  <p>my home controller class</p>
  
  <pre><code>@Controller
  public class HomeController {
  
          @RequestMapping(value = "/", method = RequestMethod.GET)
          public String home(Model model) {
  
  
          return "home";
          }
  
  
  }
  </code></pre>
  
  <p>my login.html</p>
  
  <pre><code>&lt;html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org"&gt;
    &lt;head&gt;
      &lt;title tiles:fragment="title"&gt;Messages : Create&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;div tiles:fragment="content"&gt;
          &lt;form name="f" th:action="@{/login}" method="post"&gt;               
              &lt;fieldset&gt;
                  &lt;legend&gt;Please Login&lt;/legend&gt;
                  &lt;div th:if="${param.error}" class="alert alert-error"&gt;    
                      Invalid username and password.
                  &lt;/div&gt;
                  &lt;div th:if="${param.logout}" class="alert alert-success"&gt; 
                      You have been logged out.
                  &lt;/div&gt;
  
                  &lt;label for="username"&gt;Username&lt;/label&gt;
                      &lt;input type="text" id="username" name="username"/&gt;        
                  &lt;label for="password"&gt;Password&lt;/label&gt;
                      &lt;input type="password" id="password" name="password"/&gt;    
  
                  &lt;div class="form-actions"&gt;
                      &lt;button type="submit" class="btn"&gt;Log in&lt;/button&gt;
                  &lt;/div&gt;
  
                  &lt;!-- THIS IS COMMENTED it dont work beacuse i am already using thymeleaf &lt;input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/&gt;  --&gt;
  
  
              &lt;/fieldset&gt;
          &lt;/form&gt;
      &lt;/div&gt;
  
  
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>my home.html  page only shows after i log in and the only way i can log in if is a put .csrf().disable() in my Security config class but i dont want to disable that protection , if i dont put that in my security config class i get the errors that i mention at the start of this question.</p>