上一篇主要講了整個項目的子模塊及第三方依賴的版本號統一管理維護,數據庫對接及緩存(Redis)接入,今天我來說說過濾器配置及攔截設置、接口安全處理、AOP切面實現等。作為電商項目,不僅要求考慮高並發帶來的壓力,更要考慮項目的安全穩固及可擴展。首先我們說說接口安全。
一,接口安全
說起安全,這似乎是IT行業一直以來的重點話題。實際真正的項目安全,更多的是運維工程師(安全專家)從網絡和服務器層面保護。目前基本每個大的互聯網公司都有一個安全團隊(推薦大家了解下阿里安全專家吳翰清)。今天我要說的只是接口安全防護(如何防止惡意請求、數據篡改),這也是好多中高級開發者經常在面試中被問到的話題。首先我說說思路,目前接口安全的基本防護方案就是:令牌+簽名,也有采用非對稱加密密文傳輸,https協議傳輸等方案。
1,令牌+簽名
這是今天要說的重點,令牌+簽名到底怎么實現接口安全請求呢?
簽名實現:最簡單的實現就是先把你要請求的參數轉化為字符串,再通過MD5給這個字符串加密,然后將加密后的字符串作為簽名參數。Java后台再寫一個過濾器,當請求進入過濾器,先取出參數在過濾器里按照這個規則生成校驗。但在實際開發中,這種方式很容易被他人模仿請求你的接口,那怎么辦呢?其實很簡單,給MD5生成的那個簽名“撒鹽”,也就是給那個簽名的字符串里的某個或某些片段植入隨機字符串,然后在后台過濾器校驗時,把這個片段內容取出替換后台生成的參數簽名里的那個片段再對比校驗。
令牌實現:令牌也就是我們常說的token,在用戶登錄后,生成一個唯一的token,並將這個token作為key,登錄者信息(一般都是封裝的登錄實體類)作為值存到Redis中,並將token返回給用戶。用戶要訪問其他接口,那你就必須帶token,在過濾器檢驗完簽名后,然后取到請求參數里的token,再查詢Redis檢驗Token是否有效,校驗不通過直接攔截返回。
部分代碼片段
注意,這里都是以封裝的實體和工具類處理返回。返回實體及返回工具類代碼如下:
自定義異常枚舉類:
注意:過濾器的一定要實現Filter接口,並添加注解
@WebFilter(filterName = "myFilter",urlPatterns = {"/*"}),如:
@WebFilter(filterName = "myFilter",urlPatterns = {"/*"})
public class MyFilter implements Filter {
然后重寫doFilter()方法。
2,非對稱密文傳輸
這個方案實現起來很簡單,可以先用RSA生成一對密鑰(公鑰何私鑰),服務端保存私鑰,公鑰給要訪問的客戶端,客戶端在請求接口時,把參數用RSA公鑰加密,服務端接收到客戶端請求傳入的密文,用自己的私鑰解密。這樣就算有人獲取到你的請求密文,甚至獲取到客戶端的公鑰,那也沒用,解不開,哪有人說了,如果拿到公鑰了,就可以隨意請求你的接口了。哪有你想的那么簡單,后台可以在過濾器再加個校驗簽名不就解決了。對一般的接口,是沒必要使用非對稱密文傳輸的,加密解密需要時間開銷,所以針對不同的業務場景,選擇合適自己的方案。
3,令牌+簽名方案測試驗證
這里我啟動服務測試一下,先在啟動類里添加包掃描,然后啟動服務測試。
在啟動服務前,已寫好的接口(用戶的添加和登錄接口)。
參數不帶token和簽名請求添加用戶接口。
參數里隨機添加簽名(未按約定規則生成)請求接口。
參數里的簽名按規則生成並發請求,這時開始驗證token。
那么我先登錄,獲取token再發起請求。
再看看數據庫。
二,AOP切面實現
這里用Aop主要實現日志及異常處理,首先我們在接口層(lyn-web)創建一個Aop的切面類,如下:
定義好切面,然后寫前置通知,后置通知,環繞通知。
前置通知主要打印了請求接口、IP、接口請求方式等信息,環繞通知抓取了接口的響應時間和異常處理,后置通知打印了相應的參數。接下來我將使用Aop實現一些其他功能。
三,防SQL注入實現
先寫一個非法字符檢驗工具類:
然后在AOP里寫一個參數檢查方法:
再在環繞通知里執行訪問接口前操作執行檢查方法
測試,參數帶sql注入關鍵詞(Drop user_info)發起請求。
看打印的日志:
那我們去掉去掉非法關鍵詞再發起請求:
再看看日志:
添加成功的數據庫數據:
推薦閱讀:
下期文章:深入介紹項目的配置,優化相關,以及緩存安全防范,Kafka的對接等內容。
獲取項目源代碼,請掃碼關注公眾號,並發送Springboot獲取。