業務SaaSアプリケーションのマイクロサービス化と認証認可

# はじめに
こちらの記事は[ツクリンクアドベントカレンダー](https://qiita.com/advent-calendar/2023/tsukulink)2023の22日目の記事です。


アドベントカレンダーということで何を書けばよいか考えましたが、業務ウェブシステムに長く携わっていたこともあり、それに関連した内容をお伝えできればと思い業務アプリケーションのマイクロサービス化について記載しました。
あまり私自身も理解が及んでいない、アップデートされていない点もあるかと思いまして概要レベルにとどめている点もありますので検討されておられる皆様の今後の議論のネタにでもあれば嬉しい限りです。


# マイクロサービス?
まずそもそもマイクロサービスの定義としては「協調して動作する小規模で自律的なサービス」ということを定義としてここでは語りきれないほどの概念やアーキテクチャパターンが存在し、NetFlix, Uber, Etsyなども様々な文献があります。

[Microservices – Netflix TechBlog](https://netflixtechblog.com/tagged/microservices)

これについては別文献や私の頑張り次第ではございますが次回作をご期待いただけると嬉しいです。

# マイクロサービス化のメリット
多数ある中で業務アプリケーションに特化した点でメリットいくつか記載致します。

### 回復性
レジリエンス(回復性)エンジニアリングの主要な考え方として「隔壁」という考え方があるかと思います。
とある箇所で障害が発生していてもそこと連鎖してなければ製品として動作を担保することができます。

### スケーリング
また、モノリシックな大規模サービスは基本的に全体スケールとなり、とある機能のみスケールさせるといった行為において柔軟にこなせるという点ではマイクロサービスに優位性があると考えております。

具体例としては以下のようなピークが想定される場合スケジュール化や機能担保がし易いです。

| システム | ピーク期間 | 要因 |
|:-----------|:------------|:-------------|
| 会計システム | 月末月初 | 請求書発行や仕訳・計上 |
| 請求書OCRシステム | 月初 | 請求書が到着するため |

また業界に依りますが、土日祝日は利用がほぼされないシステムなどもありますので、ピークを予め判断できるという面については費用の節約にもつながるかと存じます。

### デプロイ容易性
すべての業務システムで利用している共通コンポーネントなどがモノリシックなサービスで存在している場合、1行だけ変更する必要が出た際にその責務は非常に高いと言えます。(大規模リリースに混ぜ込むなどの運用になりがち)
その点残りのサービスとは独立してリソースを更新できる状態を築くことができれば容易性は高く問題が起きてもロールバックの時間や効率も良いと言えます。
これらはBFFやリポジトリ分断で解決できる場合もあるので一例として記載しております。


### その他
サービス毎に異なる技術を使うと行った決断も容易ではございます(技術異質性)
しかしながら業務アプリケーションという枠組みでジョブごとに適したツールや言語の選定となると、人的リソースの面で技術者を確保できる環境下ではメリットとなりますが、それが難しい場合メリットとならない場合もあります。


# マイクロサービス化のデメリット
### 分散するのでそもそもアーキテクチャが複雑になる
購買関連の業務システムの場合、見積→発注→出荷→検収→支払など前段及び後段の状況がリンクしていることを求められることが多いです。
このケースで

![スクリーンショット 2023-12-18 21.08.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71229/f58dfcda-0bd8-02a3-deb1-8e970d1cbab9.png)


- 見積システム
- 発注システム
- 支払システム

といったようにシステムを分断してしまうと、一つの購買情報のステータスを参照するために複数のシステムからデータを取得する必要があるので資源の不効率さが出てしまいます。
また、弾力性が高いことをメリットとして掲げましたが、スケーラビリティとパフォーマンスという観点においては、レイテンシ・スループットの最適化など限界の無い追求が必要にかられることもあり、このデメリットを減らすためにリアクティブ・非同期・ノンブロッキングなアーキテクチャを求められることになります。


# ここから認証認可の話へ
といったようになかなか難しいマイクロサービスの話ではありますが認証認可についてはどのように考えればよいのでしょうか。
いくつかの適した考え方や製品が存在します。


| 名称 | 機能 |
|:-----------|:------------|
|認証(Authentication)| IDやパスワードなどでユーザーとシステム間での本人性を検証 |
|認可(Authorization)| ユーザーとシステム間の処理を行うことを許可すること |

これをぱっと見たとき、両方とも"認"から始まってるし"Auth〜"みたいな感じなので理解が難しい部分もあるかと思いますが、色々な紹介サイトがあると思いますのでそちらを参照いただければと思います。

一部事例を紹介させていただきます。
[認証と認可の違い ゼロトラストセキュリティ対策 | SailPoint](https://www.sailpoint.com/ja/identity-library/what-is-the-difference-between-authentication-and-authorization/)

また以下の図を参照すればトークンとAPI含めた内容をご理解いただけるかと思います。

![スクリーンショット 2023-12-18 20.59.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71229/77c6dfd4-dad9-5b61-5976-3bd111bcafc6.png)


### 一般的に広く使われている認証の方式

上図でもご紹介しましたが、認証においてJWT(JSON Web Token)を使用した標準プロトコルが存在しており、自己完結型のトークンを用いることで通信などにおいても非常に効率のよい認証が再現できます。

概要
[RFC 7523 - JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants](https://datatracker.ietf.org/doc/html/rfc7523)

そして代表的な以下製品・OSSはその動作を担保しております。

Auth0
[JSON Web Tokens](https://auth0.com/docs/secure/tokens/json-web-tokens)

Amazon Cognito
[JSON Web トークンの検証 - Amazon Cognito](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html)

KeyCloak
[Server Developer Guide](https://keycloak-documentation.openstandia.jp/7.0.0/ja_JP/server_development/index.html#_client_authentication)

## 認可フロー
OAuth2.0には認可フローという概念が存在しておりまして、RFC6749においては5つのフローが定義されております。

[The OAuth 2.0 Authorization Framework](https://openid-foundation-japan.github.io/rfc6749.ja.html)

| フロー | トークンエンドポイント |
|:-----------|:------------|
| 認可コード<br>Authorization Code | あり |
| インプリシット(暗黙)<br>Implicit | リフレッシュトークンの発行なし |
| リソースオーナー・パスワード・クレデンシャルズ<br>Resource Owner Password Credentials | あり |
| クライアント・クレデンシャルズ<br>Client Credentials | あり |
| リフレッシュトークン<br>Refresh Token | アクセストークン |

### 認可フローはわかったが結論どうなのよ

Authorization Code with PKCEがファーストチョイスかなと考えます。
(PKCEなんて聞いてない)

業務システムにおいてはスマホアプリなどの要件もあり、その際パブリッククライアントからのトークンリクエストがありえる上にシングルページアプリケーション（SPA）からトークンを要求する場合などを想定して作られたインプリシットフローですが、現在は認可コードフロー+PKCE（Proof Key for Code Exchange）が推奨されております。
故に業務システムにおいてもAuthorization Code with PKCEとなります。

こちらに関してはAuthlete共同創業者の川崎氏がすごく詳細なフローの記載をされております。
[OAuth 2.0 全フローの図解と動画 #OAuth - Qiita](https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f)


# これまでの内容を業務アプリケーションに置き換えてみる
半ば強引ではありますが、これまでの内容を踏まえて業務アプリケーションをマイクロサービスで表現してみましょう。
今回はマルチテナントアーキテクチャで構成された購買管理(MM: Material Management)を例に考えてみます。
必要な機能としては以下の図のようなものになるかと思います。
![スクリーンショット 2023-12-19 1.08.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71229/f0d5749f-fcfc-00fc-e0fe-bb02bc6a963c.png)
いくつかトピックを抜粋すると、

- 運営者、顧客双方ともに同認証を利用し、認可をエンドポイントで制御する
- 顧客ごとに取引先、得意先、供給先、購買品目が存在する
- 自社ユーザーの権限(認可)については各顧客テナントで操作できるようにする

とはいえここまで単純なケースはまずないと言ってもよく、これに申請・承認フローシステムや会計システムが関与することが往々にして起こりえます。

上記を踏まえると以下のケースを検討することができると思います。
![スクリーンショット 2023-12-19 1.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71229/64672e56-51b9-2f2c-63c2-fd1b0f2f8876.png)
リソースや権限管理と購買に関わる行為を分断化した仕組みになります。
責務としてわかりやすい分け方でありますし、ドメイン知識など企業において分散させると面倒なこともない非常に安直かつ効果的な仕組みかと存じます。

購買品目からレコメンドを行うなどの要件がある際にも購買品目マイクロサービス(Read Only)を検索エンジンシステムを利用し構築するケースなどさらなる細分化も容易に可能となります。

無論このケースにおいてはこちらが最適解というわけではなく、様々な思想により無数の構成があるかと思います。
あくまで参考程度にとどめていただけますと幸いです。

# 最後に
これまでマイクロサービスとは?と言う部分から認証認可またそのフローおよび使用例について記載しましたが、実際にOSSなどを動かしつつ体験する部分までたどり着くにはもう少し理解が必要になると思います。
業務システムにおいてもWebアプリケーションやSaaSの担う部分が増えSPAなどで構成されたステキなサービスも数多くあります。
それらがどのように構成されているか少しでも理解が進み皆さんのディスカッションのネタになればと思い記載させていただきました。


# その他の関連記事・書籍
オライリー・ジャパン マイクロサービスアーキテクチャ Sam Newman 著