domix / jade4j-spring-boot-starter

Spring Boot jade4j Starter
Apache License 2.0
64 stars 20 forks source link

CSRF usage #4

Open nathand opened 9 years ago

nathand commented 9 years ago

Hi, I'm getting 2 different errors. 1 on the first form submission, and a different on subsequent ones. This happens when I have CSRF enabled with Spring Security

1 - Expected CSRF token not found. Has your session expired? 2 - Invalid CSRF Token '' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

I'm wondering if it's supposed to work out of the box, or if I'm supposed to overwrite anything in particular.

domix commented 9 years ago

You have to properly set your forms: http://docs.spring.io/autorepo/docs/spring-security/3.2.0.CI-SNAPSHOT/reference/html/csrf.html#csrf-include-csrf-token

This issue is not related to this project.

nathand commented 9 years ago

Aware of that. I've tried using _csrf.parameterName and _csrf.token. I'm getting null on all the following when applied to my form below.

{_csrf.parameterName}

{_csrf.token}

{_csrf.value}

{_csrf}

{csrf}

{csrf.token}

form(role="form", method="post", action="/login")
              input(type="hidden", name='_csrf', value=csrftoken, enctype="multipart/form-data")
              \\ - username, password fields
              button.btn.btn-default(type="submit")
                | Submit
domix commented 9 years ago

this is working for me:

html
  head
    title Sign in

  body

    h2 Login: Username and password

    form(method='POST', action='/login')
      table
        tbody
          tr
            td User:
            td
              input(type='text', value='', name='username')
          tr
            td Password:
            td
              input(type='password', value='', name='password')
          tr
            td(colspan= '2')
              input(type='submit', value='Login', name='submit')
              input(type='hidden', value='#{_csrf}', name='_csrf')
nathand commented 9 years ago

guess I'm really puzzled now. Must be something wrong with my security config. Not even a hello world authentication is working for me....

domix commented 9 years ago

This is my Spring Security Config it's Groovy code

package sindicato.alosh.web.config

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter

/**
 * Created by domix on 2/9/15.
 */
@Configuration
@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
  def publicPaths = [
    "/", "/resources/**", "/css/**", "/js/**", "/webjars/**", "/img/**"
  ]

  @Autowired
  public void configureGlobal(
    AuthenticationManagerBuilder auth) throws Exception {
    auth
      .inMemoryAuthentication()
      .withUser("user@foo").password("password").roles("USER").and()
      .withUser("admin@foo").password("password").roles("USER", "ADMIN");
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .antMatchers(*publicPaths).permitAll()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
      .rememberMe();
  }

}
nathand commented 9 years ago

I'd say mines looks like a java equivalent.... I've tried:

I'm using just spring-boot-starter-security and the jade dependencies in gradle. Guess I'm gonna sign up for a stackoverflow account now lol.

package com.mysite;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          .authorizeRequests()
              .antMatchers("/", "/public/**", "/js/**", "/css/**").permitAll()
              .anyRequest().authenticated()
              .and()
          .formLogin()
              .loginPage("/login")
              .permitAll();
              .and()
          .csrf();
  }

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

      auth
          .inMemoryAuthentication()
              .withUser("admin@mysite.com").password("password").roles("USER");
  }
}
nathand commented 9 years ago

I don't know how much it matters anymore, but here was a solution that was given to me.

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(csrfTokenAddingInterceptor());
  }

  @Bean
  public HandlerInterceptor csrfTokenAddingInterceptor() {
    return new HandlerInterceptorAdapter() {
      @Override
      public void postHandle(HttpServletRequest request,
          HttpServletResponse response, Object handler, ModelAndView view) {
        CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
        SecurityContext context = SecurityContextHolder.getContext();
        if (view != null) {
          if (token != null) {
            view.addObject(token.getParameterName(), token);
          }
        }

      }
    };
  }
}
domix commented 9 years ago

thanks @nathand , the idea to reopen this issue is to provide the configuration above automatically, if Spring Security is on your project.