2012-11-13 48 views
3

在我正在開發的應用程序中,我們正在使用ASP.Net表單身份驗證來授予用戶進一步訪問該網站的權限。本網站面向移動用戶,因此我們試圖儘可能地與服務器脫鉤,並利用KnockoutJS進行Web服務調用並加載數據,以便用戶查看它。安全地將用戶標識從ASP.Net傳遞到Javascript

現在,web服務(使用GET方法的REST服務)需要用戶名才能加載特定於該用戶的數據。我在服務器端(ASP.net)擁有這些信息,我可以輕鬆訪問User.Identity.Name或直接訪問表單身份驗證cookie並獲取信息。

我的問題是,我需要從服務器獲取用戶名到客戶端,以便可以進行服務調用。我已經考慮過這樣做,但迄今爲止已經空白。目前,我將用戶名作爲url參數傳遞並使用JavaScript解析出來,並檢查Page_Load方法以驗證url中的用戶名與登錄用戶的匹配。

我需要一種方法來保證從ASP.Net傳遞用戶名,該用戶名已經通過表單向客戶端JavaScript進行了身份驗證,因此我可以進行REST Web服務調用。

編輯:因此,谷歌搜索和我的團隊負責人會議上,我認爲我們將使用類似於此示例一個OAuth實施後:

http://www.c-sharpcorner.com/UploadFile/surya_bg2000/secure-wcf-restful-service-using-oauth/

還爲別的尋找同樣的答案,我發現這個問題非常有幫助理解的OAuth:

What's the point of a timestamp in OAuth if a Nonce can only be used one time?

如果一切都實現編輯正確,它會更安全(完全安全,安全,或更不安全?),而不是通過ASP標籤生成的簽名,如下所述?

編輯2:經過一些更多的審查和一些更多的搜索,我們終於決定了一個框架和做這項工作的方法。事實證明OAuth是不一定的答案在這裏,這個問題:

But Seriously.... Example of ASP.NET WebAPI implementation including OAuth

是一個很大的幫助,以及在搞清楚如何使這項工作。我們最終要做的就是生成簽名並放入JavaScript中,然後像這樣打電話。每次用戶加載頁面時,簽名都會變得時間敏感並重新生成,所以非常類似於OAuth,但我們並未實現完整的規範。

TL:DR最終的解決辦法是生成一個散列簽名,並把它放在網頁上通過ASP服務器標籤<%aspvar_here%>,並用它來驗證服務調用

+0

該服務位於與用戶登錄的站點相同的服務器/域上嗎? – nerdybeardo

+0

是的,他們都將駐留在相同的域 – Pseudonym

回答

2

最簡單的方法是使您的頁面裏的這個javascript:

<script type="text/javascript"> 
    window.UserID = '<%=HttpUtility.JavaScriptStringEncode(this.User.Identity.Name)%>'; 
</script> 

現在你可以在你的JS中引用它。

但是,更重要的是,如果此用戶標識不僅僅用作默認參數,而是用於對用戶進行身份驗證,則這是一個安全漏洞。通常,REST服務也應該能夠查看User.Identity.Name而不是將其作爲參數接收。

+0

如何在服務器上進行加密,如上所述將它傳遞給JS,然後在Web服務中解密?你能否詳細說明做這種事情的安全性? – Pseudonym

+0

是的,你可以通過加密來做類似的事情。但是,您應該確保加密數據的安全性不會被重用 - 例如,加密時間戳,並且在解密時檢查時間戳是否在最後X分鐘內。否則,有人可能會竊取加密的用戶名一次,然後繼續使用它僞造身份驗證。 –

+0

感謝您的幫助,這是我們將最終使用的解決方案 – Pseudonym

1

正常情況下,用戶名是由客戶端提供的。然後在服務器端進行驗證(使用任何必要的驗證,例如密碼)。

如果它已在服務器端進行驗證(對於您的情況,這必須來自WCF Web服務,因爲ASMX不能很好地處理REST),那麼您可以確定它是正確的 - 加上您已經擁有在客戶端的用戶名。

編輯: 正如Knaģis指出的那樣,您可以使用ASPX標籤獲取它,假定頁面是ASPX頁面而不是HTML。

0

如果你只是想在客戶端有用戶名,其他答案解釋如何做到這一點。
但正如你所說,這是一個安全風險。有人可以修改客戶端上的數據並冒充其他用戶。

這樣做的正確方法:

  1. 在用戶成功登錄,一個Guid發出它唯一標識該用戶。
  2. Guid是保存在客戶端並傳遞到服務器而不是用戶名的令牌。
  3. 所有web服務都收到Guid而不是用戶名。
  4. 服務器有一個將Guid轉換爲原始用戶名的字典。

另一種選擇可以是encrypt用戶名和加密值傳遞給web服務。 Web服務將需要解密該值以獲取用戶名。

+0

絕對是一個好建議,我的反問題是:有沒有辦法做到這一點,而無需修改現有的Web服務? – Pseudonym

+0

那麼,如果你的web服務只接收**一個用戶名,並只返回信息 - 那麼你可能沒有選擇,因爲這裏存在嚴重的安全/設計缺陷。另一方面,無論您選擇使用Guid還是使用加密的用戶名 - 它仍然是一個字符串值,因此它不會中斷WSDL,您只需更改Web服務的內部邏輯 – Blachshma

相關問題