Issue
I have built a simple Spring Boot Rest Controller that does nothing but return a custom Java Object - Data. Everything compiles and runs normally. When I fetch from the endpoint, I get the data as expected.
However, when looking under the hood using "Inspect Element" on Firefox, I see an error due to Content Security Policy (CSP). The Content-Security-Policy error says the following:
"Content Security Policy: The page’s settings blocked the loading of a resource at http://localhost:8081/favicon.ico (“default-src”)."
I tried a few solutions, all to no avail.
- I tried to disable the icon through the application.properties, but that didn't seem to have any effect.
- I created an icon called "favicon.ico" and placed it in the proper directories. Annoyingly enough, this page still threw an error, meanwhile all my other pages started to get icons.
- I tried many permutations of headers including setting the Content-Security-Policy header to be default src self. None worked, though this is likely the source of the problem, as there seem to be a lot of moving parts that I don't fully grasp.
- I tried to create a GET endpoint for "/favicon.ico", but that didn't seem to accomplish anything at all.
- I had added in the icon to my directory at this point, so when I attempted to hit the endpoint, it just sent me an image of my icon, with the icon also showing in the tab at the top of my browser, and no error in the logs.
- I tried to mess around with the WebSecurityConfigurerAdapter, but that quickly got out of hand, and frankly, a lot of it didn't make sense.
Here are my files.
Application properties = application.properties
spring.mvc.favicon.enabled=false
Main file - DemoApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.getProperties().put( "server.port", 8081);
SpringApplication.run(DemoApplication.class, args);
}
}
Rest Controller = DataController
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DataController
{
@GetMapping("/data")
public Data data()
{
return new Data(123, "abc");
}
}
Returning Type = Data
public class Data
{
private final long id;
private final String data;
public Data(long id, String data) { this.data = data; }
public long getId() { return this.id; }
public String getData() { return this.data; }
}
Solution
After some debugging, I found that the issue seems to be Firefox specific, and only for endpoints that return a JSON object.
For example, if I built an endpoint that just returned a String, Firefox would return the String and the icon would be in the tab on the top.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DataController
{
@GetMapping("/data")
public Data data()
{
return new Data(123, "abc");
}
@GetMapping("/abc123")
public String abc123()
{
return "abc123";
}
}
I ran more examples than this, but this demonstrates how String as a response type throws no error on Firefox, but JSON as a response type throws an error.
When attempting both of these endpoints on other browsers, it seems like there are no errors for either JSON or String.
And then I realized - unlike the other browsers, Firefox has a built-in JSON Viewer. Meaning, if the data being received for an entire page is purely JSON, then Firefox will render the page entirely differently. Rather than just spitting out the plain JSON String onto the page, Firefox will organize the JSON using some fancy UI for easier reading/parsing.
So, as a final test, I turned off the JSON Viewer, then reloaded the page -- all worked as expected.
I would also add - I don't really think this is a bug on Firefox's part -- @granty pointed out that Mozilla themselves are looking into this. This only happens for endpoints where the entirety of the response is JSON.
If you look at it big picture, endpoints that return purely JSON are really just meant to be streams of data, and not consumed by the average user. So do you really need an icon to be included? lol, probably not.
Answered By - davidalayachew
Answer Checked By - David Marino (JavaFixing Volunteer)