本系列博客鏈接:webapi框架搭建系列博客
前言
webapi接口是開放給外部使用的,包括接口的地址,傳參的規范,還有返回結果的說明。正因為接口的開放性,使得接口的安全很重要。試想一下,用抓包工具(如fiddler),甚至瀏覽器獲取到接口的規范后(甚至可以猜到接口的其它規范),如果接口沒有做”安全“這一道防火牆,任何人都可以調用接口來獲取及提交數據,這真是太可怕了。17年我負責一個氣象類項目的開發,其中有些功能是我們無法完成但甲方要求必須有的功能,並給我們展示了實現該功能的一個產品。后面通過對此產品的fiddler抓包分析,了解了該產品是通過接口向apps端提供數據,而所有的接口竟然都沒有加密,於是這個項目基於此功能的實現基本上都是通過調用該產品的接口實現,對我來說是省去了很大的開發成本,但對於那個產品的公司來說是損失了有價值的數據。
對於webapi方面的安全,可寫的東西太多了,且asp.net webapi及asp.net core webapi在安全方面也有些差異。我只對”webapi框架搭建“項目里用到的技術做一些說明。后續的博客會對每一個技術的實現做詳細的描述。
JWT技術
考慮http的無狀態性,且又必須讓服務器能區分每次的http請求是”誰“發出的,但又不想在http請求里攜帶很多信息(盡量每次的請求包比較小),我采用token技術。即將用戶的基本信息,如用戶id,用戶的角色等進行加密,並附在http請求頭里。服務器端只要對token進行解密后就能知道是誰發起的請求。之前我是自己生成token,規范token的加密/解密規則和token里存儲的信息(如一個user實體的信息),后面發現這一技術已經有一個規則,那就是jwt。jwt參考如下網站:https://jwt.io/。
webapi安全
微軟對webapi的安全拆分為authentication和authorization,authentication的職責是解決”用戶是誰“的問題,而authorization的職責是解決”是否有權限“的問題。通過jwt技術,可以解決”用戶是誰“的問題,通過”基於角色的權限控制“可以解決”是否有權限“的問題。后續的博客會詳細說明。
安全的”切入點“
我們肯定不想在每個接口里都去寫一段”安全代碼“,而是用aop的思想,在整個http請求的生命周期中做為一個切面插入到生命周期的某個點上。所以先讓我們了解下webapi的生命周期。如下圖。
對於在哪一個環節做為安全機制的切入點,微軟的一篇文章里說的很好:https://msdn.microsoft.com/en-us/magazine/dn781361.aspx。我總結如下
Http Module:如果webapi的host為iis,所有的請求會通過httpmodule,可以創建自己的httpmodule並在該類里寫安全機制的代碼。缺點是和iis耦合了。而我們現在的教程里用的是owin技術。所以先排除。
owin middleware:如果webapi的host為owin,可創建自己的安全middleware組件,並注冊到owin管道里。只要webapi組件注冊在該組件之后就行。且這種方式有一個優點(也能說是它的缺點),不僅可以用於webapi框架,也可以用於其它框架的安全,只要該框架可以注冊在owin管道里就行。
http Message handler:從上圖可以看出,請求從httpserver出來后的第一個通道就是http message handler。微軟的這篇文章里也提到怎么用這種方式去實現:https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api。
action filter:可以但不建議的方式,良好的安全通道是http請求先經過authentication再經過authorization(即要先知道這個人“是誰”才能知道他有什么“權限”)。但從圖可以看出action filter是在authorization filter之后,雖然可以不用authorization filter,只用action filter,但畢竟有點怪異。
authentication filter和authorization filter:推薦的方式。