2015-01-08 64 views
0

除了標準的即用型cookie /表單身份驗證外,我還需要支持基於HTTPS的SignalR基本身份驗證。 SignalR運行在混合MVC/WebApi站點的上下文中。基本身份驗證重定向到登錄頁面,而不是返回身份驗證質詢

把拼湊如何實現在此之後,我用ThinkTecture.IdentityModel.Owin.BasicAuthentication庫這個服務器上,像這樣:

app.Map("/basicauth", map => 
{ 
    map.UseBasicAuthentication("realm", ValidateUser); 
    map.MapSignalR<AuthenticatedEchoConnection>("/echo"); 
    map.MapSignalR(); 
}); 

,而不是返回一個挑戰,但我總是得到一個HTTP 302響應重定向到MVC網站的登錄頁面。爲了更好地進行調試,我很快推出了自己的簡單OWIN中間件進行基本認證,並得到了相同的結果。使用如下簡單映射進一步測試:

app.Map("/test", map => 
    { 
     map.Use((context, next) => 
      { 
       // context.Response.StatusCode = 401; 
       context.Response.Write("Hello World!"); 
       return Task.FromResult(0); 
      }); 

顯示簡單的「Hello World」響應正常返回。但是,當我將響應代碼設置爲401的行註釋掉時,我會再次重定向到「登錄」頁面。我不明白這種行爲...爲什麼我的MVC網站在這裏涉及,而不是401響應返回?我怎樣才能防止這一點?

對於OWIN,除了上面的特殊/basicauth地圖,我只有在定義的啓動方法應該繼續爲所有的cookie身份驗證的調用工作頂級SignalR映射:

app.MapSignalR(); 

閒來無事已被配置由我爲OWIN。

有人可以幫我嗎?

回答

1

好的,我找到了解決此問題的方法。第一部分是從第一個樣本中丟棄map.MapSignalR<AuthenticatedEchoConnection>("/echo"); - 這是沒有必要的,由於某種原因,我沒有發現它阻止了SignalR正常工作。

第二部分,以及實際問題的解決方法是,在客戶端,我還會發送帶有第一個請求的憑證,不要等待挑戰。因此,401永遠不會發生,所以沒有重定向到登錄頁面。這對我來說已經足夠了。

所以解決辦法是,在客戶端,不使用的NetworkCredential這樣的:

connection.Credentials = new NetworkCredential(username, password); 

相反,添加授權頭自己那麼它在第一次請求已經包括:

string creds = string.format("{0}:{1}", username, password); 
string encodedCreds = Convert.ToBase64String(Encoding.Utf8.GetBytes(creds)); 
connection.Headers.Add("Authorization", "Basic " + encodedCreds); 

此外,我發現,與OWIN一樣,這個問題似乎是一個更通用的問題,不僅與SignalR或甚至基本身份驗證一起使用時有關:

http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

因此,通過對基本認證模塊進行一些修改,也應該可以防止此重定向。我可能會研究這一點,並會在完成後更新這篇文章。