Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
B2B SaaSでSpringSecurityによる Roleを用いたユーザー権限設定の 実装...
Search
Rakus_Dev
November 11, 2023
Programming
690
1
Share
B2B SaaSでSpringSecurityによる Roleを用いたユーザー権限設定の 実装について
Rakus_Dev
November 11, 2023
More Decks by Rakus_Dev
See All by Rakus_Dev
主体的に活躍する内製QA組織の作り方と組織文化の醸成 / How to Build a Proactive In-house QA Organization and Foster Its Culture
rakus_dev
0
200
AI実装による「レビューボトルネック」を解消する仕様駆動開発(SDD)/ ai-sdd-review-bottleneck
rakus_dev
0
190
仕様駆動開発の組織的定着に向けた取り組み ~『楽楽電子保存』開発チームの事例~ / Establishing SDD: Organizational Initiatives
rakus_dev
0
390
全エンジニアのAI活用状況を可視化する~Lookerを用いたアンケート分析と今後の推進策~ / Visualizing AI Adoption Across Engineering
rakus_dev
0
410
出してみてわかったAIエージェントプロダクトの舞台裏 〜楽楽AIエージェント for 楽楽精算〜 / Behind the Scenes of Rakuraku AI Agent
rakus_dev
0
420
プロダクトマネージャーの目標と評価 / Goal Setting for Product Managers
rakus_dev
1
880
【pmconf2025】AI時代の『ジュニア不要論』に異議あり! 未経験から戦力PdMを生み出すOJT戦略とは?
rakus_dev
1
1.1k
プロダクトづくりにAIを溶かす3つの壁 ― ラクス流AI浸透のススメ / 3 Barriers to AI in Products: The Rakus Way
rakus_dev
0
2.7k
設計フェーズを加速するAI活用戦略 / AI Strategy for Accelerated Design
rakus_dev
4
710
Other Decks in Programming
See All in Programming
テレメトリーシグナルが導くパフォーマンス最適化 / Performance Optimization Driven by Telemetry Signals
seike460
PRO
2
200
20260320登壇資料
pharct
0
140
[PHPerKaigi 2026]PHPerKaigi2025の企画CodeGolfが最高すぎて社内で内製して半年運営して得た内製と運営の知見
ikezoemakoto
0
310
PHPのバージョンアップ時にも役立ったAST(2026年版)
matsuo_atsushi
0
270
Kubernetesでセルフホストが簡単なNewSQLを求めて / Seeking a NewSQL Database That's Simple to Self-Host on Kubernetes
nnaka2992
0
190
Symfony + NelmioApiDocBundle を使った スキーマ駆動開発 / Schema Driven Development with NelmioApiDocBundle
okashoi
0
250
条件判定に名前、つけてますか? #phperkaigi #c
77web
2
900
コードレビューをしない選択 #でぃーぷらすトウキョウ
kajitack
3
1.2k
仕様漏れ実装漏れをなくすトレーサビリティAI基盤のご紹介
orgachem
PRO
8
3.8k
Migration to Signals, Signal Forms, Resource API, and NgRx Signal Store @Angular Days 03/2026 Munich
manfredsteyer
PRO
0
200
Tamach-sre-3_ANDPAD-shimaison93
mane12yurks38
0
220
RailsのValidatesをSwift Macrosで再現してみた
hokuron
0
140
Featured
See All Featured
Docker and Python
trallard
47
3.8k
Statistics for Hackers
jakevdp
799
230k
Done Done
chrislema
186
16k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
170
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
160
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.8k
Building AI with AI
inesmontani
PRO
1
840
The Spectacular Lies of Maps
axbom
PRO
1
670
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.4k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
230
Paper Plane (Part 1)
katiecoart
PRO
0
6.2k
Designing Powerful Visuals for Engaging Learning
tmiket
1
320
Transcript
© RAKUS Co., Ltd. B2B SaaSでSpringSecurityによる Roleを用いたユーザー権限設定の 実装について JJUG CCC
2023 Fall 株式会社ラクス 開発統括部 HUYNH PHUONG(フィン フォン) 2023/11/11 1
© RAKUS Co., Ltd. 2 自己紹介 HUYNH PHUONG(フィン フォン) ・株式会社ラクス
開発統括部 ・バックエンド エンジニア ・担当サービス:楽楽電子保存 自己紹介
© RAKUS Co., Ltd. 3 本日お話すること ・開発要件 ・実装方法選定 ・SpringSecurityの機能を使った事例 ・SpringSecurityでは実現できない部分
Spring AOP(AspectJ)で回避
© RAKUS Co., Ltd. 4 はじめに 本事例の対象サービス「楽楽電子保存」 オンライン上で請求書の受取・管理 はじめに
© RAKUS Co., Ltd. 5 開発要件
© RAKUS Co., Ltd. 6 こんな開発要件がありました。 無料版ユーザー 有料版ユーザー • 有料版/無料版で利用できる機能を制限する
開発要件 エンドポイント 制限
© RAKUS Co., Ltd. 7 • ユーザーの持っている権限に応じてアクセスできる データを制限する 開発要件 データ制限
© RAKUS Co., Ltd. 8 • アクセス違反の理由に応じて、エラーメッセージを 出し分ける 開発要件 オプションが有
効でない 権限がない 指定タグに閲覧 権限がない 指定帳票に閲覧 権限がない 無料版ユーザー 有料版ユーザー 有料版ユーザー 有料版ユーザー
© RAKUS Co., Ltd. 9 開発要件を実現するにあたり実装時 に遭遇したいくつかの課題を紹介さ せていただきます。
© RAKUS Co., Ltd. 10 実装方法選定
© RAKUS Co., Ltd. 11 実装方法の選択肢 Spring bootを利用しているのでこの前提で 以下のいずれかの方法で検討しました ・Spring
security ・Spring AOP(AspectJ) ・Filter 実装方法選定
© RAKUS Co., Ltd. 12 実装方法選定 Spring security 使う強み ・セキュリティ機能は最低限の設定で実装できること
・一般的な脆弱性の対策を広くカバーしている ・単体テストもサポートされている
© RAKUS Co., Ltd. 13 実装方法選定 Spring AOP(AspectJ) 使う強み ・クリーナーコード
メインロジックから横断的関心(Crosscutting Concern) (ロギング、セキュリティなど)を取り除く ・メンテナンスが楽になる AOPで注入する処理は共通処理として一元管理される
© RAKUS Co., Ltd. 14 実装方法選定 Filter 使う強み ・Springは、Filterを作成するためのサポートクラスも 提供されている
・各コントローラーの前後に共通処理を実行することが 担保できる
© RAKUS Co., Ltd. 15 実装方法選定 Spring securityとAOPを併用しました 現場で認証処理はSpringSecurityで実装されていたので 認可処理でも簡単に実装できた
無料版ユーザー 有料版ユーザー
© RAKUS Co., Ltd. 16 実装方法選定 指定タグに閲覧 権限がない 指定帳票に閲覧 権限がない
有料版ユーザー 有料版ユーザー SpringSecurityで実装できない部分も出てしまったので Spring AOP(AspectJ)で回避できた (セキュリティーは横断的関心(Crosscutting Concern)の 中で一つなので似合っている)
© RAKUS Co., Ltd. 17 SpringSecurityの機能を使った事例
© RAKUS Co., Ltd. 18 SpringSecurityの機能を使う部分 SpringSecurityの認可機能なら、 アクセス権限を制御することは簡単に出来る 図:HttpServletRequest を認証する(Spring公開ドキュメント)
ここで触る
© RAKUS Co., Ltd. 19 SpringSecurityの機能を使う部分:実装事例 現場での実装事例 ログインの際にSecurityContextのAuthentication情報 にGrantedAuthority一覧を追加する List<GrantedAuthority>
authorities = List.of( new SimpleGrantedAuthority(“MANAGER”) ); SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(principal, credentials, authorities));
© RAKUS Co., Ltd. 20 SpringSecurityの機能を使う部分:実装事例 http.authorizeHttpRequests(auth -> { authenticationProperties.getAuthorities().forEach(authority
-> auth.requestMatchers(authority.getHttpMethod(), authority.getEndPoint()) .hasAnyRole(authority.getRole())); }) HttpServletRequestsを利用し、認可定義 Httpメソッドによる マッチング RequestMatcherによる マッチング
© RAKUS Co., Ltd. 21 SpringSecurityの機能を使う部分:実装事例 AccessDeniedHandlerの処理関数を用意する public AccessDeniedHandler accessDeniedHandler()
{ return (request, response, accessDeniedException) -> { request.getRequestDispatcher(【該当パス】) .forward(request, response); }; } 無料版/有料版を判断し、 該当のエラーコントローラーへ移動
© RAKUS Co., Ltd. 22 SpringSecurityの機能を使う部分:実装事例 http.exceptionHandling(e -> e.accessDeniedHandler(accessDeniedHandler())); Spring
SecurityのAccessDeniedHandlerを定義する
© RAKUS Co., Ltd. 23 SpringSecurityでは実現できない部分 Spring AOP(AspectJ)で回避
© RAKUS Co., Ltd. 24 Spring AOP(AspectJ) Spring認可の課題 アクセス権限がない時にAccessDeniedExceptionのみを 返すため、エラーケースを区別するのは簡単にできない
P22~23で使用してい るが、無料版/有料版 の判断がすごく簡単 だから!
© RAKUS Co., Ltd. 25 指定タグに閲覧権限がない 指定帳票に閲覧権限がない 指定アップロードファイルに閲覧権限がない Spring AOP(AspectJ):Spring認可の課題
・データベースへ アクセスが必要 ・分岐ケースも 多い
© RAKUS Co., Ltd. 26 Spring AOP(AspectJ):Spring認可の課題 複雑で同様処理だが二重実行が発生 ・認可 ・エラー出し分け
AOP
© RAKUS Co., Ltd. 27 AOP概要 Spring AOP(AspectJ):AOP概要 クラスを横断した処理(例外処理やロギングなど)をビジ ネスロジックから分離するようにコードを記述する
Advice Join points Point cut Program Execution Advice:抽出した共通処理 Joinpoint:Adviceを入れる場所 (@Before、 @Afterなど) Pointcut:Adviceを適用する条件 例: @Before("@annotation(XXX)") https://spring.pleiades.io/spring- framework/reference/core/aop.html
© RAKUS Co., Ltd. 28 Spring AOP(AspectJ):実装事例 現場での実装事例 ・専用アノテーションを作成する ・AOPのAdviceを定義して権限チェック処理を実装する
・権限チェックのAOPをメソッドに注入する
© RAKUS Co., Ltd. 29 Spring AOP(AspectJ):実装事例 専用アノテーション @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME)
public @interface BrowsableChecker { } メソッドのみに使用できる
© RAKUS Co., Ltd. 30 Spring AOP(AspectJ):実装事例 Advice定義 AOPのAdviceを定義し、権限チェック処理を実装する @Aspect
@Component public class BrowsableCheckerAspect { @Before("@annotation(BrowsableChecker)") public void check(JoinPoint joinPoint) { // 権限判断処理を行う } } メソッドが実行される前に、 Advice実行 AOP宣言 指定したアノテーションが付いて いるメソッドのみがAOPの対象
© RAKUS Co., Ltd. Advice定義(権限判断処理) @Before("@annotation(BrowsableChecker)") public void check(JoinPoint joinPoint)
{ // パラメーターを取得する Object command = joinPoint.getArgs()[0]; // commandを該当な型に変換する if (target instanceof XXXCommand cmd) { // データベースからデータを取得して権限チェ ック // アクセス拒否の場合、例外をThrowする } } Joinpointから メソッドの パラメーターが取 得可能 Spring AOP(AspectJ):実装事例
© RAKUS Co., Ltd. Spring AOP(AspectJ):実装事例 AOP注入 データアクセス制御が必要なサービスのメソッドに 専用アノテーションを簡単に付ける @Service
public class XXXUpdateService { @BrowsableChecker public void execute(XXXCommand cmd) { // メイン処理を行う(略) } } excuteメソッドの処 理を実行する前に、 権限チェックのAOP を実行する
© RAKUS Co., Ltd. Spring AOP(AspectJ):実装事例 単体テスト 単体テストでもMockとして共通化に用意する public class
BrowsableCheckerMock { public void setup(XXXCommand command) { // 共通Mock処理を行う } } 権限チェックMockクラス
© RAKUS Co., Ltd. Spring AOP(AspectJ):実装事例 単体テスト @SpringBootTest @Import([BrowsableCheckerMock.class]) class
XXXUpdateServiceSpec extends Specification { def "アクセスする権限がありません"() { setup: browsableCheckerMock.setup(cmd) } } @Importを定義し、使用する
© RAKUS Co., Ltd. おわりに おわりに Spring securityの認可機能はエンドポイント単位も データ単位も制限可能 但し、SpringSecurityの認可で実装すれば、アクセス拒否の時に
AccessDeniedExceptionのみを返すため、エラーの理由を区別する ことができないので注意必要 セキュリティーとは横断的関心(Crosscutting Concern)の中で一つ なのでSpringSecurity認可の代わりに、AOPで回避可能
© RAKUS Co., Ltd. おわりに Spring Security in Action Laurentiu
Spilca 参照 Spring によるアスペクト指向プログラミング https://spring.pleiades.io/spring- framework/reference/core/aop.html Spring Security - リファレンス https://spring.pleiades.io/spring-security/reference/
© RAKUS Co., Ltd. ご清聴ありがとうございました