閒談軟體設計:身家調查

更新於 發佈於 閱讀時間約 6 分鐘

上一回 閒談軟體設計:安全聲明聊到怎麼替每個 endpoint 加上安全聲明,它就像是在入口貼一張紙,上面寫著:只有某單位的某角色或上層單位的某角色能進入,也可能是簡單的閒雜人等禁入。現在有某個人來了,身上別個通行證,我們僅依靠通行證就讓這個人進入嗎?這就是這回要聊的身家調查。

資料採信原則

對後端開發者在處理 request 大概都會有這個原則:前端資料不可信。產品上線後,有壞人會亂搞。所以那些資料可以採信就是後端要仔細思考的。這也是為什麼光是怎麼辨識 session,有人說不要用 XXX,有人說要用 XXX,各有各的說法。

沒有要戰前後端,目前我一個人同時寫後端和前端,要不是有找到好夥伴一起加入,連 app 都要自己寫,對我來說,我在開發「產品」,不是後端或前端。

一般來說,在使用者登入 (完成驗證) 後,後端會簽署一張憑證,後面所有的操作都是透過這張憑證,有時間限制的就像是一張臨時通行證,沒時間限制的就是永久通行證。但後端怎麼知道這個憑證不是假造的?簽署時通常會留檢核碼,後端在看到通行證後,把通行證上的資料和只有後端知道的資料再核算一次檢核碼,若檢核碼相同,這個通行證是偽造的機率就很低了。

但也就只有這樣了,至於有這個通行證的 request 是不是由當初驗證的人所發出,就沒有百分百的方式可以辨別了。

這樣就放行?當然不是,通行證是有可能被註銷的,因此還是要去查一下這張通行證的狀態,若沒問題,這張就是有效的通行證,到這邊,我們可以開始檢查這個人能不能進入了。如果這個入口僅是貼著「閒雜人等禁入」,那有通行證的人已經可以進入了;但如果「只有某單位的某角色或上層單位的某角色能進入」,剩下要考慮的便是角色來源和組織層級。

角色來源。曾有一陣子,有把使用者角色編到通行證裡的做法,這樣的好處是可以直接讀取通行證,省去較耗時的資料庫讀取。但缺點也很明顯,一旦使用者的角色變了,要註銷已發出的通行證,到換發新通行證前,所有的請求都會失敗。因此,在這次的系統設計裡,憑證只有最簡單的資訊:誰、簽發時間、到期時間及簽發單位 (還有檢核碼)。使用者擁有的角色是每次請求來的時候向 IAM 子系統查詢。

組織層級。在 RESTful API 的設計上,曾在閒談軟體設計:休息時間聊過,不過那時候並沒有特別提到,resource identifier 要不要把資源層級納入?例如,這次的組織層級有O、M、S 三層,那要存取 M 時,路徑應該是 /s/{mId} 還是 m/{oId}/{mId}?這次設計時我使用前者,因為 oId 可能會誤導,例如 /m/o123/m1234,很直覺會以為 m1234 屬於 o123,但真的是這樣嗎?有沒有可能用有 o123 主管權限的憑證,用這路徑存取不屬於 o123 的 m1234 呢?既然不能相信,那就乾脆不用帶上來,只帶最低限度有用的資料上來就好。

這次選擇前者,不僅僅是安全上的考慮,這次為了加速開發,把 O 和 M 之間還有一層 C 的組織先忽略了,如果選擇後者,之後把 C 加回來,那 API 是否要跟著變動?這就讓我想到,在原始論文中有提到,API 應該隱藏內部細節,讓路徑是穩定鮮少變動的。

Security Context

既然前端的資料不可信,那檢查安全聲明時,什麼資料是可信的?為此,定義了一個 SecurityContext 介面,規範在檢查安全聲明需要的資料:(1) 使用者擁有什麼角色和 (2) 請求的資源 (Resource) 存不存在。

而這些資料由 SecurityContextResolver 的實作提供,負責從請求的 Context 中試圖解析出來,其中一個實作大概像這樣:

  • 先用 this.subjectResolver.resolve(context) 找出是誰
  • 接著用 this.resourceResolver.resolve(context) 找到請求的資源,還記得上回的 PathResourceResolver.of("s") 嗎?
  • 然後用迴圈的方式,一路詢問該資源的上層資源是什麼?

