マイクロサービス アーキテクチャ - サービス ゲートウェイ (ゲートウェイ) - 認可認証 (分散セッション代替)

認可認証 - 分散セッションの代替

前にゲートウェイ コンポーネントのフィルターについて学習しましたが、このセクションでは、分散環境におけるゲートウェイの具体的な使用例、つまりユーザー認証について説明します。

1. 従来の単一アプリケーションのユーザー認証

私たちは JavaEE を学び始めて以来、ログイン成功後にキーと値のペアをセッションに保存するなど、ユーザーのログイン状態を HttpSession に保存するという権限検証の標準的な方法に洗脳されてきました。 、keyはuserld、valueはユーザー背景の実際のIDです。

次に、アクセスするためにログインする必要があるリソースをインターセプトする ServletFilter フィルターを作成します。このリクエストに対応するサーバー セッションでキー userld が見つからない場合は、ユーザーがログインしていないことを意味します。このとき、直接サービスを拒否し、ユーザー ログイン ページにリダイレクトします。

誰もがセッション メカニズムについてよく知っているはずです。セッション メカニズムと Cookie は相互に依存しています。Cookie はユーザーのブラウザに保存される情報であり、セッションはサーバー側に保存されます。ブラウザがサービス リクエストを開始すると、Cookie が送信され、サーバーはリクエストを受信した後、Cookie 内の jsessionid に従って対応するセッションを取得します。

サーバーを 1 つだけ起動するため、ログイン後に保存されたセッションは常にこのサーバーにあり、セッション内のすべての情報を簡単に取得できます。この方法を使用して、これまでにさまざまな授業や卒業プロジェクトを完了してきました。仕事に取り掛かってみると、すべてのアプリケーションがクラスターにデプロイされており、1 台のマシンに保存されたセッションを他のマシンに同期できないため、それは実現不可能であることがわかりました。

2. 分散環境におけるソリューション

2.1) 同期セッション

セッション レプリケーションは、最初に考える最も簡単なソリューションです。あるマシンのセッションをクラスタ内の他のマシンにコピーできます。

たとえば、Tomcat にもセッション同期ソリューションが組み込まれていますが、これはあまり洗練されたソリューションではなく、次の 2 つの問題が発生します。

タイミングの問題:同期にはある程度の時間がかかり、セッション同期の適時性は保証できません。つまり、ユーザーが開始した 2 つのリクエストが異なるマシンに到達した場合、前のリクエストによってセッションに書き込まれた情報が反映されない可能性があります。すべてのマシンに同期されている後者のリクエストはすでにビジネス ロジックの実行を開始しているため、必然的にダーティ ファントム読み取りが発生します。

データの冗長性:すべてのサーバーはセッションの完全なセットを保存する必要があるため、大量の冗長データが生成されます。

2.2) リバースプロキシ: バインド IP または一貫したハッシュ

このソリューションは、Nginx ゲートウェイ層で実行できます。特定の IP セグメントに対するリクエストが指定されたマシンに送信されるように指定できるため、セッションは常に 1 台のマシン上にのみ存在しますが、以前のセッション レプリケーションの方法と比較すると、バインディング IP にはさらに明らかな欠陥があります。

負荷分散: IP をバインドする場合、負荷分散戦略はゲートウェイ層では適用できず、サーバーに障害が発生すると、指定された IP セグメントの訪問ユーザーに大きな影響を及ぼします。この方式のルーティング ルールの設定も非常に面倒です。

IP の変更:多くのネットワーク オペレータはユーザー IP を時々切り替えるため、IP 変更後のリクエストは処理のために別のサービス ノードにルーティングされるため、以前に設定されたセッション情報を読み取ることができなくなります。

2 番目の問題を解決するには、ユーザー ID に従ってハッシュを実行するなど、一貫したハッシュ ルーティング スキームを通じてルーティングを実行できます。また、異なるハッシュ値が異なるマシンに割り当てられることで、十分に均等な分散が確保され、IP アドレスの漏洩が回避されます。スイッチングの問題は解決できますが、最初の点で述べた負荷分散の問題はまだ解決できません。

2.3) Redis ソリューション

このソリューションにより、上記の問題のほとんどが解決され、セッションはサーバーに保存されなくなり、代わりに redis に保存され、すべてのサーバーがキャッシュ情報を redis に書き込み/読み取ります。

Tomcat レベルでは、tomcat-redis-session-manager コンポーネントに直接入力して、コンテナ レベルのセッション コンポーネントを Redis ベースのグループに置き換えることができますが、このソリューションはコンテナに密接にバインドされています。

