Api接口通用安全策略及實現-OSS.Core


  這篇文章一直說寫,遲遲沒有動手,這兩天看到一些應用接口數據被別人爬蟲、短信接口被人高頻率請求攻擊等案列,感覺簡單概述分享一下接口安全驗證還是有必要的。畢竟當下基本都以客戶端應用為主,如果前期疏忽,發布之后的維護升級等將會有很大的麻煩。這里我將主要圍繞以下幾個方面:

1. 基礎的安全策略

2. Restful安全實現方式介紹

3. OSS.Core實現案例

4. OSS.Core接口參數規范

一. 基礎的安全策略

    這里討論只針對應用本身,像Https或者防火牆等第三方支持不在此討論范圍。

      對於一個接口項目來說,安全策略我個人認為主要分兩塊:1. 接口驗證模塊  2. 用戶驗證模塊

  1. 接口驗證模塊

  這個模塊是對整個接口安全層面負責。對於接口安全而言,特別是客戶端接口,是直接暴露在整個互聯網中的,我們首先要保證的就是不會被別人冒名請求我們的接口數據。經常使用的就是簽名驗證,在接口正常的數據傳輸之外,傳遞額外的約定加密簽名信息等,來過濾非授權的接口請求。

  這里可以舉一個去年我遇到的典型案列,當時有個外賣的站點短信發送接口沒有添加任何驗證,接口地址還寫在了頁面上,可想而知后果有多么嚴重,網絡上的很多短信轟炸機用的就是這些接口,這里給一張當時發現時測試的截圖:

  當然簽名校驗只是最基礎的安全校驗,如果再配合IP限流等校驗措施效果更佳!

  2. 用戶授權驗證模塊

  這個模塊主要是對用戶個體負責,上一步主要是在一定程度上過濾一些非自身應用接口請求。但是應用本身出了問題,例如漏洞或者被反編譯等,又或者是人員流動造成的秘鑰泄露,又如何保證接口的真實用戶數據不被輕易篡改。

  對於這個問題,我們可以獨立一個用戶驗證模塊,核心思路就是通過給每個登錄用戶頒發token(可以通過用戶編號加密,或者編號+時間戳),對用戶相關的操作通過token驗證,用戶主鍵信息不通過接口明文傳送,在服務端通過token解密獲取。token的加解密過程都在服務端完成,和簽名驗證模塊獨立。

    這兩個模塊也可以通過下邊的簡單時序圖了解相關分工:

 

二. Restful接口下安全實現方式介紹

 上邊介紹了一個基礎的接口驗證步驟,這邊我以常見的http接口協議來簡單介紹下實現過程:

  1. 簽名驗證

  這個主要是通過對每次請求通過參數和隨機數的排序組合生成唯一的簽名【sign】信息,方式多種多樣,這里我介紹一種通用做法,如果你對第三方網站簽名驗證比較熟悉可以跳過。

  這里因為一個接口項目可能會給對個應用提供數據服務,我們給每個應用頒發對應的appid和appsecret信息。

        第一步,在正常傳遞的參數外,添加appid,timespan(當前時間戳)參數,把當前參數集合中值不為空的參數按照參數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串str,同時需要注意一下幾點。

    1. 參數名ASCII碼從小到大排序(字典序)
    2. 參數的值為空不參與簽名
    3. 參數名區分大小寫

         第二步,將得到str使用簽名算法,生成sign(主要看和服務器約定的加密算法,一般使用單向簽名算法即可),一下是兩種常見加密算法

    1. 使用MD5

     在str后追加  &appsecret=xxx 后再進行md5 加密,即 sign = md5(str&appsecret=xxx)

    2.  使用SHA1

       因為sha1本身支持加鹽操作, 直接使用  appsecret加密 str ,即 sign=sha1(str, appsecret) 

    第三步:  傳遞內容   str&sign=xxxx   到服務端。

    以上是一個基本的簽名實現過程,當然具體的實現可以根據實際情況各自調整,比如簽名信息也可以放在請求header中,參數格式也可以是json等,重要的是需要保證:每次請求簽名不會相同

  2.  用戶授權驗證實現

    這個大家可以參考最近比較流行的 jwt 協議等實現,主要思路是用戶授權后,服務端頒發token返回給客戶端,在請求相關授權接口時附帶token即可。

    這里加密算法需要使用雙向加密算法,然后服務端在處理請求時,攔截並解密相關信息,保存在上下文中。

三. OSS.Core實現案例

     1. 簽名驗證:

  在OSS.Core項目,我把簽名相關驗證信息放置在請求頭(httpheader)中,通過自定義AuthorizeSignMiddleware中間件在程序入口處進行攔截,主要包含以下參數(實現代碼詳見GitHub):

  如果你想了解詳細排序加密等處理,可參見OSS.Common中的SysAuthorizeInfo

  2. 用戶驗證模塊:

  主要通過自定義Attribute注冊實現,代碼詳見 GitHub中AuthorizeMemberAttribute,  同時我會將當前用戶信息保存在一個 AsyncLocal 變量中,詳細代碼參見OSS.Common中的MemberShiper

四.  OSS.Core接口參數規范

  所有的接口信息中,我會定義套全局錯誤碼,所有的接口返回信息中都會包含ret標識,來返回當前接口的正常與否,比如:如果ret=1423時表示非法應用來源,ret=1425需要去獲取授權驗證token,當然每個接口也可以自定義其特有的局部錯誤碼。 

  全局錯誤碼詳見:Github 下 ResultTypes

  同時,接口請求頭中AppSource,AppVersion,AppClient 參數必填,來保證后續的活躍度,用戶注冊,訂單分布等情況統計。

 

     注:有些朋友說這些在頁面上並無用處,可能大家還沒搞清楚相互的層級關系,當前一個常見的系統一般分為兩個主要部分:1.  接口層    2.  交互層(客戶端,web站點)

     首先:本文的驗證安全主要討論的是接口層,朋友們擔心的短信利用在交互層面上需要做交互層面上對應的措施,包括但不限於手動驗證碼,臨時令牌等,切不可混為一談,但如果接口層都沒有做好最基礎的防護,上層做再多的措施也都為零,有點經驗的人通過網絡監控就可以獲取接口地址,直接繞開前端。

  其次: ip限流,https等在有一定條件的情況下,添加最好,交叉驗證,和上述方法是互補的關系,而不是互斥的關系。但在項目前期並不建議,精力最好還是集中在項目本身,這些都有第三方產品,上線之后添加即可。

 

如果你感覺本文對你有一定的幫助,請給個贊吧!!!

 

======================================== 

如果你還有其他問題,歡迎關注公眾號(OSSCoder)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM