Spring Boot:在 JSONP 回调函数名称之前删除 /**/
Posted
技术标签:
【中文标题】Spring Boot:在 JSONP 回调函数名称之前删除 /**/【英文标题】:Spring Boot: Remove /**/ before JSONP callback function name 【发布时间】:2016-02-09 16:10:00 【问题描述】:我正在使用 @ControllerAdvice 尝试 JSONP 响应。但回调函数名前出现不必要的注释。
build.gradle
apply plugin: 'java'
repositories
mavenCentral()
dependencies
compile 'org.springframework.boot:spring-boot-starter-web:1.2.7.RELEASE'
应用
@SpringBootApplication
public class Application
public static void main(String[] args)
SpringApplication.run(Application.class, args);
控制器
@RestController
public class Controller
@ControllerAdvice
public static class JsonpAdvice extends AbstractJsonpResponseBodyAdvice
public JsonpAdvice()
super("callback");
@RequestMapping("/product")
public Product product(@RequestParam(value = "callback", required = false) String callback)
return new Product(1, "foo", 100);
产品
public class Product
int id;
String name;
int price;
public int getId()
return id;
/* getters, setters, constructor */
结果http://localhost:8080/product?callback=callback
/**/callback("id":1,"name":"foo","price":100);
如何在回调之前删除 /**/? 谢谢。
【问题讨论】:
【参考方案1】:generator.writeRaw("/**/");//NB! This is the added content
出于安全原因,如上面的代码,实际上还有另一种方法:
generator.writeRaw("\r\n")
避免 xss 攻击。
【讨论】:
【参考方案2】:我遇到了和你完全相同的问题,因此找到了你的帖子。但是,基于Spring Boot源代码:
@Override
protected void writePrefix(JsonGenerator generator, Object object) throws IOException
if (this.jsonPrefix != null)
generator.writeRaw(this.jsonPrefix);
String jsonpFunction =
(object instanceof MappingJacksonValue ? ((MappingJacksonValue) object).getJsonpFunction() : null);
if (jsonpFunction != null)
generator.writeRaw("/**/");//NB! This is the added content
generator.writeRaw(jsonpFunction + "(");
来自https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java,
哪里有generator.writeRaw("/**/");
,我真的不认为作者错误地添加了这个语句,他一定是故意添加的,他根本不希望它被删除。因此,好奇心促使我用几个小时来研究这个问题。 在jsonp回调函数名前加上generator.writeRaw("/**/");
语句,即/**/的原因是安全。
从链接https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/,它被告知“为了防止content sniffing attacks(click to see the meaning),在反射回调前加上/**/。这正是谷歌、Facebook和GitHub目前正在做的事情。”
即使是谷歌、Facebook 和 GitHub 目前也在这样做,我们删除 /**/
是否有意义?在我看来,我们绝对应该把它留在那里。我确实尝试在html客户端中使用带有/**/
的jsonp回调,它仍然可以正常工作。此外,jsonp 回调实现应该考虑来自https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ 的其他缓解和修复建议。 [Yahoo Finance REST API 实现https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22BHP.AX%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=foo
就是一个典型的例子。可以使用一些Header阅读工具来读取Header信息,看看它是如何实现的,以避免json劫持。
【讨论】:
【参考方案3】:@Configuration 注解在声明的地方
@Bean
public MappingJackson2HttpMessageConverter MappingJackson2HttpMessageConverter (ApplicationContext applicationContext)
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(applicationContext).build();
return new MappingJackson2HttpMessageConverter(objectMapper)
@Override
protected void writePrefix(JsonGenerator generator, Object object) throws IOException
String jsonpFunction =
(object instanceof MappingJacksonValue ? ((MappingJacksonValue) object).getJsonpFunction() : null);
if (jsonpFunction != null)
generator.writeRaw(jsonpFunction + "(");
;
替换类“MappingJackson2HttpMessageConverter”
【讨论】:
以上是关于Spring Boot:在 JSONP 回调函数名称之前删除 /**/的主要内容,如果未能解决你的问题,请参考以下文章