例付きのSAMLを介したSSO実装

はじめに







こんにちは、読者の皆様。 私は長い間、Habréに関する記事を書きたいと思っていましたが、ついにこの瞬間が訪れました。 私が扱った最後のトピックについて、これはrealtimeboard.comサービスへのSSOの実装でした-これは、リモートチームが1か所でコラボレーションするための素晴らしい製品であり、常に開発および改善したいと考えています。 ここですぐに明確にしたいのは、原則として、FacebookとGoogleを介したSSOは、私が到着する前にすでにサービスに入っていたことです。 私のタスクは、SAMLプロトコルを介して実装することでした。







SSO( シングルサインオン )は、ユーザーのシングルサインオンのテクノロジーです。これにより、ユーザーは1つのアカウントだけで、多くの異なるサービスにアクセスできます。







SAMLは、SSOを実装するための一般的なXMLプロトコルです。 原則として、大規模な組織(エンタープライズ)は、実績のある信頼できるオプションとしてそれを使用します。







私たちのサービスでは、この機能の出現は、まさにエンタープライズ顧客からの実装の頻繁なリクエストによるものでした。 このような顧客は、最新のユーザーベースを集中管理し、独自のセキュリティポリシーなどを導入します。 したがって、サービス内のコンテンツへのアクセスはより安全になり、制御されます。







技術的な詳細







執筆時点では、標準の最新バージョンはSAML 2.0です。 この標準はXMLに基づいています。つまり、XMLのw3c標準のすべての要件もXMLに適用できます。忘れないでください。 そのため、たとえば、実装時に1つの間違いを見つけました。 AuthnRequestの作成時に、 ID属性の一意の文字列識別子を生成したため、要件に応じて数字で始まるべきではありませんが、時々そのようになりました。







SAML SSOを介した認証には3つの関係者が関与します。









相互作用スキーム自体を次の図に示します。







画像






相互作用の2つの主なケースがそこから取得されます。







オプション1。ユーザーはサービスにアクセスします。 サービスはAuthnRequestメッセージを生成し、それをSAMLRequestパラメーターに入れ、ブラウザーを介して認証が行われるログインURLのプロバイダーにリダイレクトし、プロバイダーは応答メッセージを生成し、 SamlResponseパラメーターに入れて、 ACS URLのサービスにリダイレクトします







オプション2。ユーザーは既に認証されており、プロバイダーのダッシュボードにあり、そこからショートカットをクリックしてサービスにアクセスできます。 この状況では、プロバイダーはすぐに応答メッセージを生成し、それをSamlResponseパラメーターに入れて、 ACS URLのサービスに送信します







ACS URL(Assertion Consumer Service URL) -SamlResponseパラメーターを使用して要求を受け入れ、それを処理し( 応答メッセージを引き出し、証明書の署名を検証し、さまざまなルール)、すべてがうまくいけば、アプリケーションでユーザーの作業セッションを作成するアプリケーション側のURL。







IdPログインURL-プロバイダー側​​のURL。SAMLRequestパラメーターを使用して要求を受け入れ、このパラメーターを適切に検証します。すべてが問題なければ、認証フォームに送信します。







OneLogin、LastPass、Oktaなどのオンラインサービスの1つは、IdPプロバイダーとして機能できます。 Shibbolethを使用してIdPを展開するか、ADを上げることもできます。







設定







この相互作用のすべてのパラメーターは、両側(IdP、SP)で構成および保存する必要があります。つまり、信頼関係を構築する必要があります。







SPは、IdPを発行する証明書と、 SAMLRequestを送信するSamlログインURLを保持する必要があります







IdPには、ホストされるアプリケーション用にホストされるACS URLが必要です...







画像

... 証明書を生成し、暗号化アルゴリズムを選択し、サービスのSamlログインURLを提供する必要があります...







画像

...(必要な場合)特定のサービスのユーザー属性またはその他のカスタムフィールドを構成する必要があります。 サービスプロバイダーは、 サブジェクトのNameID形式にも同意する必要があります。 これは基本的にユーザーの識別子であり、その情報はメッセージで送信されます。 私たちの場合、これはメールです。







