天天看點

使用ASP.NET Web Api建構基于REST風格的服務實戰系列教程【八】——Web Api的安全性

前言

這一篇文章我們主要來探讨一下Web Api的安全性,到目前為止所有的請求都是走的Http協定(http://),是以用戶端與伺服器之間的通信是沒有加密的。在本篇中,我們将在“StudentController”中添加身份驗證功能——通過驗證使用者名與密碼來判斷是否是合法使用者。衆所周知,對于機密資訊的傳遞,我們應該使用安全的Http協定(https://)來傳輸

在Web Api中強制使用Https

我們可以在IIS級别配置整個Web Api來強制使用Https,但是在某些情況下你可能隻需要對某一個action強制使用Https,而其他的方法仍使用http。

為了實作這一點,我們将使用Web Api中的filters——filter(過濾器)的主要作用就是可以在我們執行方法之前執行一段代碼。沒接觸過得可以通過下圖簡單了解下,大神跳過:

使用ASP.NET Web Api建構基于REST風格的服務實戰系列教程【八】——Web Api的安全性

我們新建立的filter将用來檢測是否是安全的,如果不是安全的,filter将終止請求并傳回相應:請求必須是https。

具體做法:建立一個filter繼承自AuthorizationFilterAttribute,重寫OnAuthorization來實作我們的需求。

在網站根目錄下建立“Filters”檔案夾,建立一個類“ForceHttpsAttribute”繼承自“System.Web.Http.Filters.AuthorizationFilterAttribute”,下面上代碼:

在上面代碼中,我們通過actionContext參數拿到request和response對象,我們判斷用戶端的請求:如果不是https,那麼直接響應用戶端應該使用https。

在這裡,我們需要區分請求是Get還是其他(Post,Delete,Put),因為對于使用了Http的Get請求來通路資源,我們将使用https建立一個連接配接并添加在響應Header的Location中。這樣做了之後用戶端就會自動使用https來發送Get請求了。

對于非Get請求,直接傳回404,并通知用戶端必須使用https來請求

如果我們打算在整個項目中使用,那麼在“WebAPIConfig”類中做如下設定:

如果我們相對具體的Controller或Action設定時,可以做如下設定:

使用Basic Authentication驗證使用者

到目前為止,我們提供的所有Api都是公開的,任何人都能通路。但在真是場景中卻是不可取的,對于某些資料,隻有通過認證的使用者才能通路,我們這裡有兩個地方恰好說明這一點:

對于上面的場景,我們使用Basic Authentication來進行身份驗證,主要思路是使用filter從請求header部分擷取身份資訊,校驗驗證類型是否為“basic”,然後校驗内容,正确就放行,否則傳回401 (Unauthorized)狀态碼。

在上代碼前,解釋一下下basic authentication:

什麼是basic authentication?

它意味着在正式處理Http請求之前對請求者身份的校驗,這可以防止伺服器受到DoS攻擊(Denial of service attacks)。原理是:用戶端在發送Http請求的時候在Header部分提供一個基于Base64編碼的使用者名和密碼,形式為“username:password”,消息接收者(伺服器)進行驗證,通過後繼續處理請求。

由于使用者名和密碼僅适用base64編碼,是以為了保證安全性,basic authentication通常是基于SSL連接配接(https)

為了在我們的api中使用,建立一個類“LearningAuthorizeAttribute”繼承自System.Web.Http.Filters.AuthorizationFilterAttribute

我們重寫了“OnAuthorization”,實作如下功能:

1.從請求Header中擷取校驗資料

2.判斷驗證資訊類型為“basic”并包含base64編碼

3.将base64編碼轉化為string,并提取使用者名和密碼

4.校驗提供的驗證資訊是否與通路的資源資訊相同(學生的詳細資訊隻能由他自己通路)

5.去資料庫校驗使用者名及密碼

6.如果校驗通過,則設定Thread的CurrentPrincipal,使本次接下來的請求都是通過校驗的。

7.校驗沒通過,傳回401(Unauthorized)并添加一個WWW-Authenticate響應頭,根據這個請求,用戶端可以添加相應的驗證資訊

在代碼中實作起來就很簡單了,上兩個Attribute就完了:

測試成果

使用測試工具發送如下請求:

使用ASP.NET Web Api建構基于REST風格的服務實戰系列教程【八】——Web Api的安全性

由于沒有提供身份驗證,于是得到如下響應:

使用ASP.NET Web Api建構基于REST風格的服務實戰系列教程【八】——Web Api的安全性

取消:

使用ASP.NET Web Api建構基于REST風格的服務實戰系列教程【八】——Web Api的安全性

去資料庫找到對應的使用者名和密碼輸入,得到如下結果:

使用ASP.NET Web Api建構基于REST風格的服務實戰系列教程【八】——Web Api的安全性

總結

因為 Base Authentication 的安全性較差,但對于無 Cookie 的 Web Api 來說,應用上非常的簡單和友善。

Base Authentication 最大的缺點是憑據會被浏覽器緩存——直到你關閉浏覽器為止。如果你已經對某個URI獲得了授權,浏覽器就會在授權頭發送相應的憑據,這使其更容易受到跨站點請求僞造(CSRF)攻擊

Base Authentication 通常需要使用HTTPS方式進行加密處理。

繼續閱讀