2017-01-17 12 views
5

Tôi đang cố thực hiện yêu cầu có nguồn gốc chéo bằng cách sử dụng RestTemplate của Spring. Giao tiếp được thực hiện giữa hai ứng dụng web khởi động Spring, cả hai đều chạy trên localhost nhưng khác cổng. Những gì tôi làm là:RestTemplate không vượt qua Tiêu đề gốc

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

Cuộc gọi được thực hiện, tiêu đề "Ủy quyền" được chuyển tốt, nhưng không có vấn đề gì tôi cố gắng, không có tiêu đề "Gốc" ở bên nhận. Khi tôi tạo một yêu cầu simillar bằng cách sử dụng một số công cụ khác (SoapUI, plugin RestClient Chrome, v.v.), tiêu đề được truyền như tôi cung cấp.

Để in tất cả các tiêu đề ở phía bên nhận Tôi đang sử dụng một thực hiện javax.servlet.Filter với:

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

Tại sao tiêu đề nguồn gốc không được thông qua khi sử dụng RestTemplate?

Trả lời

7

Đã có cùng một vấn đề mà tôi đã dành một thế kỷ để khắc phục.

Nguyên nhân sâu xa là dòng này từ tài liệu RestTemplate

Lưu ý: theo mặc định RestTemplate dựa vào các cơ sở JDK tiêu chuẩn để thiết lập kết nối HTTP.

Nếu bạn kiểm tra mã nguồn của HttpUrlConnection lớp trong Java, bạn sẽ tìm thấy bên dưới khối mã và tiêu đề Origin là một trong những tiêu đề hạn chế để cấm thay đổi:

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

Có một dễ dàng sửa chữa cho vấn đề này, chỉ để thiết lập một cuộc tranh luận JVM

-Dsun.net.http.allowRestrictedHeaders=true 

hoặc thêm một dòng trong mã của bạn

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

ngăn chặn hạn chế.

0

Đã xảy ra sự cố tương tự. Tôi đã phát hiện ra rằng ứng dụng khách apache http không có vấn đề này và gửi yêu cầu với 'Xuất xứ': 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) 
Các vấn đề liên quan