2013-07-05 24 views
13

Tôi gặp sự cố CORS khi tự lưu trữ SignalR với OWIN, điều này chỉ xảy ra khi tôi cố bật xác thực.Các kết nối miền chéo SignalR với tự lưu trữ và xác thực

Các lỗi tôi nhận được trong trình duyệt web của tôi là:

XMLHttpRequest không thể tải http://.../signalr/negotiate?[snip] xứ ... không được phép bởi Access-Control-Allow-Origin

này chỉ xảy ra nếu tôi cho phép xác thực trong máy chủ tự lưu trữ của tôi sử dụng phương pháp này trong this answer:

public void Configuration(IAppBuilder app) 
{ 
    var listener = (HttpListener)app.Properties[typeof(HttpListener).FullName]; 
    listener.AuthenticationSchemes = AuthenticationSchemes.Ntlm; 

    app.MapHubs(new HubConfiguration { EnableCrossDomain = true }); 
} 

Nếu tôi nhận xét ra 01.dòng rồi CORS hoạt động (và tôi đã kiểm tra mọi thứ trong these instructions). Tôi nhận được cùng một vấn đề nếu tôi sử dụng các chương trình xác thực khác hơn NTLM.

Sử dụng Fiddler để kiểm tra những gì đang xảy ra, mà không xác thực cho phép tôi nhìn thấy các tiêu đề CORS cần thiết khi trở về từ máy chủ:

Access-Control-Allow-Credentials: true
Access-Control- Allow-Origin: [máy chủ của tôi]

Tuy nhiên, khi tôi bật xác thực, tôi nhận được phản hồi 401 thiếu các tiêu đề này. Tất cả các yêu cầu có tiêu đề Origin cần thiết.

Đã kiểm tra SignalR source code có vẻ như các tiêu đề đang được đặt, nhưng có lẽ với xác thực đã bật, HttpListener sẽ gửi phản hồi 401 ban đầu mà không cần nhấn mã này.

Vì vậy, tôi nghĩ câu hỏi của mình là: Làm cách nào để có được HttpListener để bao gồm tiêu đề Access-Control-Allow-Origin trong việc thương lượng các giao thức xác thực?

+0

Bạn có bao giờ nhận được thêm bất kỳ điều này không? Tôi đang gặp vấn đề tương tự ... –

Trả lời

4

Tôi đã nhận được xác thực NTLM để làm việc với tín hiệu tên miền chéo tự lưu trữ trong OWIN bằng cách cho phép yêu cầu preflight truy cập ẩn danh.

Điều bạn cần làm là tạo đại biểu để chọn lược đồ xác thực tìm kiếm tiêu đề yêu cầu preflight và cho phép các tiêu đề này ẩn danh. Tất cả các yêu cầu khác sẽ sử dụng NTLM.

public void Configuration(IAppBuilder appBuilder) 
{ 
    var listener = (HttpListener)appBuilder.Properties[typeof(HttpListener).FullName]; 
    listener.AuthenticationSchemeSelectorDelegate += AuthenticationSchemeSelectorDelegate; 
} 

private AuthenticationSchemes AuthenticationSchemeSelectorDelegate(HttpListenerRequest httpRequest) 
{ 
    if (httpRequest.Headers.Get("Access-Control-Request-Method")!=null) 
     return AuthenticationSchemes.Anonymous; 
    else 
     return AuthenticationSchemes.Ntlm; 
} 
+0

Cảm ơn bạn đã đề xuất!Có vẻ như một con đường đầy hứa hẹn, nhưng trình duyệt của tôi dường như không đưa ra yêu cầu preflight có nghĩa là nó không thực sự hữu ích. Điều này đã truyền cảm hứng cho tôi để tìm ra thuộc tính UnsafeConnectionNtlmAuthentication, gần như đạt được một cái gì đó tương tự (yêu cầu đầu tiên là một tài nguyên không yêu cầu CORS, và các yêu cầu tiếp theo sử dụng lại xác thực từ đầu tiên). Tuy nhiên điều này giảm xuống sau một thời gian vì thông tin đăng nhập được lưu trữ trên mỗi kết nối TCP và khách hàng của tôi rõ ràng sẽ kết thúc bằng việc mở nhiều kết nối. Đó là một hack anyway. Tôi sẽ tiếp tục cố gắng ... –

+0

Cảm ơn bạn rất nhiều! Tôi đã rách tóc ra để cố gắng làm việc này. –

3

Tôi đoán bạn đang sử dụng Chrome, mà rất unhelpfully nói với bạn rằng những tiêu đề đang thiếu và rằng đây là vấn đề, khi thực sự bạn đã có lẽ chỉ quên để thiết lập withCredentials tài sản XMLHttpRequest của bạn để true.

Nếu bạn đang sử dụng jQuery bạn có thể làm điều này cho tất cả các yêu cầu với:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) { 
    options.xhrFields = { withCredentials: true }; 
}); 

Bạn cũng cần phải làm những điều đúng với OPTIONS yêu cầu như trong câu trả lời khác.

Các vấn đề liên quan