タラバガニー設計局stalins.clubNOTE/notes/method-security-is-an-alternative-to-route-security

認可をルーティングではなくメソッド境界に置く

認可を URL やルータの木に結び付けず、実際に業務操作を行うメソッドの境界へ置く方法もある。これは パス階層を認可階層として使う と対照的な設計である。

Spring Security の Method Security は @PreAuthorize@PostAuthorize@PreFilter@PostFilter などを Spring-managed method に付け、入力引数や戻り値を含めて認可できる。HTTP controller だけでなく service method にも適用できるため、同じ業務操作が HTTP、ジョブ、メッセージ処理など複数の入口から呼ばれる場合でも、認可境界を一か所に保ちやすい。

ASP.NET Core の resource-based authorization も、対象リソースを取得した後で IAuthorizationService.AuthorizeAsync(user, resource, ...) を呼ぶ形を公式に案内している。こちらは AOP 的な method security ではないが、「ルートへ先に属性を置く」のではなく、リソースが具体化した場所で認可する点が共通している。

この配置の強みは、権限が URL 構造ではなく 操作の意味 に結び付くことである。ApproveInvoicePublishArticle のような操作は、同じ resource でも viewedit とは別の権限を持ちやすい。そうした場合に URL のネストへ権限モデルを押し込む必要がない。

一方で、ルーティング定義だけを読んでも「この endpoint へ入るためにどの認可が必要か」が見えにくくなる。さらに controller と service の両方で認可すると二重化しやすい。したがって、入口で粗い認証・ロール判定を行い、リソース依存の細かい認可を method boundary に置く、といった責務分担が現実的である。

リソースベース認可では認可より先にリソース解決が必要 の観点では、この方式は「解決と認可を handler/service の近くまで遅らせる」選択肢といえる。

出典

▸ ノート一覧に戻る