もう 1 つのより洗練されたソリューションは、Spring-session を使用して Redis でセッションを管理することです。この方式は特定のコンテナから分離されていますが、依然としてセッションベースのユーザー認証方式であり、マイクロサービス アプリケーションではこの種のセッション方式は排除されています。

2.4) 分散セッションの代替手段

セッションを後にして、2 つの一般的な認証方法を見てみましょう。

2.4.1)OAuth 2.0

誰もが一般的なサードパーティ ログインを使用したことがあるはずです。たとえば、WeChat で QR コードをスキャンすることでアプリケーションのオンライン システムにログインできますが、このアプリケーションは私の WeChat のユーザー名とパスワードを知りません。これは最初の部分です。認証スキーム - OAuth 2.0 を紹介します。

OAuth 2.0 はオープンな認証標準プロトコルであり、これを使用すると、ユーザーはサードパーティ アプリケーションがサービス内のユーザーの特定のプライベート リソースにアクセスできるようになりますが、アカウントとパスワードの情報はサードパーティ アプリケーションに提供されません。

上の例では、WeChat はサードパーティ アプリケーションに相当します。WeChat 経由でサードパーティ アプリケーションにログインする例として OAuth 2.0 を使用します。
ここに画像の説明を挿入

  • 認証許可:このステップでは、CIient は WeChat システムへの許可リクエストを開始し (たとえば、WeChat でコードをスキャンして許可することにより)、ID 検証が成功した後に認証許可を取得します。
  • トークンの取得:クライアントは WeChat から取得した認証許可を取得し、トークンと引き換えにサードパーティが参照する認証サービスに送信します。トークンは、サードパーティのアプリケーション リソースにアクセスするために必要なトークンです。
  • リソースへのアクセス:最後のステップでは、クライアントはリソースを要求するときにトークン トークンを取得し、サーバーはトークンが真で有効であることを確認した後、指定されたリソースを返します。

spring-cloud-starter-oauth2Spring Cloud の組み込みコンポーネントを使用して OAuth 2.0 認証サービスを構築できますが、OAuth 2.0 プロトコルには、ロール、クライアント タイプ、認可モードなどの多くの複雑な仕様も含まれていますこのセクションでは、当面 OAuth 2.0 の実装については詳しく説明しませんので、まず別の軽量な認証スキームである JWT 認証について見てみましょう。

2.4.2) JWT認証

JWT もトークンベースの認証メカニズムであり、その基本的な考え方は、ユーザー名とパスワードをアクセス トークンと交換することです。

2.4.2.1) 認証プロセス

OAuth 2.0 と比較して認証プロセスが簡素化されており、基本的な流れは次のとおりです。

1. ユーザー名+パスワードによるアクセス認証サービス

  • 検証に合格した: サーバーはアクセス トークンをクライアントに返し、その後のアクセス制御のためにサーバー上のどこかにトークンを保存します (データベースまたは Redis に保存できます)。
  • 検証に失敗しました: トークンが生成されませんでした。

2. クライアントはトークンを使用してリソースにアクセスし、サーバーはトークンの有効性を検証します。

  • トークンが間違っているか、期限切れです。リクエストをインターセプトし、クライアントにトークンを再申請させます。
  • トークンは正しいです: リリースは許可されます
2.4.2.2) アクセストークンの内容

JWT のアクセス トークンは、ヘッダー、ペイロード、署名の 3 つの部分で構成されており、これら 3 つの部分にどのような情報が含まれているかを見てみましょう。

ヘッダー:ヘッダーはトークンのタイプ (JWT タイプ) と暗号化アルゴリズム (HS256) を宣言します。

{
  'typ': 'JWT',
  'alg': 'HS256'
}

**ペイロード:** この段落には非常に多くの情報が含まれています。トークン発行者、発行と有効期限、有効時間などの一連の属性を定義でき、またカスタム属性を追加することもできます。同様のことが次の場合にも実行できます。サーバーはトークンを受信します ペイロードに含まれる情報を確認します たとえば、特定のトークンの発行者が「Feign-API」である場合、特定のインターフェイスが「Gateway-API」によって発行されたトークンのみを許可する場合は、それを使用できます認証サービス用に発行者の判定ロジックを追加します。

署名:ヘッダーとペイロード、およびキーを使用してビザ情報を生成します。このステップでは、ヘッダーで指定した暗号化アルゴリズムを使用して暗号化します。

現在、JWT を実装するオープン ソース コンポーネントが多数あります。このソリューションを使用する場合は、オープン ソースの JMT 実装の依存関係をプロジェクト内の POM ファイルに追加し、このコンポーネントを呼び出して暗号化と暗号化を完了するだけです。復号化。

おすすめ

転載: blog.csdn.net/jianghao233/article/details/130055847