2017-05-05 37 views
0

我正在使用WCF處理客戶端 - 服務器應用程序。第一個客戶端將是桌面應用程序(WPF),但我計劃添加Xamarin(Android和iOS)和Web客戶端。我希望這是一個互聯網服務,並可能支持大量的客戶端,所以我使用http,一種無狀態服務來節省服務器資源。通過http在WCF上進行表單身份驗證 - 我如何知道哪個用戶正在給我打電話

我在實現驗證邏輯時遇到困難。 我發現,實現窗體身份驗證這個很好的例子:

http://www.dotnetspeak.com/wcf/securing-wcf-with-forms-authentication/

它讓我來處理身份驗證我多麼希望 - 針對數據庫進行比較的用戶名和密碼,創建一個身份驗證Cookie並將其返回。隨後使用此cookie的呼叫將被自動認證。

但問題是,我不知道哪個用戶稱爲服務。如果GetMyData()被稱爲user1的,我要確保他只得到他自己的數據。我顯然不希望讓客戶端根據每個請求分別發送他們的ID,因爲這可能很容易被篡改 - 只需將「user1」切換爲「user2」,然後嘿嘿,你就得到了別人的數據。 我可以通過調用

WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie] 

(我也可以看到有一個叫做「主機」等標題)

的Cookie是從的FormsAuthenticationTicket產生的,其中包含了獲取到服務方法內的身份驗證cookie用戶名和密碼,但它是加密的。我不確定是否有可能在我的代碼中解密cookie,但我非常確定這不是正確的方法。我的方法被稱爲AFTER底層系統認證的調用者,所以大概這個cookie被解密,票據被發現是有效的。那麼爲什麼我無法獲得數據呢?不幸的是,我發現的每篇文章都只涉及到對用戶進行身份驗證的問題,但只要他被授權,任何人都不會關心哪個用戶在使用該服務。

我想我可以存儲cookie服務器端,以及映射到特定用戶,並以這種方式找到用戶。但我希望服務因性能原因儘可能無狀態。此外,這將涉及對300個字符長的字符串進行全文匹配 - 對於每一個請求!哎呀!

在我看來,我需要的是一個非常常見的用例,所以必須有一個正確的方法來做到這一點。我似乎無法找到它。誰能幫我嗎?

回答

0

如果您有窗體身份驗證設置正確,那麼你就可以得到登錄通過Thread.CurrentPrincipal.Identity.Name的用戶名,並將其發送到數據訪問驗證您的服務方法。從用戶名獲取用戶標識並驗證所有權。

Thread.CurrentPrincipal.Identity.Name解密cookie票據並返回登錄用戶名。

+0

我嘗試在服務方法內查看Watch窗口中的值。沒有'線程'可用: 錯誤CS0103:名稱'線程'在當前上下文中不存在 您編寫了「將其發送到您的服務方法」。我不明白。從哪裏發送? – Shaggydog

+0

我通常公開Web api項目而不是WCF到互聯網。在asp.net應用程序中,您可以通過User.Identity.Name或Thread ... Name訪問登錄的身份名稱。在你的情況下,在WCF公開的地方,必須有一種方法來訪問這些值。注意:我討厭將WCF服務直接暴露給互聯網,相反,最好將asp.net web api/mvc公開給互聯網,並讓它與您的WCF通信,但這超出了我所假設的請求範圍。 –

+0

感謝您的澄清。基於你原來的答案,我做了一些更多的搜索,發現我應該有權訪問ServiceSecurityContext.Current.PrimaryIdentity.Name。但是,我的ServiceSecurityContext.Current爲空,這意味着我需要正確配置http綁定。然而,你讓我意識到我面臨着一個關於我的服務架構的更大問題,而我對這個問題的進展知之甚少。我不需要盲目繼續撒尿,我需要做更多的學習。 – Shaggydog

相關問題