はじめに
こんにちは、読者の皆様。 私は長い間、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つの関係者が関与します。
- SAML IDプロバイダー(IdP)
- SAMLサービスプロバイダー(SP)
- ユーザーブラウザ
相互作用スキーム自体を次の図に示します。
相互作用の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に取得し、メッセージから電子メールを取得し、このドメインの証明書を取得して、メッセージを検証します。 検証に成功した場合、メッセージFirstName 、 LastNameから属性を取得します。 ユーザーが既に存在する場合、サービスのこれらの属性の値を変更します。 ユーザーがまだ作成されていない場合は、作成します。
これは、いわゆるジャストインタイムプロビジョニングです。 これは、最も簡単なユーザープロビジョニング(同期)実装です。 このような同期の欠点は、次のユーザーログインまでの実行の遅延です。 さらに、IdPからユーザーを削除するときにサービス側でユーザーを削除できないこと。 サービスでプロビジョニングを完全に開始するには、 SCIM標準を実装する必要がありますが、まだこれを行っていません-これが次の話になるでしょう。
この記事がお役に立てば幸いです。