画像

手動設定に加えて、SPとIdPは、「同僚」に必要なすべてのパラメーターを含むメタデータファイルを生成できるため、設定を自分で読み込んで設定できます。 そのような仕事はありませんでした。







さらに、プロバイダーはSSOに加えて、オプションでSLO(シングルログアウト)サービスも提供します。これは、すべてのサービスをすぐに同時に終了するメカニズムです。 2つのエントリポイントも可能です。









これを行うには、 SP SLO URLリクエストの処理と、サービス側のIdP SLO URLへのリクエスト送信をサポートする必要があります 。 私もそのような仕事を持っていませんでした。







リサーチ







それで、タスクが設定され、理論に精通しました。今から始めましょう。 まず、利用可能なライブラリのリストを知りました。 私たちのサービスのバックエンドはJavaで書かれており、私はそれ専用のライブラリを探していました。 SAML関連製品の最も完全なリストは、 ここにあります 。 私にとって最も明白なソリューションを選択しました:Okta SAML Toolkit for Java、SpringSecurity SAML、OIOSAML 2.0 Toolkit、lastpass / saml-sdk-java、OneLogin 2.0、OneLogin 1.1.2、OpenSAML 2.0。 次に、このソリューションまたはそのソリューションを選択する基準を決定する必要がありました。 そのため、次のがコンパイルされました。







正直なところ、提案されたソリューションのソースコードは恐ろしいものでした-有名なプロバイダーは高レベルのアプリケーションライブラリを作成することを決定しました(うまく機能しませんでした)。 これらすべてのライブラリを何らかの方法で編集し、ロジックのニーズを高め 、すべてのユニットテストでメインコードに埋め込む必要があることを考えると、 OpenSaml 2.0の形式で既存のベースを使用し、その上に高レベルのロジックを記述することも決定されました。 おそらくSpringがあれば、私はSpringSecurity SAMLを使用するでしょうが、持っていません。







一般に、チームでさらに議論するために、すべての考えとソリューションのオプションをサービスに記載します。下の画面を見るか、「ライブ」 ボードに行くことができます。







画像

合計、ソリューションが選択され、動作が定義されます。







実装







上記のスクリーンショットからわかるように、テスト用のIdPとして、OneLoginを選択しました。 無料の開発者アカウントを提供し、それを使用してテストアプリケーションをセットアップするのが最も簡単でした。また、作業を容易にするSAMLを操作するためのユーティリティセットも含まれています。 完全に設定可能なIdPが必要ない場合は、このシンプルなユーティリティまたはOktaの アナログを使用できます。 私もそれらを使用しました。







最初に、この技術をテストするためのテストローカルアプリケーションを作成しました。原則として、そのソースを紹介します。 その後、彼はこのソリューションを産業用コードベースに移行しました。 アプリケーションロジックはシンプルで、あらゆるサービスに適用できます。 このドメインに対してSAML SSOが設定されていない場合、アプリケーションはユーザーにメールを入力するように求めます。アプリケーションはユーザーの内部パスワードを要求します(この例では、ユーザーはSSOできないことを誓います)。 設定されている場合は、このドメインが設定されているIdPを確認し、メッセージを作成してリクエストをそこにリダイレクトします。 認証が成功すると、生成されたメッセージをIdPからACS URLに取得し、メッセージから電子メールを取得し、このドメインの証明書を取得して、メッセージを検証します。 検証に成功した場合、メッセージFirstNameLastNameから属性を取得します。 ユーザーが既に存在する場合、サービスのこれらの属性の値を変更します。 ユーザーがまだ作成されていない場合は、作成します。







これは、いわゆるジャストインタイムプロビジョニングです。 これは、最も簡単なユーザープロビジョニング(同期)実装です。 このような同期の欠点は、次のユーザーログインまでの実行の遅延です。 さらに、IdPからユーザーを削除するときにサービス側でユーザーを削除できないこと。 サービスでプロビジョニングを完全に開始するには、 SCIM標準を実装する必要がありますが、まだこれを行っていません-これが次の話になるでしょう。







この記事がお役に立てば幸いです。








All Articles