最後把所有的資料整合在一起,也就說身家調查,不只調查使用者的角色,也調查了請求的資源的祖宗十八代。

Java 的 Optional 雖然有 ifPresent(consumer) 的用法,卻沒有 guard let return 的形式有點不方便,只能用 orElseThrow() 來提前離開,但不是每個地方都適合拋出例外,有趣的是,有時候我不用 ifPresent(consumer) 的原因是 consumer 不允許拋出例外…

有了這些資訊,ScopedRoleSecurityClaim 的實作就很單純了:

  • 先用請求的資源類型,來找資源
  • 接著用「找到的資源」和「聲明的內容」來檢查是否有對應的角色

拿上回提到的 anySResponsible(),由三個 ScopedRoleSecurityClaim 組成,假設按順序是 O 的主管或擁有者、M 的主管或擁有者和 S 的主管或擁有者,這三個實體分別顯查 O、M 和 S 資源存不存在,假設存在,再問是不是有對應的角色,只要其中一個滿足即可。

小結

整個身家調查的過程中,只有最一開始 PathResourceResolver 提供的 sId 來自前端,其餘資訊都是從資料庫取得,即便是 sId 也會檢查對應的資源存不存在。搭配彈性的安全聲明,就可以完成不同形式的安全檢查了。

留言
avatar-img
留言分享你的想法!
avatar-img
Spirit的沙龍
55會員
107內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit的沙龍的其他內容
2025/06/22
本文探討如何使用函數式風格聲明 Javalin API endpoint 的安全性需求,並透過組合函數,例如 any 和 all,以及自定義函數,例如 anyManager 和 anyOwner,來簡化複雜的權限檢查。此方法避免了使用註解的繁瑣,並提高了程式碼的可讀性和可維護性。
Thumbnail
2025/06/22
本文探討如何使用函數式風格聲明 Javalin API endpoint 的安全性需求,並透過組合函數,例如 any 和 all,以及自定義函數,例如 anyManager 和 anyOwner,來簡化複雜的權限檢查。此方法避免了使用註解的繁瑣,並提高了程式碼的可讀性和可維護性。
Thumbnail
2025/06/15
從Spring Boot轉換到Javalin的過程與考量,以及如何保持核心業務邏輯與Web框架的距離以提升專案彈性。文中比較了Micronaut, Helidon和Javalin三個輕量級框架,並說明選擇Javalin的原因及優缺點。
Thumbnail
2025/06/15
從Spring Boot轉換到Javalin的過程與考量,以及如何保持核心業務邏輯與Web框架的距離以提升專案彈性。文中比較了Micronaut, Helidon和Javalin三個輕量級框架,並說明選擇Javalin的原因及優缺點。
Thumbnail
2025/06/08
日誌設計包含幾個重要考量因素,包括關聯式查詢、雲端生態支援、情境豐富性、結構化日誌以及與商業邏輯核心保持距離。利用 correlation ID、ThreadLocal 以及自定義抽象物件,實現了這些需求,並簡潔地說明在不同任務發動情況下 (API請求、定時執行、事件驅動) 的使用
Thumbnail
2025/06/08
日誌設計包含幾個重要考量因素,包括關聯式查詢、雲端生態支援、情境豐富性、結構化日誌以及與商業邏輯核心保持距離。利用 correlation ID、ThreadLocal 以及自定義抽象物件,實現了這些需求,並簡潔地說明在不同任務發動情況下 (API請求、定時執行、事件驅動) 的使用
Thumbnail
看更多
你可能也想看
Thumbnail
家中修繕或裝潢想要找各種小零件時,直接上網採買可以省去不少煩惱~看看Sylvia這回為了工地買了些什麼吧~
Thumbnail
家中修繕或裝潢想要找各種小零件時,直接上網採買可以省去不少煩惱~看看Sylvia這回為了工地買了些什麼吧~
Thumbnail
👜簡單生活,從整理包包開始!我的三款愛用包+隨身小物清單開箱,一起來看看我每天都帶些什麼吧🌿✨
Thumbnail
👜簡單生活,從整理包包開始!我的三款愛用包+隨身小物清單開箱,一起來看看我每天都帶些什麼吧🌿✨
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
自由接案好像很自由、容易,卻需要點方向的指引,希望這篇的分享能給予你一些幫助。
Thumbnail
自由接案好像很自由、容易,卻需要點方向的指引,希望這篇的分享能給予你一些幫助。
Thumbnail
資訊架構就像是網站的地圖,讓用戶快速找到所需的資訊。好的資訊架構可提升使用者滿意度、強化 SEO、增進擴充性、達成商業目標。資訊架構可透過使用者訪談、卡片分析、競品分析、使用者測試等方法設計。在設計資訊架構時,需考量用戶的認知方式、目標客群、資訊分類等因素。定期檢驗資訊架構,才能確保用戶體驗。
Thumbnail
資訊架構就像是網站的地圖,讓用戶快速找到所需的資訊。好的資訊架構可提升使用者滿意度、強化 SEO、增進擴充性、達成商業目標。資訊架構可透過使用者訪談、卡片分析、競品分析、使用者測試等方法設計。在設計資訊架構時,需考量用戶的認知方式、目標客群、資訊分類等因素。定期檢驗資訊架構,才能確保用戶體驗。
Thumbnail
利用文字紀錄,明確寫下自己的採購項目......
Thumbnail
利用文字紀錄,明確寫下自己的採購項目......
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
Thumbnail
權限管理=新增、修改、刪除+審核 通常,這種程式的設計會包含權限管理,其中包括現場修改、刪除等三大類功能。然而,根據經驗,我們還需要關注另一類功能,即審核權限。 審核不執行新增 審核權限通常不執行新增的動作,僅限於某些欄位的輸入。新增、修改、刪除這些操作基本上是容易理解的。也就是說,對於這個工
Thumbnail
權限管理=新增、修改、刪除+審核 通常,這種程式的設計會包含權限管理,其中包括現場修改、刪除等三大類功能。然而,根據經驗,我們還需要關注另一類功能,即審核權限。 審核不執行新增 審核權限通常不執行新增的動作,僅限於某些欄位的輸入。新增、修改、刪除這些操作基本上是容易理解的。也就是說,對於這個工
Thumbnail
先前幾篇筆記介紹了網路請求,瀏覽器儲存資料的方式,那麼實務上,前端最常需要發送網路請求的時候,就是透過呼叫 API,去向後端工程師發送/請求資料,所以今天來記錄什麼是 API吧!
Thumbnail
先前幾篇筆記介紹了網路請求,瀏覽器儲存資料的方式,那麼實務上,前端最常需要發送網路請求的時候,就是透過呼叫 API,去向後端工程師發送/請求資料,所以今天來記錄什麼是 API吧!
Thumbnail
談了許多網路安全的議題,提醒民眾要注意哪些事情,建構哪些網路安全思維,讓我們可以降低踏入詐騙陷阱的風險。但除了民眾本身要不斷學習、提升防詐意識外,是不是還有其他方面的作法呢? 本文就來聊聊在企業端可以做些什麼。 要打造一個密不可破的防護網,企業端就不能夠缺席。 舉幾個例子讓大家知道。
Thumbnail
談了許多網路安全的議題,提醒民眾要注意哪些事情,建構哪些網路安全思維,讓我們可以降低踏入詐騙陷阱的風險。但除了民眾本身要不斷學習、提升防詐意識外,是不是還有其他方面的作法呢? 本文就來聊聊在企業端可以做些什麼。 要打造一個密不可破的防護網,企業端就不能夠缺席。 舉幾個例子讓大家知道。
Thumbnail
最近有專案需求要在 Web 上進行一個掃描條碼辨識的動作,做了一些功課,有 Open Source 方案跟商業解決方案,整理起來分享給大家。
Thumbnail
最近有專案需求要在 Web 上進行一個掃描條碼辨識的動作,做了一些功課,有 Open Source 方案跟商業解決方案,整理起來分享給大家。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News