OpenID Connectを使用したElastic Stackのシングルサインオンの設定

Elastic Stackは、Kibanaを介してOpenID Connectを使用したシングルサインオン(SSO)をサポートしており、Elasticsearchはほとんどの機能を保持するバックエンドサービスです。KibanaとElasticsearchは、OpenID Connect仕様で定義されている認可コードフローと暗黙的フローをサポートするOpenID Connect依存パーティ(RP)を表します。

このガイドでは、Elastic Stack依存パーティが登録されるOpenID Connectプロバイダーがあることを前提としています。

KibanaのOpenID Connect領域サポートは、そのKibanaインスタンスのユーザーにとって主要な認証方法になることを期待して設計されています。Kibanaの設定セクションでは、これが何を意味するのか、必要に応じて他の領域をサポートするためにどのように設定できるかについて説明しています。

OpenID Connectプロバイダー

OpenID Connectプロバイダー(OP)は、OpenID Connectにおいてユーザーを認証し、依存パーティが使用するための認証およびユーザー情報を含む必要なトークンを付与する責任を持つエンティティです。

Elastic Stackが認証のためにOpenID Connectプロバイダーを使用できるようにするには、OPとRPの間に信頼関係を確立する必要があります。OpenID Connectプロバイダーでは、これによりRPをクライアントとして登録することを意味します。OpenID Connectは動的クライアント登録プロトコルを定義していますが、これは通常、リアルタイムのクライアント登録に向けられており、クロスセキュリティドメインのシングルサインオンのための信頼確立プロセスには向いていません。すべてのOPは、ユーザーインターフェースを介して、または(あまり一般的ではありませんが)メタデータドキュメントの消費を介して、RPをクライアントとして手動で登録することも許可します。

Elastic Stack RPを登録するプロセスは、OPによって異なり、プロバイダーの関連ドキュメントに従うことが賢明です。登録のために一般的に提供する必要があるRPの情報は次のとおりです:

  • Relying Party Name: 依存パーティのための任意の識別子。この値に対しては、仕様やElastic Stackの実装は制約を課しません。
  • Redirect URI: これは、OPが認証後にユーザーのブラウザをリダイレクトするURIです。この適切な値は、あなたの設定やKibanaがプロキシやロードバランサーの背後にあるかどうかによって異なります。通常は、${kibana-url}/api/security/oidc/callback(認可コードフローの場合)または${kibana-url}/api/security/oidc/implicit(暗黙的フローの場合)になります。ここで、${kibana-url}はあなたのKibanaインスタンスのベースURLです。これをCallback URIと呼ぶこともあります。

登録プロセスの最後に、OPはRP(Elastic Stack)が使用するクライアント識別子とクライアントシークレットを割り当てます。これらの2つの値をメモしておいてください。これらはElasticsearchの設定で使用されます。

OpenID Connect認証のためのElasticsearchの設定

以下は、ElasticsearchでOpenID Connectを使用した認証を有効にするために必要な設定手順の概要です:

HTTP用のTLSを有効にする

Elasticsearchクラスターが本番モードで動作している場合、OpenID Connect認証を有効にする前にHTTPインターフェースをSSL/TLSを使用するように設定する必要があります。

詳細については、ElasticsearchのHTTPクライアント通信を暗号化するを参照してください。

トークンサービスを有効にする

ElasticsearchのOpenID Connect実装は、Elasticsearchトークンサービスを利用します。このサービスは、HTTPインターフェースでTLSを設定すると自動的に有効になり、次の内容をelasticsearch.ymlファイルに含めることで明示的に設定できます:

Yaml

  1. xpack.security.authc.token.enabled: true

OpenID Connect領域を作成する

OpenID Connectベースの認証は、Elasticsearchの認証チェーン内で適切な領域を設定することによって有効になります。

この領域にはいくつかの必須設定と多数のオプション設定があります。利用可能な設定は、OpenID Connect領域設定で詳細に説明されています。このガイドでは、最も一般的な設定を探ります。

以下のように、oidc(領域タイプはoidc)のOpenID Connect領域をelasticsearch.ymlファイルに作成します:

以下で使用される値は例示のためのものであり、すべてのユースケースに適用されることを意図したものではありません。設定スニペットの下の詳細は、OP設定に応じて適切な値を選択するための洞察と提案を提供します。

