天天看點

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

<b>閱讀目錄</b>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label0">一、為什麼需要身份認證</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label1">二、Basic基礎認證的原了解析</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label1_0">1、常見的認證方式</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label1_1">2、Basic基礎認證原理</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label2">三、Basic基礎認證的代碼示例</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label2_0">1、登入過程</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label2_1">2、/Home/Index主界面</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label2_2">3、WebApiCORS驗證部分(重點)</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label3">四、優化</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label3_0">1、解決API的問題</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label3_1">2、解決ajax的問題</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label3_2">3、解決特殊不想使用驗證的方法</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html#_label4">五、總結</a>

<b>正文</b>

前言:最近,讨論到資料庫安全的問題,于是就引出了WebApi服務沒有加任何驗證的問題。也就是說,任何人隻要知道了接口的url,都能夠模拟http請求去通路我們的服務接口,進而去增删改查資料庫,這後果想想都恐怖。經過一番折騰,總算是加上了接口的身份認證,在此記錄下,也給需要做身份認證的園友們提供參考。

WebApi系列文章

<a href="http://www.cnblogs.com/landeanfen/p/5210356.html">C#進階系列——WebApi接口測試工具:WebApiTestClient</a>

<a href="http://www.cnblogs.com/landeanfen/p/5177176.html">C#進階系列——WebApi 跨域問題解決方案:CORS</a>

<a href="http://www.cnblogs.com/landeanfen/p/5287064.html">C#進階系列——WebApi身份認證解決方案:Basic基礎認證</a>

<a href="http://www.cnblogs.com/landeanfen/p/5337072.html">C#進階系列——WebApi接口傳參不再困惑:傳參詳解</a>

<a href="http://www.cnblogs.com/landeanfen/p/5501487.html">C#進階系列——WebApi接口傳回值不困惑:傳回值類型詳解</a>

C#進階系列——WebApi異常處了解決方案

C#進階系列——WebApi區域Area使用小結

在前言裡面,我們說了,如果沒有啟用身份認證,那麼任何匿名使用者隻要知道了我們服務的url,就能随意通路我們的服務接口,進而通路或修改資料庫。

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

可以看到,匿名使用者直接通過url就能通路我們的資料接口,最終會發生什麼事,大家可以随意暢想。

例如我們直接通過url通路,會傳回401

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

 如果是正常流程的請求,帶了票據,就OK了。

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

可以看到,正常流程的請求,會在請求封包的頭裡面增加Authorization這一項,它的值就是我們的Ticket票據資訊。

我們知道,asp.net的認證機制有很多種。對于WebApi也不例外,常見的認證方式有

FORM身份驗證

內建WINDOWS驗證

Basic基礎認證

Digest摘要認證

園子裡很多關于WebApi認證的文章,各種認證方式都會涉及到,但感覺都不夠細。這裡也并不想去研究哪種驗證方式适用哪種使用場景,因為部落客還是覺得“貪多嚼不爛”,也可能是部落客能力所限。對于認證機制,弄懂其中一種,其他的都能融會貫通。此篇就使用Basic基礎認證來詳細講解下整個的過程。

 我們知道,認證的目的在于安全,那麼如何能保證安全呢?常用的手段自然是加密。Basic認證也不例外,主要原理就是加密使用者資訊,生成票據,每次請求的時候将票據帶過來驗證。這樣說可能有點抽象,我們詳細分解每個步驟:

首先登陸的時候驗證使用者名、密碼,如果登陸成功,則将使用者名、密碼按照一定的規則生成加密的票據資訊Ticket,将票據資訊傳回到前端。

如果登陸成功,前端會收到票據資訊,然後跳轉到主界面,并且将票據資訊也帶到主界面的ActionResult裡面(例如跳轉的url可以這樣寫:/Home/Index?Ticket=Ticket)

在主界面的ActionResult裡面通過參數得到票據資訊Ticket,然後将Ticket資訊儲存到ViewBag裡面傳到前端。

在主界面的前端,發送Ajax請求的時候将票據資訊加入到請求的Head裡面,将票據資訊随着請求一起發送到服務端去。

在WebApi服務裡面定義一個類,繼承AuthorizeAttribute類,然後重寫父類的OnAuthorization方法,在OnAuthorization方法裡面取到目前http請求的Head,從Head裡面取到我們前端傳過來的票據資訊。解密票據資訊,從解密的資訊裡面得到使用者名和密碼,然後驗證使用者名和密碼是否正确。如果正确,表示驗證通過,否則傳回未驗證的請求401。

 這個基本的原理。下面就按照這個原理來看看每一步的代碼如何實作。

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

正如上面的原理部分說的,登入如果失敗,則直接傳回;如果成功,則将生成的票據Ticket帶到前端,傳到主界面/Home/Index,下面,我們就來看看主界面Home/Index。

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

這裡需要說明的是,我們在發送ajax請求之前,通過 XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket); 這一句向請求的封包頭裡面增加票據資訊。就是因為這裡加了這一句,是以才有我們下圖中的紅線部分:

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

我們看到,上面的/Home/Index頁面裡面發送了ajax請求去通路服務的 http://localhost:27221/api/Charging/GetAllChargingData 這個接口,那麼我們在WebApi裡面怎麼去驗證這個請求和合法的請求呢?接下來我們重點看看驗證的這個過程。

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

增加了特性标注之後,每次請求這個API裡面的接口之前,程式會先進入到我們override過的 OnAuthorization() 方法裡面,驗證通過之後,才會進到相應的方法裡面去執行,否則傳回401。

 通過上面的幾步,基本就能達到我們想要的身份認證的效果,但是總是感覺不太友善,主要不太友善的點有以下幾個。

每次建立一個API,對應的接口上面都要标注 [RequestAuthorize] 這個一個東西,感覺好麻煩。

每次發送ajax請求,都要在beforeSend事件裡面加 XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket); 這個,感覺也麻煩。

如果有些WebApi服務的某些方法,我們不想使用這個驗證,讓它可以匿名使用者驗證(比如我們的登入方法Login)。該怎麼處理呢。

關于以上兩點,我們優化下

在API裡面加一個公共的父類,在父類上面标注 [RequestAuthorize] 即可。

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

 注意:我們登入的請求是不需要驗證的,因為登入的時候還沒有産生票據,是以登入的API不能夠繼承 BaseApiController 

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

引用這個js後再發送ajax不必在每個請求的beforeSend裡面寫了。

如果我們某些方法不想使用驗證,使得它可以讓匿名使用者通路,我們可以在方法的上面加特性标注 [AllowAnonymous] ,申明該方法運作匿名通路。比如:

C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證一、為什麼需要身份認證二、Basic基礎認證的原了解析三、Basic基礎認證的代碼示例四、優化五、總結

以上結合一個執行個體講解了下Basic認證的實作原理以及簡單使用,本文觀點都是來自部落客自己的了解,如果有不全面的地方,還望園友們斧正。如果本文能夠或多或少幫到你,不妨幫忙推薦,部落客一定繼續努力~~

本文轉自懶得安分部落格園部落格,原文連結:http://www.cnblogs.com/landeanfen/p/5287064.html,如需轉載請自行聯系原作者

繼續閱讀