RestTemplate Does Not Pass Header Header

I am trying to make a cross-start query using Spring RestTemplate. Communication is performed between two Spring-boot webapps, both running on localhost, and with another port. What am I doing:

HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setOrigin("http://localhost:8083"); httpHeaders.add("Authorization", token); HttpEntity<Void> httpEntity = new HttpEntity<>(httpHeaders); ParameterizedTypeReference<List<MyObj>> beanType = new ParameterizedTypeReference<List<MyObj>>() {}; ResponseEntity<List<MyObj>> list = restTemplate.exchange(serviceURL, HttpMethod.GET, httpEntity, beanType); 

A call is made, the "Authorization" header is just fine, but no matter what I try, there is no "Origin" header on the receiving side. When I create a simillar request using some other tool (SoapUI, RestClient Chrome plugin, etc.), the Header is transmitted in the same way as I provide it.

To print all headers on the receiving side, I use the javax.servlet.Filter implementation with:

 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); log.info(headerName + ": " + request.getHeader(headerName)); } } 

Why is the source header not transmitted when using RestTemplate?

+5
source share
2 answers

There was the same problem that I spent a century to fix.

The root cause is this line from the RestTemplate documentation

Note. By default, RestTemplate uses the standard JDK capabilities to establish HTTP connections.

If you have checked the source code for the HttpUrlConnection class in Java, you will find the code block below, and the Origin header is one of the restricted headers that prohibit changes:

 /* * Restrict setting of request headers through the public api * consistent with JavaScript XMLHttpRequest2 with a few * exceptions. Disallowed headers are silently ignored for * backwards compatibility reasons rather than throwing a * SecurityException. For example, some applets set the * Host header since old JREs did not implement HTTP 1.1. * Additionally, any header starting with Sec- is * disallowed. * * The following headers are allowed for historical reasons: * * Accept-Charset, Accept-Encoding, Cookie, Cookie2, Date, * Referer, TE, User-Agent, headers beginning with Proxy-. * * The following headers are allowed in a limited form: * * Connection: close * * See http://www.w3.org/TR/XMLHttpRequest2. */ private static final boolean allowRestrictedHeaders; private static final Set<String> restrictedHeaderSet; private static final String[] restrictedHeaders = { /* Restricted by XMLHttpRequest2 */ //"Accept-Charset", //"Accept-Encoding", "Access-Control-Request-Headers", "Access-Control-Request-Method", "Connection", /* close is allowed */ "Content-Length", //"Cookie", //"Cookie2", "Content-Transfer-Encoding", //"Date", //"Expect", "Host", "Keep-Alive", "Origin", // "Referer", // "TE", "Trailer", "Transfer-Encoding", "Upgrade", //"User-Agent", "Via" }; 

There is an easy solution to this problem, just to set the JVM argument

 -Dsun.net.http.allowRestrictedHeaders=true 

or add a line to your code

 System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); 

which suppress the restriction.

+7
source

There was the same problem. I found out that the apache http client does not have this problem and sends a request using "Origin": http://hc.apache.org/

 HttpOptions httpOptions = new HttpOptions(url) httpOptions.setHeader("Origin", "test") httpOptions.setHeader("Content-Type", "application/json") BasicHttpClientConnectionManager manager = new BasicHttpClientConnectionManager() HttpClient client = new MinimalHttpClient(manager) client.execute(httpOptions) 
0
source

Source: https://habr.com/ru/post/1262934/


All Articles