Reputation: 8090
I'm updating my application from
spring 3.2.5 to 4.2.0
spring security 3.1.4 to 4.0.2.
A lot of my controllers which used to display HTML now display plain text. I created a few test methods, the following displayed HTML in version 3 and displays plain text in version 4:
@RequestMapping(value = "/htmltest", method = RequestMethod.GET)
public void test(Writer writer, HttpServletRequest request, HttpServletResponse response) throws IOException {
writer.append("<html><head></head><body>"); //$NON-NLS-1$
writer.append("this is a HTML test");
writer.append("</body></html>"); //$NON-NLS-1$
writer.flush();
}
I also added produces = "text/html"
to the @RequestMapping
, did not have an effect.
I think this only has an effect using @ResponseBody
? Did the following test:
@ResponseBody
@RequestMapping(value = "/htmltest2", method = RequestMethod.GET, produces = "text/html")
public String test2(HttpServletRequest request, HttpServletResponse response) {
StringBuilder str = new StringBuilder();
str.append("<html><head></head><body>"); //$NON-NLS-1$
str.append("this is a HTML test");
str.append("</body></html>"); //$NON-NLS-1$
return str.toString();
}
This displays HTML and if I switch to produces = "text/plain"
returns text.
So the question is how do I get controllers to produce HTML where the writer is being used?
I found out that I can set the content type on the response response.setContentType("text/html")
, but would prefer not having to do that for all my controllers.
Especially since it worked in the previous spring version, could it be a configuration problem?
@RequestMapping(value = "/htmltest3", method = RequestMethod.GET)
public void test3(Writer writer, HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
writer.append("<html><head></head><body>"); //$NON-NLS-1$
writer.append("this is a HTML test");
writer.append("</body></html>"); //$NON-NLS-1$
writer.flush();
}
Edit: I just found out that only Chrome (44.0.2403.155 m) does not display HTML, Firefox (40.0.2) and InternetExplorer (11.0.9600.17959) work as expected.
Still it may also not work in older browser versions, but maybe this gives a hint?
Upvotes: 4
Views: 1944
Reputation: 8090
So the problem was the headers which have been introduced in Spring Security 3.2.0:
http://spring.io/blog/2013/08/23/spring-security-3-2-0-rc1-highlights-security-headers/
If I add the following lines to my application context, the controllers display HTML again.
<http>
...
<headers disabled="true"/>
</http>
Well but this is a bad idea since it will disable all the additional seurity features (X-XSS-Protection, X-Frame-Options, HSTS).
So one option could be to disable the defaults and configure own headers:
<http>
...
<headers defaults-disabled="true">
<frame-options policy="SAMEORIGIN" />
</headers>
</http>
After narrowing it down this solves my issue:
<http>
...
<headers>
<content-type-options disabled="true" />
</headers>
</http>
There are some security aspects that need to be considered, but for me this works for now. http://docs.spring.io/autorepo/docs/spring-security/4.0.x/reference/html/headers.html#headers-content-type-options
Upvotes: 1
Reputation: 812
Try:
@ResponseBody
@RequestMapping(value = "/htmltest3", method = RequestMethod.GET)
public void test3(Writer writer, HttpServletRequest request, HttpServletResponse response) throws IOException {
String html = "<html><head></head><body>this is a HTML test</body></html>";
return html;
}
Upvotes: 0