记录FreeMarker防xss的使用

149 阅读1分钟

配置Configuration

下图所配置的方式是通过classpath获取的,如果想从文件或者路径获取可以使用如下方式

// 设置模板所在目录
configuration.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));
package com.think.meta.config;

import freemarker.template.Configuration;
import javax.annotation.Resource;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader;
import org.springframework.ui.freemarker.SpringTemplateLoader;

@org.springframework.context.annotation.Configuration
public class FreeMarkerConfig {
  // 注入spring的ResourceLoader,或者也可以单独创建spring的DefaultResourceLoader
  @Resource private ResourceLoader resourceLoader;

  @SneakyThrows
  @Bean
  @Primary
  public Configuration configuration() {
    // 通过配置TemplateLoader->classpath
    SpringTemplateLoader springTemplateLoader =
        new SpringTemplateLoader(resourceLoader, "classpath:templates");
    Configuration configuration = new Configuration(Configuration.VERSION_2_3_32);
    configuration.setDefaultEncoding("UTF-8");
    configuration.setTemplateLoader(springTemplateLoader);
    return configuration;
    // 或者使用FreeMarkerConfigurer通过配置Template的加载路径,最后创建新的configuration;
// FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
// freeMarkerConfigurer.setDefaultEncoding("UTF-8");
// freeMarkerConfigurer.setTemplateLoaderPath("classpath:/templates");
// Configuration configuration = freeMarkerConfigurer.createConfiguration();
  }
}

防xss攻击

FreeMarker模板文件通过<#escape>标签包裹模板内容,会对相应的文本内容进行转义,从而防止xss攻击

<#--  定义标签  -->
<#escape x as x?html>
    <!doctype html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8"/>
        <meta http-equiv="cache-control" content="no-cache"/>
        <meta name="viewport" content="width=device-width" , initial-scale="1.0"/>
        <title>统一登录</title>
        <style>
            html,
            body {
                margin: 0px;
                padding: 0px;
                height: 100%;
            }

            .login-container {
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;

                background-image: url();
                background-repeat: no-repeat;
                background-position: center;
                background-size: 100%;
            }

            .login-iframe {
                min-width: 320px;
                min-height: 320px;
                border: none;
            }
        </style>
    </head>
    <body>
    <div class="login-container">
        <iframe
                class="login-iframe"
                src="${URL!"url参数不能为空"}"></iframe>
    </div>
    </body>
    </html>
</#escape>