Spring Boot Groovy模板未将_csrf添加到模型

时间:2015-06-29 17:42:16

标签: spring groovy spring-security spring-boot

我有一个非常简单的Spring Boot应用程序,它包含一个主Application.java(使用默认的main方法),一个MainController(有一个requestMapping到/ login)和一个SecurityConfig(主要是默认值)。

我的问题在于Groovy模板中的_csrf支持。使用FreeMarker一切正常,但是当我切换到GroovyTemplates时,_csrf参数不会被放入模型中。

Groovy模板中是否存在错误,我需要手动获取令牌,或者是否有一些配置步骤我不知道(虽然我不知道为什么它适用于FreeMarker)?

更新:

我在login.tpl(Groovy Template)上打印了this.properties(HashMap):

{class=class login, out=java.io.BufferedWriter@5e2aead3, model={error=Optional.empty, org.springframework.validation.BindingResult.error=org.springframework.validation.BeanPropertyBindingResult: 0 errors, spring=org.springframework.web.servlet.support.RequestContext@1d99fb33, springMacroRequestContext=org.springframework.web.servlet.support.RequestContext@7fcc5c78}}

属性映射中的模型键包含参数

我使用:

在Controller操作中添加了错误
@RequestMapping(value="/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam Optional<String> error) {
    return new ModelAndView("views/login", "error", error);
}

2 个答案:

答案 0 :(得分:3)

使用GroovyMarkupViewGroovyMarkupViewResolver时,视图的属性仅包含模型中可用的属性(以及为Groovy添加的属性)。

要包含请求属性,请将exposeRequestAttributes的{​​{1}}属性设置为GroovyMarkupViewResolver。理想情况下,这可以通过在true

中设置以下属性来完成
application.properties

但由于this issue目前无法实现。

要解决此问题,请创建一个spring.groovy.template.exposeRequestAttributes=true ,检查传入的bean是否为BeanPostProcessor(如果您想要更通用的方法,则检查GroovyMarkupViewResolver)。如果是这样,请将AbstractTemplateViewResolver设置为true。

exposeRequestAttributes

执行此操作后public class TemplateViewResolverPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instance GroovyMarkupViewResolver) { ((GroovyMarkupViewResolver) bean).setExposeRequestAttributes(true); } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } 可用密钥CsfrToken,请注意这是实际的_csfr

另一种解决方案是创建CsfrToken实现HandlerInterceptor方法并将postHandle属性添加到模型中。这样您就可以简单地添加令牌的值而不是实际的令牌本身。这适用于所使用的任何视图技术。

_csfr

然后将其添加为拦截器,您将获得可用的值。

答案 1 :(得分:0)

因此处理此问题的方法是在Controller中手动将_csrf属性添加到模型中。例如:

model.addAttribute( "_csrf", request.getAttribute("_csrf") );

如果服务器上有很多视图,我不建议您这样做。我建议您遵循@ M-Deinnum中的一个选项。但是,为了进行快速测试,这是可行的。