閒談軟體設計:安全聲明

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

上一篇 閒談軟體設計:Web 框架的選擇提到,離開 Spring framework 後,需要有安全檢查與資料庫交易管理相關的配套,現在就來聊聊與安全檢查相關的議題,不過這次只聊怎麼「聲明」每個請求需要的安全性。

Spring Security 的寫法

Spring framework 裡的 Spring Security 提供非常彈性 (複雜) 的設計,包含身分驗證權限檢查,這邊就先不討論身分驗證,只看權限檢查,Spring Security 有非常多種設定的方法,簡單一點的像是直接針對路徑設定 (範例來自官網):

或是彈性一點,針對每個函式設定 (範例來自官網):

除了 Role-based,也可以用 ACL (範例來自官網):

Javalin 的寫法

Spring Security 可以說是相當彈性,那 Javalin 呢?在官網上可以看到,能對每個 endpoint 設定對應的角色,雖然沒有 Spring Security 來的多樣性,但很多情況下是相當夠用的。

到這邊為止,不管是用 .requestMatchers("/api/user/**").hasRole("USER") 或是 @PreAuthorize(hasRole("ADMIN")),還是 app.get("/private", ctx -> ctx.result("Hello private"), Role.LOGGED_IN);,都是在做一件事:「聲明」這些請求需要怎樣的安全性。至於,是否滿足這些聲明,通常是框架幫忙處理了,讓開發者只需要聲明即可。

角色設計

回到這次要開發的系統。首先,系統有 O、M 和 S 三個不同組織階層 (細節不方便透露太多),及三個後端 (backends for frontends),針對不同的服務提供不同的 API endpoints,三個服務的帳號是分開管理,因此,A 服務的登入資訊是無法呼叫 B 服務的 API。

三個服務都有不同的角色設計,其中最複雜的,是每個資源階層都可以有擁有者 (owner)、管理者 (manager)、一般職員(staff) 以及財務 (finance) 四種角色。職員和財務都是唯讀 (read-only) 的角色,差別是財務相關的資料只有財務 (以及擁有者和管理員) 看的到,擁有者比管理者多了角色管理的權限。最重要的是,上層角色的權限適用於下層的資源,也就是 M 的管理員,也是S 的管理員。

函式風格的聲明

針對這樣的資源階層和角色階層,要怎麼聲明,確實有點麻煩。雖然 Java 的 annotation 很適合用來宣告,但在 runtime 處理 annotation 老實說我覺得很麻煩,我比較喜歡用別人寫好的,自己寫這些處理就有點懶,而且也不太符合 Javalin 的風格。最後,我希望使用起來的感覺像這樣:

一開始的 post,指這個 endpoint 要用 HTTP POST,/resources/{sId},是該 endpoint 的路徑,最後是這個 endpoint 的 handler,被一個 secured 的函式包裝過,這函式的原型像是這樣:

第一個參數是實際的 handler,第二個參數是聲明 (JavalinSecurityClaim),secured 回傳一個 wrapper,該 wrapper 在呼叫實際的 handler 之前,先呼叫 claim.fulfill,如果不滿足聲明會拋出例外,忽略實際的 handler。

該如何提供聲明?上面的例子,anySResponsible() 意思是指該使用者能對 S 負責,具體來說必須是 S 的管理者或擁有者,或是 M 的管理者或擁有者,又或是 O 的管理者或擁有者,感覺很複雜?實際上它只有一行:

這邊是我個人偏好的命名,讓程式碼可以像一般的句子,這一行由三個函式組成,isanyResponsible 和 of。先看 anyResponsible,它用 any 函式 將 anyManager 和 anyOwner 包起來,any 是一個用來組合聲明的函式,只要組合的聲明哩,有任一個聲明滿足,就算是滿足,因此 anyResponsible 代表只要 anyManager 或 anyOwner 任一個滿足,就算是滿足。

JavalinSecurityClaim 和 SecurityClaim 之間不是繼承關係,SecurityClaim 用來描述與框架無關的資訊,JavalinSecurityClaim 則是與特定框架綁定,將 SecurityClaim 的資訊包裝成能在特定框架中執行的物件。

有了 any,很容易組出「必須是 S 的管理者或擁有者,或是 M 的管理者或擁有者,又或是 O 的管理者或擁有者」,anyManager 將 RoleScope 這個 enum 的值 (O、M 和 S) 拿出來,各別產生一個 ScopedRoleSecurityClaim 物件,然後再用 any 組合起來。ScopedRoleSecurityClaim 的責任很簡單,檢查該使用者有沒有對應階層的角色。anyOwner 也比照辦理。

除了 any,還有 all,必須是組合的聲明全部滿足才算滿足,但目前實際使用上,還沒有用到 all 的情境。

