web-dev-qa-db-ja.com

クロスドメイン認証にJWTを使用したシングルサインオンフロー

Webには、認証にJWT(Json Web Token)を使用することに関する多くの情報があります。しかし、複数ドメイン環境でのシングルサインオンソリューションにJWTトークンを使用する場合、フローがどうあるべきかについての明確な説明はまだ見つかりませんでした。

私は、異なるホストに多くのサイトがある会社で働いています。 example1.comexample2.comを使用してみましょう。シングルサインオンソリューションが必要です。つまり、ユーザーがexample1.comで認証する場合、ユーザーも認証されるexample2.com、自動的に。

OpenId Connect フローを使用すると、example1.comで認証したいユーザーが最初にリダイレクトされることを理解しています認証サーバー(またはOP: "OpenId Provider")。ユーザーはそのサーバーで認証され、署名されたJWTトークンを使用して元のexample1.comサイトにリダイレクトされます。 (中間トークンを返す別のフローがあることを理解していますが、それ自体は後で実際のJWTトークンと交換できますが、これは私たちにとって必要ではないと思います)...

これで、ユーザーはexample1.comに戻り、認証されました! JWTトークンをAuthenticationヘッダーに渡すことで要求を行うことができ、サーバーは署名されたJWTを検証できるため、ユーザーを識別できます。いいね!

最初の質問:

JWTトークンはどのようにクライアントに保存する必要がありますか?これについても多くの情報があり、人々はWeb Storageを使用することが古き良きcookiesではなく進むべき方法であることに同意しているようです。ブラウザの再起動間でJWTを永続的にしたいので、Local StorageではなくSession Storageを使用しましょう。

これで、ユーザーはブラウザを再起動できますが、JWTトークンの有効期限が切れていない限り、ユーザーはexample1.comで認証されます!

また、example1.comが別のドメインにAjaxリクエストを行う必要がある場合、 CORS の設定が理解できますそれを許可します。しかし、主な使用例はクロスドメインリクエストではなく、シングルサインオンソリューション!です。

したがって、主な質問:

ここで、ユーザーがexample2.comに移動し、すでに持っているJWTトークンを使用して認証されるようにしたい場合、フローはどうでしょうか? Local Storageはクロスドメインアクセスを許可していないため、この時点でブラウザはJWTトークンを読み取ってexample2.com

する必要があります:

  • ユーザーは認証サーバーに再度リダイレクトされますか?ユーザーがexample1.comに対して認証された場合、認証サーバーはユーザーにCookieを設定して、このexample2.comの新しい認証要求がそのCookieを使用してユーザーが既に認証されていることを確認し、すぐにリダイレクトしますtoexample2.com同じJWTトークンで?
  • または、ブラウザは、example2.comで、認証サーバーにアクセスせずにJWTトークンにアクセスできますかもう一度? ストレージ間ソリューション がありますが、それらは広く使用されていますか?クロスドメインSSO環境に対する推奨ソリューションですか?

派手なものは何も必要ありません。私たちは、主に使用されているソリューションに満足しています。

93
electrotype

ユーザーは再び認証サーバーにリダイレクトされ、example2.comを特にターゲットとする新しいトークン(JWT)を取得する必要があります。これが、OpenID Connectおよび他のクロスドメインフェデレーションSSOプロトコルの仕組みです。

23
Hans Z.

ユーザーがログインしていないときに中央認証サービスにユーザーをリダイレクトして資格情報を要求し、新しい認証トークンを発行することは、oauth2やOpenIdConnectなどの既知のプロトコルを使用するシングルサインオンシステムの一般的なシナリオです

ただし、このスキーマがクロスドメイン間で使用される場合、主な欠点は、同じ起源ポリシーによりユーザーが他のドメインに移動するたびに認証されることです:セッショントークンは共有できませんそのため、SSOはユーザーを認証されていないものとして扱います。

example2.comexample1.comのデータにアクセスできませんが、ブラウザのlocalStorage/cookiesと中間ドメインを指すiframeを使用してドメイン間でデータを共有する技術がありますsso.example.com

  1. example1.comでユーザーを認証するには、sso.example.comで認証サーバーにリダイレクトし、認証後にJWTを発行して、このドメインのlocalStorageに保存します。この後、ユーザーをオリジンドメインexample1.comにリダイレクトします

  2. example2.comを指すsso.example.comにiframeを作成します。 sso.example.comのiframeはJWTトークンを読み取り、親ページにメッセージを送信します

  3. 親ページはメッセージを受信し、SSOフローを続行する添付トークンを取得します

sso.example.comはlocalStorageにアクセスでき、Originと宛先がお互いを認識する場合、iframeと親ページ間の通信が許可されるため、same-Originポリシーに問題はありません( http:// blog。 teamtreehouse.com/cross-domain-messaging-with-postmessage

開発を簡素化するために、最近リリースしましたクロスドメインSSOとJWT https://github.com/Aralink/ssojwt

この方法は、SSOフローと完全に互換性があります。これは、リダイレクトなしで認証トークンを共有し、ドメインがフェデレーションされたときに不要なログインを回避するための単なる方法です

22
pedrofb

これが質問に答えるかどうかはわかりませんが、主な目標がシングルサインオンの場合、単純な リバースプロキシ が問題を解決すると思います(少なくともクロスドメインストレージの問題)。

したがって、example1.com example2.com

のようなものになるだろう

example.com/example1

example.com/example2

(そして、ユーザー側からは、これは通常きれいです)

それがオプションではない場合、ユーザーが1つのドメインで認証するときに、AJAX /非表示のiframeを使用して他のドメインとの認証も作成するように設定する必要がある場合があります)。

そして、それがオプションではない場合、ブラウザはクロスドメイン相互作用についてより厳格になっているため、ユーザー名+ピンに頼る必要があるかもしれません。

2
Tezra