7

Tüm Api'ye bir AuthorizationFilterAttribute kullanarak uygulanan Basic Auth ile korunan bir WebApi sahibim. Ayrıca bazı Api Kontrol Cihazlarımda oturan SignalR Hub'larım var.ajaxSetup'ı kullanma Temel Auth için Gönderme Sonucu için sinyal kesiliyor Sinyal bağlantısı

Bunun yanı sıra WebApi'yi kullanan bir web sayfam var. web sayfası çoğunlukla benim güvenli WebAPI çağrı yapmak amacıyla bu yüzden, aşağıdaki jquery

Bu benim Api Kontrolörleri ile iletişim fakat kırmıştır yukarıdaki kod ekleyerek için çalışır
$.ajaxSetup({ 
    beforeSend: function (jqXHR, settings) { 
     jqXHR.setRequestHeader('Authorization', 'Basic ' + Token); 
     return true; 
    } 
}); 

ekledik, omurga içerisine yazılır özellikle benim SignalR Hub bağlantı,:

XMLHttpRequest cannot load http://localhost:50000/signalr/negotiate?_=1366795855194. 
Request header field Authorization is not allowed by Access-Control-Allow-Headers. 

jqXHR.setRequestHeader() hattını Çıkarma benim SignalR Hub bağlantısı geri yükler ama Api aramaları kırar.

bu etrafında bir temizleyici yolu var mı ... Ben hacky bir şeyler yapabileceğini, yukarıda Verilen ve yapılmakta olan istek değil/signalr ise sadece istek başlığını ayarlamak ama bu sadece kirli hisseder?

Sadece aptalca bir şey yapıyorum? Bunun için başka biri var mı?

cevap

7

Ne Daha önce söz etmedi benim WebAPI için gelen herhangi bir talebe doğru Başlıkları geri gönderen bir DelegatingHandler olması. Bu, WebApi'mdeki tüm istekler için mükemmel bir şekilde çalışıyor, ancak bunun yanlış bir şekilde SinyalR isteklerine de uygulanacağını farz ettim. Onlar örneğin (see here)

için tüm WebSockets uygulamalarının bir gereklilik değiliz - SignalR birkaç farklı taşıma yöntemlerine dayanıyor gibi

, ben ilk etapta Yetkilendirme başlıklarına erişebilir varsaymak makul görünmüyor

Şu anki çözümüm, SignalR'ın HubPipeline'ı (detailed here) kullanmak oldu.


Geçme Sorgu dizesi

$.connection.hub.qs = "auth=" + MyBase64EncodedAuthString; 

: Bu kullanarak, ben bir sorgu dizesinde Basic Auth kimlik geçmek ve SignalR istekleri için yetkilendirme işlemek için ayrı bir modül yazabilirsiniz inanıyoruz t kaydedilmesi Filtre

public class SignalrBasicAuthFilterAttribute: Attribute, IAuthorizeHubConnection { 

    public bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) { 
     var authString = request.QueryString["auth"]; 

     // ... parse, authorize, etc ... 

     return true; 
    } 

} 

o Ayrıca

var globalAuthorizer = new SignalrBasicAuthFilterAttribute(); 
GlobalHost.HubPipeline.AddModule(new AuthorizeModule(globalAuthorizer, globalAuthorizer)); 

Filtre ...

$.ajaxSetup({ 
    beforeSend: function (jqXHR, settings) { 
     if (settings.url.indexOf("/signalr") == -1) 
      jqXHR.setRequestHeader('Authorization', 'Basic ' + Token); 
     return true; 
    } 
}); 
: yukarıda belirtilen nedenlerle, SignalR istekleri ile bir Yetkilendirme başlığını göndermek için güvenilir bir varsayım değil çünkü, hala benim $ .ajaxSetup filtreleme ediyorum sadece olmayan SignalR isteklerini etkilediği

Not

Bunu yaparken SignalR isteklerini yetkilendirmek için tüm sorumluluğu üstlenmek üzere SignalrBasicAuthFilterAttribute sınıfından ayrılıyorum.


Ek Okuma:

+0

AuthorizeHubConnection ben eksikti parça oldu! Teşekkürler!!! – kzfabi

1

Sorunun gerçek çözümü, "Yetkilendirmenin" "pazarlık" talebi için sinyal R yanıtından döndürülen İzin Verilen Başlıklar (Erişim Denetimi - İzin Vericiler) bölümünün parçası olduğundan emin olmak olduğunu düşünüyorum.

Başlığı bu olasılık gibi web.config dosyanıza kaydedebilirsiniz.

<httpProtocol> 
    <customHeaders> 
    <add name="Access-Control-Allow-Headers" value="Authorization" /> 
    </customHeaders> 
</httpProtocol>