2015-07-14 4 views
4

У меня есть приложение Spring Boot с настройкой java. Я только ссылаюсь на spring-boot-starter-jade4j и spring-boot-starter-security в моем файле build.gradle. Я пытаюсь понять, почему я не могу получить токен csrf. Вот мой SecurityConfigspring boot csrf и jade

@Configuration 
@EnableWebMvcSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Autowired 
    DataSource ds; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .antMatchers("/", "/signup", "/js/**", "/css/**", "/terms", "/privacy", "/favicon.ico").permitAll() 
      .anyRequest().authenticated() 
      .and() 
     .formLogin() 
      .loginPage("/login") 
      .permitAll() 
      .and() 
     .logout() 
      .logoutUrl("/logout") 
      .permitAll() 
      .and() 
     .csrf(); 
    } 
… 
} 

Вот моя форма Войти. Скрытое поле CSRF отображается в исходном коде, но токен csrf, похоже, не оценивается, и значение пусто.

extends _base 
block head 

block body 
    #bodContent.container-fluid 
    .row 
    .col-md-4 
    .col-md-4 
     br 
     .panel.panel-default 
     .panel-body 
      h1 Please log in 
      form(method="POST", action="/login") 
      input(type="hidden", name='_csrf', value='#{_csrf}') 
      .form-group 
       label(for="email") 
       | Email address 
       input#username.form-control(name="username", type="email", value="") 
      .form-group 
       label(for="password") 
       | Password 
       input#password.form-control(name="password", type="password", value="") 
      .checkbox 
       label 
       input(type="checkbox") 
       | Remember me 
      input.btn.btn-default(type="submit") 
       | Submit 
    .col-md-4 
+1

Вы пробовали использовать 'input (type =" hidden ", name = '# {_ csrf.parameterName}, value =' # {_ csrf.token} ')' как указано в [официальной документации] (http: // docs.spring.io/spring-security/site/docs/4.0.1.RELEASE/reference/htmlsingle/#csrf-include-csrf-token-form)? – manish

+0

Все эти: # {_} csrf.parameterName # {_} csrf.token # {_} csrf.value # {_ CSRF} – mugua

ответ

3

Мои подозрения в том, что Spring Загрузочный не выставляет маркер CSRF в качестве атрибута модели, которые можно было бы ожидать, так как маркер, как правило, подвергается как атрибут запроса (не атрибут модели). В типичном приложении Spring MVC атрибуты запроса могут быть представлены как атрибуты модели, установив exposeRequestAttributes на true на ViewResolver. Однако я не уверен, как это можно сделать с помощью распознавателя зрения Jade4j.

Однако существует обходное решение, которое заключается в том, чтобы вручную выставить маркер через конфигурацию приложения.

@Configuration 
@EnableAutoConfiguration 
public class ApplicationConfig extends WebMvcConfigurerAdapter { 
    public static void main(String... args) { 
    SpringApplication.run(ApplicationConfig.class, args); 
    } 

    @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()) 
     if (token != null) { 
      view.addObject(token.getParameterName(), token) 
     } 
     } 
    } 
    } 
} 

Теперь ваш код #{_csrf.parameterName} и #{_csrf.token} будет работать.

Примечание: Специальный кредит this answer.

+0

Спасибо. Некоторые изменения в синтаксисе, и это было сделано. Я вручную добавлял токены к моему представлению в своем контроллере в качестве работы, но это лучше и выглядит более корректно. – mugua

+0

У JadeViewResolver есть метод, называемый setExposeRequestAttributes, но установка его в true не помогает. – Traubenfuchs