2017-01-17 4 views
5

Ich versuche, eine Cross-Origin-Anfrage mit Spring's RestTemplate zu machen. Die Kommunikation erfolgt zwischen zwei Spring-Boot-Webapps, die beide auf localhost, aber auf einem anderen Port ausgeführt werden. Was ich tue, ist:RestTemplate nicht übergeben Origin-Header

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); 

Der Aufruf ausgeführt wird, wird die „Berechtigung“ Header übergeben ganz gut, aber egal was ich versuche, es gibt keinen „Origin“ Header auf der Empfangsseite ist. Wenn ich eine Simillar-Anfrage mit einem anderen Tool (SoapUI, RestClient Chrome-Plugin usw.) erstelle, wird die Kopfzeile genauso übergeben, wie ich sie angegeben habe.

Um alle Header auf der Empfangsseite druckt ich mit einer Implementierung von javax.servlet.Filter bin mit:

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)); 
    } 
} 

Warum ist der Ursprung Header nicht besteht bei der Verwendung von RestTemplate?

Antwort

7

Hatte das gleiche Problem, das ich ein Jahrhundert zu beheben hatte.

Die Ursache ist diese Linie von der RestTemplate Dokumentation

Hinweis: standardmäßig die RestTemplate auf Standard-JDK Einrichtungen setzen HTTP-Verbindungen herzustellen.

Wenn Sie Quellcode HttpUrlConnection Klasse in Java überprüfen, werden Sie unter Code-Block zu finden, und Kopf Origin ist eine der eingeschränkten Header, die Änderungen verbieten:

/* 
* 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" 
}; 

Es gibt eine leicht fix für dieses Problem, nur ein JVM-Argument zu setzen

-Dsun.net.http.allowRestrictedHeaders=true 

oder eine Zeile in Ihrem Code hinzufügen

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

die die Einschränkung unterdrücken.

0

Hatte das gleiche Problem. Ich habe herausgefunden, dass Apache HTTP-Client dieses Problem nicht haben und sendet Anfrage mit 'Herkunft': 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)