我有一个非常简单的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);
}
答案 0 :(得分:3)
使用GroovyMarkupView
和GroovyMarkupViewResolver
时,视图的属性仅包含模型中可用的属性(以及为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中的一个选项。但是,为了进行快速测试,这是可行的。