Spring Boot Groovy模板未在模型中添加_csrf [英] Spring Boot Groovy Templates Not Adding _csrf to model

查看:146
本文介绍了Spring Boot Groovy模板未在模型中添加_csrf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

Groovy模板中是否存在错误,我必须手动执行一些操作以获取令牌,或者我缺少一些配置步骤(尽管我不知道为什么它对FreeMarker有用)?

更新:

我在login.tpl(Groovy模板)上打印了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);
}

解决方案

使用GroovyMarkupViewGroovyMarkupViewResolver时,视图的属性仅包含模型中可用的属性(其中一些是为Groovy添加的).

要包括请求属性,请将GroovyMarkupViewResolverexposeRequestAttributes属性设置为true.理想情况下,这是通过在application.properties中设置以下属性来完成的.

spring.groovy.template.exposeRequestAttributes=true

但是由于此问题,目前无法实现.

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

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;
    }
}

在使用键_csfr使CsfrToken可用之后,请注意这是实际的CsfrToken.

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

public class CsrfAddingInterceptor extends HandlerInterceptorAdapter {

    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView mav) throws Exception {
        CsrfToken token = (CsrfToken) req.getAttribute(CsrfToken.class.getName())
        if (token != null) {
            mav.addAttribute(token.getParameterName(), token.getToken());
        }
    }

}

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

I have a very simple Spring Boot Application which consists of a main Application.java (with the default main method), a MainController (which has one requestMapping to /login), and a SecurityConfig (with mainly default values).

My problem is with the _csrf support in Groovy Templates. Everything works fine with FreeMarker, but when I switch to GroovyTemplates the _csrf param does not get put into the model.

Is there a bug in the Groovy Templates, something manually I have to do to grab the token, or is there some configuration step I'm missing (although I don't know why it would work for FreeMarker) ?

UPDATE:

I printed this.properties (HashMap) on the login.tpl (Groovy Template) :

{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}}

The model key in the properties map includes the parameters

I added error in the Controller action using the:

@RequestMapping(value="/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam Optional<String> error) {
    return new ModelAndView("views/login", "error", error);
}

解决方案

When using the GroovyMarkupView and the GroovyMarkupViewResolver the properties of the view only contain properties available in the model (and some added for Groovy).

To include the request attributes set the exposeRequestAttributes property of the GroovyMarkupViewResolver to true. Ideally this is done by setting the following property in the application.properties.

spring.groovy.template.exposeRequestAttributes=true

However due to this issue that currently isn't possible.

To work around it create a BeanPostProcessor which check if the incoming bean is a GroovyMarkupViewResolver (or AbstractTemplateViewResolver if you want a more general approach). If so set the exposeRequestAttributes to true.

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;
    }
}

After doing that the CsfrToken is available with the key _csfr, be aware that this is the actual CsfrToken.

Another solution is to create a HandlerInterceptor implement the postHandle method and add the _csfr property to the model. That way you can simply add the value of the token instead of the actual token itself. This will work with any view technology used.

public class CsrfAddingInterceptor extends HandlerInterceptorAdapter {

    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView mav) throws Exception {
        CsrfToken token = (CsrfToken) req.getAttribute(CsrfToken.class.getName())
        if (token != null) {
            mav.addAttribute(token.getParameterName(), token.getToken());
        }
    }

}

Then add it as an interceptor and you will have the value available.

这篇关于Spring Boot Groovy模板未在模型中添加_csrf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