2017-01-17 37 views
5

Próbuję utworzyć żądanie krzyżowe za pomocą Spring's RestTemplate. Komunikacja odbywa się między dwoma aplikacjami Spring-boot, obie działające na serwerze localhost, ale innym porcie. Co mogę zrobić, to:RestTemplate nie przekazuje nagłówka Origin

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

Połączenie zostanie zrealizowane, „Autoryzacja” nagłówek przechodzi po prostu w porządku, ale bez względu na to, co staram, nie ma „Origin” nagłówek na stronie odbiorczej. Po utworzeniu żądania simillar za pomocą innego narzędzia (SoapUI, wtyczki RestClient Chrome itp.) Nagłówek jest przekazywany tak, jak go dostarczam.

Aby wydrukować wszystkie nagłówki po stronie odbiorczej Używam wdrażania javax.servlet.Filter z:

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

Dlaczego nagłówek pochodzenie nie przeszedł podczas korzystania RestTemplate?

Odpowiedz

7

Miałem ten sam problem, który spędziłem wiek, aby naprawić.

Przyczyną jest to linia z dokumentacji RestTemplate

Uwaga: domyślnie RestTemplate opiera się na standardowym wyposażeniu JDK do nawiązywania połączeń HTTP.

Jeśli zaznaczysz kod źródłowy HttpUrlConnection klasy w Javie, znajdziesz poniżej bloku kodu, a nagłówek Origin jest jednym z ograniczonych nagłówków, które zabraniają zmiany:

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

Jest łatwy rozwiązać tego problemu, po prostu ustawić argumentu JVM

-Dsun.net.http.allowRestrictedHeaders=true 

lub dodać linię w kodzie

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

które tłumią ograniczenie.

0

Miał ten sam problem. Dowiedziałem się, że klient HTTP Apache nie ma tego problemu i wysyła żądanie z "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)