Yaml

  1. xpack.security.authc.realms.oidc.oidc1:
  2. order: 2
  3. rp.client_id: "the_client_id"
  4. rp.response_type: code
  5. rp.redirect_uri: "https://kibana.example.org:5601/api/security/oidc/callback"
  6. op.issuer: "https://op.example.org"
  7. op.authorization_endpoint: "https://op.example.org/oauth2/v1/authorize"
  8. op.token_endpoint: "https://op.example.org/oauth2/v1/token"
  9. op.jwkset_path: oidc/jwkset.json
  10. op.userinfo_endpoint: "https://op.example.org/oauth2/v1/userinfo"
  11. op.endsession_endpoint: "https://op.example.org/oauth2/v1/logout"
  12. rp.post_logout_redirect_uri: "https://kibana.example.org:5601/security/logged_out"
  13. claims.principal: sub
  14. claims.groups: "http://example.info/claims/groups"

上記の例で使用される設定値は次のとおりです:

  • xpack.security.authc.realms.oidc.oidc1
  • これは「oidc1」という名前の新しいoidc認証領域を定義します。領域についての詳細は領域を参照してください。
  • order
  • 認証チェーン内の各領域に一意の順序を定義する必要があります。OpenID Connect領域は、認証チェーンの一番下に配置することが推奨されます(つまり、最も高い順序を持つこと)。
  • rp.client_id
  • 通常は不透明な任意の文字列で、OPによってElastic Stack RPに登録されたクライアント識別子です。
  • rp.response_type
  • これは、このRPがサポートするOpenID Connect認証フローを制御し、またこのRPがOPに従うよう要求するフローを制御する識別子です。サポートされている値は
    • code、これはRPが認可コードフローを使用したいことを意味します。OPが認可コードフローをサポートしている場合は、暗黙的フローの代わりにこれを選択するべきです。
    • id_token tokenは、RPが暗黙的フローを使用したいことを意味し、OPからoAuth2アクセストークンを要求します。これは、OPがその設定でUserInfoエンドポイントを提供している場合、またはロールマッピングに使用する必要があるクレームがIDトークンに含まれていないことがわかっている場合に選択するべきです。
    • id_tokenは、RPが暗黙的フローを使用したいが、oAuth2トークンを取得することには興味がないことを意味します。これは、すべての必要なクレームがIDトークンに含まれていることが確実である場合、またはOPがUser Infoエンドポイントを提供していない場合に選択してください。
  • rp.redirect_uri
  • OPが認証後にブラウザをリダイレクトするリダイレクトURIです。これは、登録時にOPと構成されたものと正確に同じである必要があり、通常は${kibana-url}/api/security/oidc/callbackになります。ここで、${kibana-url}はあなたのKibanaインスタンスのベースURLです。
  • op.issuer
  • あなたのOpenID Connectプロバイダーの検証可能な識別子。発行者識別子は通常、大文字と小文字を区別するURLです。この設定の値は、あなたのOpenID Connectプロバイダーによって提供されるべきです。
  • op.authorization_endpoint
  • OPの認可エンドポイントのURLです。これは、ユーザーのブラウザが認証プロセスを開始するためにリダイレクトされる場所です。この設定の値は、あなたのOpenID Connectプロバイダーによって提供されるべきです。
  • op.token_endpoint
  • OpenID ConnectプロバイダーのトークンエンドポイントのURLです。これは、ElasticsearchがコードをIDトークンと交換するためにリクエストを送信するエンドポイントです。この設定は、暗黙的フローを使用する場合はオプションです。この設定の値は、あなたのOpenID Connectプロバイダーによって提供されるべきです。
  • op.jwkset_path
  • OpenID Connectプロバイダーがトークンとクレームの応答に署名するために使用する鍵素材を含むJSON Web Key SetのファイルまたはURLへのパスです。パスが設定されている場合、それはElasticsearch設定ディレクトリに対して相対的に解決されます。Elasticsearchはこのファイルの変更を自動的に監視し、更新されるたびに設定を再読み込みします。あなたのOpenID Connectプロバイダーは、このファイルまたはそれが利用可能なURLを提供する必要があります。
  • op.userinfo_endpoint
  • (オプション)OpenID ConnectプロバイダーのUserInfoエンドポイントのURLです。これは、必要に応じて、ユーザー情報を取得するためにクエリできるOPのエンドポイントです。この設定の値は、あなたのOpenID Connectプロバイダーによって提供されるべきです。
  • op.endsession_endpoint
  • (オプション)OpenID ConnectプロバイダーのエンドセッションエンドポイントのURLです。これは、ローカルログアウト後にユーザーのブラウザがリダイレクトされる場所であり、領域がRP主導のシングルログアウトに設定されていて、OPがそれをサポートしている場合です。この設定の値は、あなたのOpenID Connectプロバイダーによって提供されるべきです。
  • rp.post_logout_redirect_uri
  • (オプション)OpenID Connectプロバイダーが成功したシングルログアウト後にユーザーをリダイレクトすべきリダイレクトURLです(上記のop.endsession_endpointも設定されていると仮定します)。これは、${kibana-url}/security/logged_out${kibana-url}/login?msg=LOGGED_OUTのように、新しいOpenID Connect認証をトリガーしない値に設定する必要があります。ここで、${kibana-url}はあなたのKibanaインスタンスのベースURLです。
  • claims.principal
  • クレームマッピングを参照してください。
  • claims.groups
  • クレームマッピングを参照してください。