該有什麼角色已經確定了,但要怎麼知道從哪個階層的資源開始檢查?這就由 of 來處理,of 產生一個 PathResourceResolver 物件,這物件從請求的 context 中取得路徑上的變數,以 anySResponsible() 為例,它會試圖取得 /resources/{sId} 中 {sId} 的值,作為資源的 ID。最後 is 只是把角色 (anySResponsible()) 和資源 (of("s")) 封裝成 JavalinSecurityClaim 物件。

小節

這次選擇用函式來做聲明,搭配一些輔助函式,可以組合出不同的聲明,像是 anyMResponsible,就是單純的 is(anyResponsibile(), of("m")),重點是透過函式組合,能重複利用,減少重複的程式碼。到這邊,就完成了聲明的設計,但是怎麼檢查這些聲明是否滿足,則是另一個故事了。

留言
avatar-img
留言分享你的想法!
avatar-img
Spirit的沙龍
54會員
106內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit的沙龍的其他內容
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
2024/03/23
這篇文章探討了在軟體開發中的技術債可能來自哪些原因,以及如何自動化偵測與修復技術債。作者透過分享不同情境下的技術債選擇,提供了對於技術債的思考與建議,針對開發人員在需要做出無奈的技術決策時,提供了一些建議。此外,還提供了一些在做出技術決策時的方法,如保留抽象層和避免vendor lock-in。
Thumbnail
2024/03/23
這篇文章探討了在軟體開發中的技術債可能來自哪些原因,以及如何自動化偵測與修復技術債。作者透過分享不同情境下的技術債選擇,提供了對於技術債的思考與建議,針對開發人員在需要做出無奈的技術決策時,提供了一些建議。此外,還提供了一些在做出技術決策時的方法,如保留抽象層和避免vendor lock-in。
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
自由接案好像很自由、容易,卻需要點方向的指引,希望這篇的分享能給予你一些幫助。
Thumbnail
自由接案好像很自由、容易,卻需要點方向的指引,希望這篇的分享能給予你一些幫助。
Thumbnail
隨著企業在數位轉型過程中,愈來愈依賴多雲端架構,對雲端安全性和合規性的需求變得前所未有的重要。 雲原生應用程式保護平台(CNAPP)提供了一套全面的解決方案,讓企業能夠有效地管理多雲端環境中的安全性和合規性。
Thumbnail
隨著企業在數位轉型過程中,愈來愈依賴多雲端架構,對雲端安全性和合規性的需求變得前所未有的重要。 雲原生應用程式保護平台(CNAPP)提供了一套全面的解決方案,讓企業能夠有效地管理多雲端環境中的安全性和合規性。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
Anytype主要分為四區塊:目錄欄(Widget組成)、主編輯畫面、導航選單、設定區。
Thumbnail
Anytype主要分為四區塊:目錄欄(Widget組成)、主編輯畫面、導航選單、設定區。
Thumbnail
代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
Thumbnail
代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
Thumbnail
權限管理=新增、修改、刪除+審核 通常,這種程式的設計會包含權限管理,其中包括現場修改、刪除等三大類功能。然而,根據經驗,我們還需要關注另一類功能,即審核權限。 審核不執行新增 審核權限通常不執行新增的動作,僅限於某些欄位的輸入。新增、修改、刪除這些操作基本上是容易理解的。也就是說,對於這個工
Thumbnail
權限管理=新增、修改、刪除+審核 通常,這種程式的設計會包含權限管理,其中包括現場修改、刪除等三大類功能。然而,根據經驗,我們還需要關注另一類功能,即審核權限。 審核不執行新增 審核權限通常不執行新增的動作,僅限於某些欄位的輸入。新增、修改、刪除這些操作基本上是容易理解的。也就是說,對於這個工
Thumbnail
JavaScript 套件,頁碼 Pagination.js 搭配 axios API 請求範例
Thumbnail
JavaScript 套件,頁碼 Pagination.js 搭配 axios API 請求範例
Thumbnail
這邊統整了所有過去發表過關於 QUERY 函式的教學分享,希望可以方便你按照順序閱讀和練習。 QUERY 可以用來查詢、篩選、聚集、排序資料,還可以做張簡易的資料透視表,是我在 Google 試算表上做數據分析、製作報告、製作儀表板時最常用的函式之一,既方便又好用,誠心推薦!
Thumbnail
這邊統整了所有過去發表過關於 QUERY 函式的教學分享,希望可以方便你按照順序閱讀和練習。 QUERY 可以用來查詢、篩選、聚集、排序資料,還可以做張簡易的資料透視表,是我在 Google 試算表上做數據分析、製作報告、製作儀表板時最常用的函式之一,既方便又好用,誠心推薦!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News