.NET API 接口數據傳輸加密最佳實踐( 三 )

IApiEncrypt 接口標簽的才會正常進行解析綁定 。
剩下的就是在 ConfigureService 中添加進去即可:
services.AddControllers(options => { ... options.ModelBinderProviders.Insert(0, new SecurityTransportModelBinderProvider());})這樣實現過后,我們就能像使用 FromBody 那樣就能按需調用即可:
[HttpPost("security")]public async Task<ResultDto> DemoDecrypt([ModelBinder(typeof(SecurityTransportModelBinder))] OriginBusinessRequest request){//激活結果 ...return await Task.FromResult(WriteSafeData(data, publicKey));}如果是默認處理加解密也是可以的,直接在對應的請求實體類打上 IApiEncrypt 標簽就會自動執行模型綁定
public class UserUpdateRequest: IApiEncrypt { public int UserId { get; set; } public string Phone { get; set; } public string Address { get; set; } ...}這種方案其實也還是有缺點的 , 從剛剛的使用來看就知道,模型綁定無法解決返回自動加密處理 。所以我們不得不在每個接口處寫下如 WriteSafeData(data, publicKey) 這種顯式加密的代碼 。
優化的方式也很簡單,其實我們可以通過過濾器可以解決,這也是為什么我要加 IApiEncrypt 的原因,因為有了這個就能確定知道這是一個安全傳輸的請求,進而進行特殊處理 。

注意,這不是 .NET Core 獨有的特性,.Net Framework 也有模型綁定器
總結針對接口級傳輸加密這個需求,我們總共討論了四種實現方式 。其實各有各的好處和缺點 。
硬編碼方式適合只有特定需求的場景下是適合這種方案的 。但是一旦這種需求成為一種規范或普遍場景時,這個方法就不合適了
統一入口適合制定了一種接口規范,所有加密的請求都走這一個接口 。然后通過路由解析調度到不同的控制器 。其實我講了我司在 .NET Framework 下采取的一種方案 , 好處時實現簡單,做到了代碼復用,對業務代碼進行了解耦 。但缺點是用了反射成為了性能消耗點,并且當業務越來越多就會產生代碼爆炸,成為了維護災難 。
而中間件或 IHttpModule 方式就很好的解決這了這點 。但同樣也不是使用所有場景,如對新增的不需要加密的接口要進行過濾處理等 。
最后介紹了模型綁定這種方式,技能很方便的滿足大多數場景 , 也滿足個別列外的需求 。但同樣也有缺點,就是無法針對接口響應體進行自動加密處理,所謂好事做到底,送佛送到西 , 這事只能算是做到一半吧 。
其實我還想到了一種類似 Aop 的方案,那就是實現一個路由過濾器的功能,當請求進來,通過路由處理程序對請求體進行解密,然后重寫請求流 。然后調度到對應的原始路由,最后在響應的時候再加密重寫一次 。不過查閱了一番資料,并沒有收獲 。
參考資料
  • https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.modelbinding.imodelbinderprovider?view=aspnetcore-7.0
  • https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-6.0
  • https://www.stevejgordon.co.uk/html-encode-string-aspnet-core-model-binding
【.NET API 接口數據傳輸加密最佳實踐】

推薦閱讀