OpenID Connect領域の最終的な設定は、OPでの登録中にRPに割り当てられたClient Secretを設定することです。これは安全な設定であり、そのためelasticsearch.ymlの領域設定には定義されておらず、elasticsearchキーストアに追加されます。例えば

  1. bin/elasticsearch-keystore add xpack.security.authc.realms.oidc.oidc1.rp.client_secret
  1. OpenID Connect仕様によれば、OPはその設定をよく知られたURLで利用可能にする必要があります。これは、`````Issuer`````の値と`````.well-known/openid-configuration`````の文字列を連結したものです。例えば:`````https://op.org.com/.well-known/openid-configuration`````そのドキュメントには、ElasticsearchOpenID Connect領域を設定するために必要なすべての情報が含まれている必要があります。
  2. ### クレームマッピング
  3. #### クレームとスコープ
  4. KibanaOpenID Connectを使用して認証する際、OPはユーザーに関する情報をOpenID Connectクレームの形式で提供します。これらはIDトークンに含まれるか、OPUserInfoエンドポイントから取得されます。クレームは、認証されたユーザーに対してOPが主張する情報の一部として定義されます。簡単に言えば、クレームはユーザーに関する情報を含む名前/値ペアです。クレームに関連して、OpenID Connectスコープの概念もあります。スコープは、特定のクレームのリストへのアクセスを要求するために使用される識別子です。標準は、要求できるスコープ識別子のセットを定義しています。唯一の必須のものは`````openid`````であり、一般的に使用されるものは`````profile``````````email`````です。`````profile`````スコープは、`````name``````````family_name``````````given_name``````````middle_name``````````nickname``````````preferred_username``````````profile``````````picture``````````website``````````gender``````````birthdate``````````zoneinfo``````````locale`````、および`````updated_at`````クレームへのアクセスを要求します。`````email`````スコープは、`````email`````および`````email_verified`````クレームへのアクセスを要求します。プロセスは、RPが認証リクエスト中に特定のスコープを要求することです。OPのプライバシーポリシーがそれを許可し、認証ユーザーがそれに同意すれば、関連するクレームがRPに返されます(IDトークン内またはUserInfo応答として)。
  5. サポートされるクレームのリストは、使用しているOPによって異なりますが、[標準クレーム](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)が広くサポートされることが期待されます。
  6. #### クレームをユーザー属性にマッピングする
  7. クレームマッピングの目的は、指定された返されたクレームの値をElasticsearchがサポートする[ユーザー属性](c0411e3fe7704d82.md#oidc-user-properties)の1つにマッピングできるようにElasticsearchを設定することです。これらのユーザー属性は、Kibana UIや監査ログでユーザーを識別するために利用され、[ロールマッピング](c0411e3fe7704d82.md#oidc-role-mappings)ルールを作成するためにも使用できます。
  8. OpenIDクレームマッピングを設定するための推奨手順は次のとおりです:
  9. - 1*.* OPの設定を確認して、どのクレームをサポートしているかを確認します。OPのメタデータやOPの設定ページに提供されるリストは、潜在的にサポートされるクレームのリストです。ただし、プライバシーの理由から、完全なリストではない場合や、すべての認証ユーザーに対してすべてのサポートされるクレームが利用可能でない場合があります。
  10. - 2*.* Elasticsearchがサポートする[ユーザー属性](c0411e3fe7704d82.md#oidc-user-properties)のリストを読み、どれがあなたにとって有用であり、OPがクレームの形式で提供できるかを決定します。最低限、`````principal`````ユーザー属性が必要です。
  11. - 3*.* OPを設定して、これらのクレームをElastic Stack依存パーティに「リリース」するようにします。このプロセスはプロバイダーによって大きく異なります。静的設定を使用することもできますが、他のプロバイダーはRPが認証時に「リリース」されるクレームに対応するスコープを要求することをサポートします。[`````rp.requested_scopes`````](d1e2d0944ccc2737.md#ref-oidc-settings)を参照して、要求するスコープを設定する方法の詳細を確認してください。相互運用性を確保し、エラーを最小限に抑えるために、OPがサポートするスコープのみを要求し、Elasticsearchユーザー属性にマッピングすることを意図しているスコープを要求するべきです。
  12. ``````bash
  13. NOTE: You can only map claims with values that are strings, numbers, boolean values or an array
  14. of the aforementioned.
  15. `
  • 4. ElasticsearchでOpenID Connect領域を設定して、Elasticsearchユーザー属性(以下のリストを参照)を、OPがリリースするクレームの名前に関連付けます。上記の例では、principalおよびgroupsユーザー属性を次のように設定しました:
    • 4.1. claims.principal: sub : これは、ElasticsearchにOPがユーザーのために発行したIDトークン(またはUserInfo応答)内のsubという名前のOpenID Connectクレームを探すように指示し、このクレームの値をprincipalユーザー属性に割り当てます。subは、OPにおけるユーザーの識別子であり、IDトークンの必須クレームでもあるため、一般的に使用されるクレームです。ここでは例としてのみ使用されていますが、OPはあなたのニーズにより適した別のクレームを提供する場合があります。
    • 4.2. claims.groups: "http://example.info/claims/groups" : 同様に、これはElasticsearchにhttp://example.info/claims/groupsという名前のクレームを探すように指示します(これはURIであり、識別子として扱われ、取得される場所を指すURLではありません)IDトークンまたはUserInfo応答内で、そしてその値をElasticsearchのユーザー属性groupsにマッピングします。OPにおける認証ユーザーのロールやグループメンバーシップを表現するための標準クレームは仕様に存在しないため、ここでマッピングされるべきクレームの名前はプロバイダーによって大きく異なります。詳細については、OPのドキュメントを参照してください。

Elasticsearchユーザー属性

ElasticsearchのOpenID Connect領域は、認証されたユーザーの次の属性にOpenID Connectクレームをマッピングするように設定できます:

  • principal
  • (必須)これは、この領域に対して認証されたユーザーに適用されるユーザー名です。principalは、Elasticsearchの監査ログなどの場所に表示されます。

principal属性がクレームからマッピングされない場合、認証は失敗します。

  • groups
  • (推奨)OPのグループまたはロールの概念をユーザーのElasticsearch権限の基礎として使用したい場合は、この属性でマッピングする必要があります。groupsは、あなたのロールマッピングルールに直接渡されます。
  • name
  • (オプション)ユーザーのフルネーム。
  • mail
  • (オプション)ユーザーのメールアドレス。
  • dn
  • (オプション)ユーザーのX.500識別名。

OpenID Connectクレームから部分値を抽出する

クレームの値がElasticsearch内で使用したい情報よりも多くの情報を含む場合があります。一般的な例は、OPがメールアドレスのみを使用する場合ですが、ユーザーのprincipalをメールアドレスのローカル名部分を使用して設定したい場合です。例えば、彼らのメールアドレスが[email protected]の場合、彼らのprincipalは単にjames.wongであることを望みます。

これは、以下の領域設定で示されるように、Elasticsearch領域内のclaim_patterns設定を使用することで実現できます。

Yaml

  1. xpack.security.authc.realms.oidc.oidc1:
  2. order: 2
  3. rp.client_id: "the_client_id"
  4. rp.response_type: code
  5. rp.redirect_uri: "https://kibana.example.org:5601/api/security/oidc/callback"
  6. op.authorization_endpoint: "https://op.example.org/oauth2/v1/authorize"
  7. op.token_endpoint: "https://op.example.org/oauth2/v1/token"
  8. op.userinfo_endpoint: "https://op.example.org/oauth2/v1/userinfo"
  9. op.endsession_endpoint: "https://op.example.org/oauth2/v1/logout"
  10. op.issuer: "https://op.example.org"
  11. op.jwkset_path: oidc/jwkset.json
  12. claims.principal: email_verified
  13. claim_patterns.principal: "^([^@]+)@staff\\.example\\.com$"

この場合、ユーザーのprincipalemail_verifiedクレームからマッピングされますが、値がユーザーに割り当てられる前に正規表現が適用されます。正規表現が一致する場合、最初のグループの結果が有効な値として使用されます。正規表現が一致しない場合、クレームマッピングは失敗します。

この例では、メールアドレスはstaff.example.comドメインに属する必要があり、その後ローカル部分(@の前の部分)がprincipalとして使用されます。異なるメールドメインを使用してログインしようとするユーザーは、正規表現が彼らのメールアドレスに対して一致しないため、失敗します。そのため、必須であるprincipalユーザー属性は設定されません。

これらの正規表現の小さなミスは、重大なセキュリティ上の結果をもたらす可能性があります。例えば、上記の例から末尾の$を誤って省略した場合、staff.example.comで始まるドメインの任意のメールアドレスに一致し、[email protected]のようなメールアドレスを受け入れることになります。正規表現ができるだけ正確であることを確認し、ユーザーのなりすまし攻撃の道を誤って開かないようにすることが重要です。

サードパーティによるシングルサインオンの開始

ElasticsearchのOpenID Connect領域は、関連仕様で説明されているように、サードパーティによるログインをサポートしています。

これにより、OP自体またはRP以外の他のサードパーティが、認証プロセスを開始し、認証にOPを使用するよう要求できます。このプロセスが成功するためには、Elastic Stack RPがこのOPのためにすでに設定されている必要があります。

OpenID Connectログアウト

ElasticsearchのOpenID Connect領域は、関連仕様の一部で説明されているRP主導のログアウト機能をサポートしています。

このプロセスでは、OpenID Connect RP(この場合はElastic Stack)が、ローカルログアウトを正常に完了した後、ユーザーのブラウザをOPの事前定義されたURLにリダイレクトします。OPは、その設定に応じてユーザーをログアウトさせ、最終的にユーザーをRPにリダイレクトする必要があります。領域設定のop.endsession_endpointは、ブラウザがリダイレクトされるOPのURLを決定します。rp.post_logout_redirect_uri設定は、OPがユーザーをログアウトさせた後にユーザーをリダイレクトするURLを決定します。

rp.post_logout_redirect_uriを設定する際には、ユーザーの再認証をトリガーするURLを指さないように注意する必要があります。例えば、KibanaへのシングルサインオンをサポートするためにOpenID Connectを使用する場合、これはユーザーにユーザーフレンドリーなメッセージを表示する${kibana-url}/security/logged_outに設定するか、Kibanaのログインセレクタにユーザーを連れて行く${kibana-url}/login?msg=LOGGED_OUTに設定できます。

OpenID Connect領域のSSL設定

OpenID Connectは、転送中の暗号化やエンドポイント認証などのセキュリティプロパティを提供するためにTLSに依存しています。RPは、認可コードグラントフロー中にIDトークンと交換するためのコードを交換するためにOPとのバックチャネル通信を確立する必要があります。また、UserInfoエンドポイントから追加のユーザー情報を取得するためにも必要です。さらに、op.jwks_pathをURLとして設定すると、ElasticsearchはそこにホストされているOPの署名鍵を取得する必要があります。そのため、ElasticsearchがOPがTLSに使用するサーバー証明書を検証し、信頼できることが重要です。システムトラストストアは、外向きのhttps接続のクライアントコンテキストに使用されるため、OPが信頼できるCAからの証明書を使用している場合、追加の設定は必要ありません。

ただし、OPの証明書の発行者がElasticsearchが実行されているJVMによって信頼されていない場合(例えば、組織CAを使用している場合)、ElasticsearchがそのCAを信頼するように設定する必要があります。OPがTLSに使用する証明書に署名したCA証明書がElasticsearchの設定ディレクトリにある/oidc/company-ca.pemファイルに保存されていると仮定すると、領域設定に次のプロパティを設定する必要があります:

Yaml

  1. xpack.security.authc.realms.oidc.oidc1:
  2. order: 1
  3. ...
  4. ssl.certificate_authorities: ["/oidc/company-ca.pem"]

ロールマッピングの設定

ユーザーがOpenID Connectを使用して認証すると、彼らはElastic Stackに識別されますが、これにより自動的にアクションを実行したりデータにアクセスしたりする権限が与えられるわけではありません。

OpenID Connectユーザーは、ロールが割り当てられるまで何もできません。これは、ロールマッピングAPIを追加するか、認可領域を使用して行うことができます。

ロールマッピングファイルを使用してOpenID Connect経由で認証されたユーザーにロールを付与することはできません。

以下は、example_roleロールをoidc1 OpenID Connect領域に対して認証された任意のユーザーに付与するシンプルなロールマッピングの例です:

Python

  1. resp = client.security.put_role_mapping(
  2. name="oidc-example",
  3. roles=[
  4. "example_role"
  5. ],
  6. enabled=True,
  7. rules={
  8. "field": {
  9. "realm.name": "oidc1"
  10. }
  11. },
  12. )
  13. print(resp)

Js

  1. const response = await client.security.putRoleMapping({
  2. name: "oidc-example",
  3. roles: ["example_role"],
  4. enabled: true,
  5. rules: {
  6. field: {
  7. "realm.name": "oidc1",
  8. },
  9. },
  10. });
  11. console.log(response);

コンソール

  1. PUT /_security/role_mapping/oidc-example
  2. {
  3. "roles": [ "example_role" ],
  4. "enabled": true,
  5. "rules": {
  6. "field": { "realm.name": "oidc1" }
  7. }
  8. }

| | example_roleロールは**組み込みのElasticsearchロールではありません。
この例では、適切なアクセス権を持つ独自のカスタムロールを作成したと仮定しています。
データストリーム、インデックス、および
Kibana機能。 |

領域設定を介してマッピングされたユーザー属性は、ロールマッピングルールを処理するために使用され、これらのルールはユーザーに付与されるロールを決定します。

ロールマッピングに提供されるユーザーフィールドは、次のようにOpenID Connectクレームから派生します:

  • username: principalユーザー属性
  • dn: dnユーザー属性
  • groups: groupsユーザー属性
  • metadata: ユーザーメタデータを参照してください。

詳細については、ユーザーとグループをロールにマッピングするおよびロールマッピングを参照してください。

OPがOpenIDクレームを介してRPにグループやロールを提供する能力を持っている場合は、このクレームをElasticsearch領域のclaims.groups設定にマッピングし、以下の例に従ってロールマッピングで使用する必要があります。

このマッピングは、oidc1グループメンバーシップを持つfinance_data領域を介して認証された任意のユーザーにElasticsearch finance-teamロールを付与します。

Python

  1. resp = client.security.put_role_mapping(
  2. name="oidc-finance",
  3. roles=[
  4. "finance_data"
  5. ],
  6. enabled=True,
  7. rules={
  8. "all": [
  9. {
  10. "field": {
  11. "realm.name": "oidc1"
  12. }
  13. },
  14. {
  15. "field": {
  16. "groups": "finance-team"
  17. }
  18. }
  19. ]
  20. },
  21. )
  22. print(resp)

Js

  1. const response = await client.security.putRoleMapping({
  2. name: "oidc-finance",
  3. roles: ["finance_data"],
  4. enabled: true,
  5. rules: {
  6. all: [
  7. {
  8. field: {
  9. "realm.name": "oidc1",
  10. },
  11. },
  12. {
  13. field: {
  14. groups: "finance-team",
  15. },
  16. },
  17. ],
  18. },
  19. });
  20. console.log(response);

コンソール

  1. PUT /_security/role_mapping/oidc-finance
  2. {
  3. "roles": [ "finance_data" ],
  4. "enabled": true,
  5. "rules": { "all": [
  6. { "field": { "realm.name": "oidc1" } },
  7. { "field": { "groups": "finance-team" } }
  8. ] }
  9. }

ユーザーがElasticsearchに直接アクセスできるリポジトリ(LDAPディレクトリなど)にも存在する場合、認可領域をロールマッピングの代わりに使用できます。

この場合、次の手順を実行します:

  • 1. OpenID Connect領域で、claims.principal設定を構成して、ルックアップユーザーIDとして機能するクレームを割り当てます。
  • 2. ローカルリポジトリからユーザーをルックアップできる新しい領域を作成します(例:ldap領域)
  • 3. OpenID Connect領域で、authorization_realmsをステップ2で作成した領域の名前に設定します。

ユーザーメタデータ

デフォルトでは、OpenID Connectを介して認証されたユーザーには、追加のメタデータフィールドがいくつかあります。これらのフィールドには、認証応答で提供されるすべてのOpenIDクレームが含まれます(それがElasticsearchユーザー属性にマッピングされているかどうかに関係なく)。例えば、メタデータフィールドoidc(claim_name)では、「claim_name」はIDトークンまたはUser Info応答に含まれていたクレームの名前です。これらには、認証イベントに関連するすべてのIDトークンクレームが含まれ、ユーザー自身に関連するものではありません。

この動作は、oidc領域にpopulate_user_metadata: falseを設定することで無効にできます。

Kibanaの設定

KibanaでのOpenID Connect認証には、標準のKibanaセキュリティ設定に加えて、少数の追加設定が必要です。Kibanaセキュリティドキュメントには、適用できる設定オプションの詳細が記載されています。

特に、ElasticsearchノードがHTTPインターフェースでTLSを使用するように設定されているため、KibanaをElasticsearchに接続するためにhttps URLを使用するように設定する必要があり、Elasticsearchが使用するように設定された証明書を信頼するためにelasticsearch.ssl.certificateAuthoritiesを設定する必要がある場合があります。

KibanaでのOpenID Connect認証は、kibana.ymlの次のタイムアウト設定の影響を受けます:

これらのタイムアウトは、セキュリティ要件に基づいて調整することをお勧めします。

OpenID Connectサポートに必要な3つの追加設定は、以下に示します:

Yaml

  1. xpack.security.authc.providers:
  2. oidc.oidc1:
  3. order: 0
  4. realm: "oidc1"

上記の例で使用される設定値は次のとおりです:

  • xpack.security.authc.providers
  • OpenID Connectシングルサインオンを認証方法として使用するようにKibanaに指示するためにoidcプロバイダーを追加します。これは、ユーザーがすでに認証されていない場合、Kibana内のURLにアクセスしようとするたびにSSOフローを開始しようとするようKibanaに指示します。ユーザーがユーザー名とパスワードでログインできるようにする場合は、basic認証プロバイダーも有効にする必要があります。例えば:

Yaml

  1. xpack.security.authc.providers:
  2. oidc.oidc1:
  3. order: 0
  4. realm: "oidc1"
  5. basic.basic1:
  6. order: 1

これにより、OpenID Connectでまだ認証されていないユーザーがKibanaのログインフォームを使用してログインできるようになります。

  • xpack.security.authc.providers.oidc.<provider-name>.realm
  • このKibanaインスタンスの認証を処理するために、Elasticsearch内のOpenID Connect領域の名前です。

KibanaなしのOpenID Connect

OpenID Connectの領域は、ユーザーがKibanaに認証することを可能にするように設計されています。そのため、上記のガイドのほとんどの部分はKibanaが使用されることを前提としています。このセクションでは、カスタムWebアプリケーションがOpenID Connectを使用してElasticsearchにユーザーを認証するために関連するOpenID Connect REST APIをどのように使用できるかを説明します。

OpenID ConnectやSAMLのようなシングルサインオン領域は、Elasticsearchのトークンサービスを利用し、原則としてSAMLまたはOpenID Connectの認証応答をElasticsearchのアクセストークンとリフレッシュトークンに交換します。アクセストークンは、Elasticsearchへのその後の呼び出しのための資格情報として使用されます。リフレッシュトークンは、現在のトークンが期限切れになった後にユーザーが新しいElasticsearchアクセストークンを取得できるようにします。

Elasticsearchのトークンサービスは、最小限のoAuth2認可サーバーとして見ることができ、上記のアクセストークンとリフレッシュトークンはこの認可サーバーにのみ関連するトークンです。これらはElasticsearchによってのみ生成され、消費され、OpenID Connectプロバイダーが発行するトークン(アクセストークンとIDトークン)とは一切関係ありません。

OpenID ConnectプロバイダーにRPを登録する

依存するパーティ(ElasticsearchとカスタムWebアプリ)は、OpenID Connectプロバイダーにクライアントとして登録する必要があります。Redirect URIを登録する際には、カスタムWebアプリ内のURLである必要があります。

OpenID Connect領域

OpenID Connectの領域は、Elasticsearch内で作成され、適切に構成される必要があります。詳細はOpenID Connect認証のためのElasticsearchの構成を参照してください。

APIにアクセスするためのサービスアカウントユーザー

この領域は、認証プロキシとして機能する特権エンティティが必要であるという前提で設計されています。この場合、カスタムWebアプリケーションはエンドユーザーの認証を処理する認証プロキシです(より正確には、OpenID Connectプロバイダーに認証を「委任」しています)。OpenID Connect APIは認証を必要とし、認証されたユーザーに必要な権限レベルを要求します。このため、サービスアカウントユーザーを作成し、manage_oidcクラスター特権を付与する役割を割り当てる必要があります。認証が行われた後、manage_tokenクラスター特権の使用が必要になるため、ユーザーはアクセスを維持したり、後でログアウトされたりすることができます。

Python

  1. resp = client.security.put_role(
  2. name="facilitator-role",
  3. cluster=[
  4. "manage_oidc",
  5. "manage_token"
  6. ],
  7. )
  8. print(resp)

Js

  1. const response = await client.security.putRole({
  2. name: "facilitator-role",
  3. cluster: ["manage_oidc", "manage_token"],
  4. });
  5. console.log(response);

コンソール

  1. POST /_security/role/facilitator-role
  2. {
  3. "cluster" : ["manage_oidc", "manage_token"]
  4. }

Python

  1. resp = client.security.put_user(
  2. username="facilitator",
  3. password="<somePasswordHere>",
  4. roles=[
  5. "facilitator-role"
  6. ],
  7. )
  8. print(resp)

Js

  1. const response = await client.security.putUser({
  2. username: "facilitator",
  3. password: "<somePasswordHere>",
  4. roles: ["facilitator-role"],
  5. });
  6. console.log(response);

コンソール

  1. POST /_security/user/facilitator
  2. {
  3. "password" : "<somePasswordHere>",
  4. "roles" : [ "facilitator-role"]
  5. }

認証フローの処理

高レベルでは、カスタムWebアプリケーションはOpenID Connectを使用してユーザーを認証するために以下の手順を実行する必要があります:

  • 1. _security/oidc/prepareにHTTP POSTリクエストを行い、facilitatorユーザーとして認証し、リクエストボディにElasticsearch構成内のOpenID Connect領域の名前を使用します。詳細については、OpenID Connect認証の準備を参照してください。

Python

  1. resp = client.security.oidc_prepare_authentication(
  2. body={
  3. "realm": "oidc1"
  4. },
  5. )
  6. print(resp)

Js

  1. const response = await client.security.oidcPrepareAuthentication({
  2. body: {
  3. realm: "oidc1",
  4. },
  5. });
  6. console.log(response);

コンソール

  1. POST /_security/oidc/prepare
  2. {
  3. "realm" : "oidc1"
  4. }
  • 2. /_security/oidc/prepareへの応答を処理します。Elasticsearchからの応答には3つのパラメータが含まれます:redirectstatenonce。カスタムWebアプリケーションは、statenonceの値をユーザーのセッションに保存する必要があります(クライアント側のクッキーまたはセッション情報がこの方法で保持される場合はサーバー側)し、ユーザーのブラウザをredirect値に含まれるURLにリダイレクトします。
  • 3. OPからの後続の応答を処理します。ユーザーがOpenID Connectプロバイダーで正常に認証されると、コールバック/リダイレクトURIにリダイレクトされます。このHTTP GETリクエストを受信した後、カスタムWebアプリは再度_security/oidc/authenticateにHTTP POSTリクエストを行い、facilitatorユーザーとして認証し、ユーザーのブラウザがリダイレクトされたURLをパラメータとして渡し、以前にユーザーのセッションに保存したnoncestateの値を渡します。複数のOpenID Connect領域が構成されている場合、カスタムWebアプリはこれを処理するために使用する領域の名前を指定できますが、このパラメータはオプションです。詳細については、OpenID Connect認証を参照してください。

Python

  1. resp = client.security.oidc_authenticate(
  2. body={
  3. "redirect_uri": "https://oidc-kibana.elastic.co:5603/api/security/oidc/callback?code=jtI3Ntt8v3_XvcLzCFGq&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
  4. "state": "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
  5. "nonce": "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM",
  6. "realm": "oidc1"
  7. },
  8. )
  9. print(resp)

Js

  1. const response = await client.security.oidcAuthenticate({
  2. body: {
  3. redirect_uri:
  4. "https://oidc-kibana.elastic.co:5603/api/security/oidc/callback?code=jtI3Ntt8v3_XvcLzCFGq&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
  5. state: "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
  6. nonce: "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM",
  7. realm: "oidc1",
  8. },
  9. });
  10. console.log(response);

コンソール

  1. POST /_security/oidc/authenticate
  2. {
  3. "redirect_uri" : "https://oidc-kibana.elastic.co:5603/api/security/oidc/callback?code=jtI3Ntt8v3_XvcLzCFGq&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
  4. "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
  5. "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM",
  6. "realm" : "oidc1"
  7. }

Elasticsearchはこれを検証し、すべてが正しければ、後続のリクエストのためのBearerトークンとして使用できるアクセストークンと、後で指定されたアクセストークンをリフレッシュするために使用できるリフレッシュトークンで応答します。詳細はトークンを取得するを参照してください。

  • 4. 必要に応じて、カスタムWebアプリケーションはOIDCログアウトAPIを使用してユーザーをログアウトさせることができます。アクセス・トークンとリフレッシュ・トークンをパラメータとして渡します。例えば:

Python

  1. resp = client.security.oidc_logout(
  2. body={
  3. "token": "dGhpcyBpcyBub3QgYSByZWFsIHRva2VuIGJ1dCBpdCBpcyBvbmx5IHRlc3QgZGF0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==",
  4. "refresh_token": "vLBPvmAB6KvwvJZr27cS"
  5. },
  6. )
  7. print(resp)

Js

  1. const response = await client.security.oidcLogout({
  2. body: {
  3. token:
  4. "dGhpcyBpcyBub3QgYSByZWFsIHRva2VuIGJ1dCBpdCBpcyBvbmx5IHRlc3QgZGF0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==",
  5. refresh_token: "vLBPvmAB6KvwvJZr27cS",
  6. },
  7. });
  8. console.log(response);

コンソール

  1. POST /_security/oidc/logout
  2. {
  3. "token" : "dGhpcyBpcyBub3QgYSByZWFsIHRva2VuIGJ1dCBpdCBpcyBvbmx5IHRlc3QgZGF0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==",
  4. "refresh_token": "vLBPvmAB6KvwvJZr27cS"
  5. }

領域が適切に構成されている場合、これはユーザーがログアウトプロセスを完了するためにOPでリダイレクトされる必要がある場所を示すredirectパラメータを含む応答をもたらす可能性があります。