この記事では、認証に関する関連知識を提供します。主に、マイクロサービスでの認証の実装アイデアを紹介します。これを達成するための良い解決策はありますか?一緒に見てみましょう。皆さんのお役に立てれば幸いです。
最近たまたま友達が WeChat でこの質問をしてきたので、あなたとチャットするために来ました。この記事は主に、コードを書かずに友達とアイデアについて話します。以前の記事と組み合わせることができます。この記事のコードは自分で書けるはずです。もちろん、これらのアイデアは私自身の実践的な経験にすぎず、最も完璧な解決策ではない可能性があります。友達とコメントで議論することは歓迎です。
まず第一に、友達は、Shiro と Spring Security のどちらを勉強しても、どのような機能があるとしても、2 つのコアがあることを知っています。
Authentication
Authorization
したがって、マイクロサービスでの認証の問題に対処し、これらを使用することもできます。考慮すべき 2 つの側面。
認証とは、端的に言えば、ログインを意味します。従来の Web ログインはサーバーのローカル メモリに依存する Cookie セッション ソリューションですが、マイクロサービスではサービスの数が多いため、このソリューションは明らかに適していません。
セッション共有に Redis SpringSession を使用するという友人もいるかもしれませんが、これは 1 つの方法ではありますが、このソリューションのパフォーマンスとスケーラビリティは比較的低いため、最適なソリューションではありません。
したがって、マイクロサービスでの認証にはトークンを使用することが推奨されており、現在一般的に使用されている JWT トークンを選択することもできます。ただし、JWT に詳しい友人は、純粋なステートレス ログインではログアウトが実現できず、非常に面倒であることを知っているため、実際のアプリケーションでは、単に JWT を使用するだけでは十分ではなく、生成された JWT を変換するには Redis と組み合わせる必要があります。文字列も Redis に保存され、有効期限が設定されます。ユーザーがログインしているかどうかを判断するときは、まず JWT 文字列が Redis に存在するかどうかを確認する必要があります。存在する場合は、JWT 文字列を解析します。正常に解析できれば問題ありませんが、正常に解析できない場合は、トークンが不正であることを意味します。
ステートフル ログインとステートレス ログインを混合するこの方法は、少し平凡に見えるかもしれませんが、現時点では、この妥協案が実現可能な解決策であると考えられています。
実際、上記のソリューションは、率直に言って、従来の Cookie セッションと何ら変わりません。アイデアはほぼ完全にコピーされています。従来のセッションは Redis に置き換えられ、従来のセッション間のシャトルは、サーバーとブラウザの間の jsessionId は JWT 文字列に置き換えられます。従来の jsessionId は Cookie を通じて送信され、現在の JWT は開発者が手動で設定した後、リクエスト ヘッダーを通じて送信されます。従来のセッションは自動的に更新されますが、現在、JWT を使用して手動で更新しています。最初のリクエストがサーバーに到達したら、Redis 上のトークンの有効期限を確認します。有効期限が切れそうになっている場合は、リセットします。その他はすべてまったく同じです。
これは認証スキームの選択です。
マイクロサービスでの承認は、Shiro または Spring Security フレームワークを使用して実行することもできるため、手間が省けます。マイクロサービス テクノロジ スタックが Spring ファミリーの製品であることを考慮すると、最初は権限フレームワークの観点から Spring Security を選択することをお勧めします (Spring Security に詳しくない友人がいる場合は、WeChat のバックグラウンドで SS に返信できます)公式アカウント、チュートリアルあり)。
もちろん、Spring Security がより複雑だと思っていて、自分でやりたい場合は、それを行うことができます。自分で行う場合は、Spring Security のアイデアを使用することもできます。Song Ge の最近のプロジェクトの 1 つは次のようなものです:
リクエストがマイクロサービスに到達したら、まず現在のユーザーに関するさまざまな情報を検索します。現在のユーザーが所有するロールや権限などの情報は、現在のスレッドにバインドされている ThreadLocal オブジェクトに保存されます。一方、権限アノテーションとロール アノテーションをカスタマイズし、これらのアノテーションを側面で解析し、現在のユーザーが必要なロール/権限などを持っているかどうかを確認します。
もちろん、Spring Security を使用している場合は、上記のカスタム アノテーションは必要ありません。Spring Security に付属しているアノテーションをそのまま使用できます。また、Spring Security の機能をさらに充実させることもできます。 。 安全機能。
では、認証と認可はどこで行われるのでしょうか?
まず認証について話しましょう。認証は単純に 2 つのステップに分けることができます:
ログイン
検証
一般的に、ログイン用に別の認証サービスを実行できます。 ログイン要求がゲートウェイに到達すると、認証サービス に転送して認証操作を完了します。
認証サービスでは、ユーザー名/パスワードが正しいかどうか、ユーザーのステータスがOKかどうかを確認し、問題がなければJWT文字列を生成すると同時にRedisにデータを格納します、その後、JWT 文字列が返されました。
システムに登録機能がある場合、登録機能もこのマイクロサービス上で完結します。
検証とは、各リクエストが到着したときにユーザーがログインしているかどうかを検証することを指します。
もちろん、これは 2.1 と一緒に実行できますが、Brother Song はそれをお勧めしません。問題は、注文を作成するリクエストの場合、このリクエストは本来ゲートウェイを介して注文サービスに転送されるが、このとき、ログイン検証のためにゲートウェイ上でセクション 2.1 のサービスを呼び出す必要があることです。問題ありません。注文サービスの観点から、これは明らかに非常に時間がかかり、不合理です。
より良い方法は、要求されたトークンがゲートウェイ上で正当であるかどうかを直接検証することです。この検証自体は比較的簡単です。トークンが正当であるかどうかを検証するには、トークンが Redis 上に存在するかどうかを確認するだけです。 JWT トークンが正常に解析できる限り、この操作はゲートウェイ上で実行できます。
ゲートウェイを例に挙げると、グローバル フィルターをカスタマイズし、グローバル フィルター内の各リクエストのトークンを検証できます。検証に合格した場合、リクエストは転送され、そうでない場合は転送されません。
検証に合格し、特定のマイクロサービスに転送した後、解析されたユーザー ID、ユーザー名、その他の情報をリクエスト ヘッダーに入れて、特定の各マイクロサービスに到達するように転送できます。誰がリクエストを送信したか、そしてその人がどのような役割/権限を持っているかがわかるので、次の手順の権限検証を行うことができます。
Song Ge が行ったのはパブリック モジュールの定義です。すべてのマイクロサービスはこのパブリック モジュールに依存します。このパブリック モジュールにはインターセプターが定義されており、すべてのリクエストをインターセプトします。リクエスト ヘッダーからユーザーを取得します。 Redis から ID を取得し、Redis から特定のユーザー情報を取得して ThreadLocal に保存することで、後続のメソッド呼び出しで、ユーザーが特定の権限を持っているかどうかを判断する必要がある場合に、ThreadLocal を通じて取得できます。
大まかなプロセスは次のとおりです。
認可はゲートウェイでは実行できず、各マイクロサービスで実行する必要があります。
マイクロサービスに対する承認は、大きく 2 つのカテゴリに分類できます:
フロントエンドから送信されるリクエスト (外部リクエスト)。
他のマイクロサービスから送信されたリクエスト (内部リクエスト)。
外部リクエストの場合は、通常の権限検証、カスタム アノテーション、または Spring Security などのフレームワークに従って処理してください。カスタム アノテーションを AOP と組み合わせて、パーミッション アノテーションを自分で処理するためのアスペクトを定義できます。もちろん、これらの関数は基本的にすべてのマイクロサービスに必要なので、パブリック モジュールに抽出できます。別のマイクロサービスで依存するだけです。
内部リクエストの場合、通常は認証は必要なく、内部リクエストを直接処理できます。問題は、OpenFeign を使用すると、データがインターフェースを通じて公開されることです。認証がないと、外部リクエストがこのインターフェースを呼び出すのではないかという懸念があります。この問題に対して、アノテーション AOP をカスタマイズして、の場合は、それを区別するために追加のヘッダー フィールドを追加します。
もちろん、内部リクエストがマイクロサービスに到達するときも、認証が必要です。リクエストがゲートウェイから特定の各マイクロサービスに転送されるときと同様に、認証が必要ですが、明らかに必要ありません。 OpenFeign が他のサービスを呼び出すときは、毎回それを使用する必要があります。OpenFeign は他のサービスを呼び出すときに、大量の認証情報を渡します。feign.RequestInterceptor
インターフェイスを実装することで、OpenFeign リクエスト インターセプターを定義できます。インターセプターでは、リクエストは均一に設定されますOpenFeign リクエストのヘッダー情報。
わかりました。マイクロサービスでの認証に関しては、これが現在私たちが行っている方法です。友達はメッセージを残して一緒に議論することを歓迎します。
推奨学習: 「小プログラム ビデオ チュートリアル」「Java ビデオ チュートリアル」
以上がマイクロサービス認証の実装方法を詳しく説明した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。