JWT 認証
Elasticsearch は、外部サービスから発行された JSON Web Tokens (JWT) を認証のためのベアラートークンとして信頼するように構成できます。
JWT レルムを使用して Elasticsearch に認証する場合、Elasticsearch に接続している クライアント と、リクエストが実行されるべき ユーザー の区別がなされます。JWT はユーザーを認証し、別の資格情報がクライアントを認証します。
JWT レルムは、id_token
(デフォルト) と access_token
の 2 つのトークンタイプをサポートしています。これらは、それぞれ次の 2 つのシナリオで機能するように設計されています:
- 1.
id_token
- アプリケーションが認証フローを使用してユーザーを認証および識別し、例えば OpenID Connect (OIDC) を使用して、認証されたユーザーの代わりに OIDC ID トークン仕様に準拠した JSON Web Token (JWT) を使用して Elasticsearch にアクセスします。 - 2.
access_token
- アプリケーションが独自のアイデンティティを持ち、JWT としてエンコードされている場合、例えばアプリケーションが OAuth2 クライアント資格情報フローを使用して中央アイデンティティプラットフォームに自らを認証し、その後、得られた JWT ベースのアクセストークンを使用して Elasticsearch に接続します。
単一の JWT レルムは、単一のトークンタイプでのみ機能します。両方のトークンタイプを処理するには、少なくとも 2 つの JWT レルムを構成する必要があります。使用ケースに基づいてトークンタイプを慎重に選択する必要があります。これは、検証がどのように行われるかに影響を与えます。
JWT レルムは、構成されたトークンタイプに基づいて受信した JWT を検証します。両方のタイプの JSON Web Tokens (JWT) は、次の 5 つの情報を含む必要があります。OIDC 仕様に基づく ID トークンは、これらの情報を提供するために必要なクレームに厳格なルールがありますが、アクセストークンは一部のクレームを構成可能にします。
クレーム | ||
情報 | ID トークン | アクセストークン |
発行者 | iss |
iss |
主題 | sub |
デフォルトは sub ですが、sub が存在しない場合は別のクレームにフォールバックできます |
対象 | aud |
デフォルトは aud ですが、aud が存在しない場合は別のクレームにフォールバックできます |
発行時間 | iat |
iat |
有効期限 | exp |
exp |
さらに、Elasticsearch は、これらのクレームが存在する場合、ID トークンの nbf
および auth_time
クレームも検証します。ただし、これらのクレームはアクセストークンには無視されます。
全体として、アクセストークンタイプは検証ルールが緩和されており、自己署名のものを含むより一般的な JWT に適しています。
OIDC ワークフローからの ID トークン
Elasticsearch における JWT 認証は、OIDC ユーザーワークフローから派生しており、異なるトークンが OIDC プロバイダー (OP) によって発行されることがあります。OIDC プロバイダーからの ID トークンは、明確に定義された JSON Web Tokens (JWT) であり、常に id_token
トークンタイプの JWT レルムと互換性があるべきです。ID トークンの主題クレームはエンドユーザーを表します。これは、ID トークンが一般的に多くの許可された主題を持つことを意味します。したがって、id_token
トークンタイプの JWT レルムは、allowed_subjects
(または allowed_subject_patterns
) 検証を義務付けません。
JWT は Elasticsearch の外部で取得されるため、OIDC ワークフローを使用する代わりにカスタムワークフローを定義できます。ただし、JWT 形式は依然として JSON Web Signature (JWS) でなければなりません。JWS ヘッダーと JWS 署名は、OIDC ID トークン検証ルールを使用して検証されます。
Elasticsearch は、別の OpenID Connect レルム をサポートしています。これは、Elasticsearch が OIDC RP として機能できる任意のユースケースに推奨されます。OIDC レルムは、Kibana で OIDC 認証を有効にする唯一のサポートされた方法です。
JWT レルムで認証されたユーザーは、オプションで run_as
機能を使用して別のユーザーを偽装できます。詳細は JWT レルムユーザーに run_as
特権を適用する を参照してください。
アクセストークン
アクセストークンを取得する一般的な方法は、OAuth2 クライアント資格情報フローを使用することです。このフローの典型的な使用法は、アプリケーションが自分自身のために資格情報を取得することです。これは、access_token
トークンタイプが設計されたユースケースです。このアプリケーションは、エンドユーザーのために ID トークンも取得する可能性があります。エンドユーザーの ID トークンがアプリケーション用に構成された JWT レルムで認証に使用されるのを防ぐために、JWT レルムがトークンタイプ access_token
の場合、allowed_subjects
または allowed_subject_patterns
検証を義務付けます。
すべてのアクセストークンが JSON Web Token (JWT) 形式であるわけではありません。JWT レルムと互換性があるためには、少なくとも JWT 形式を使用し、上記の表の関連要件を満たす必要があります。
Elasticsearch を JWT レルムを使用するように構成する
JWT 認証を使用するには、elasticsearch.yml
ファイルにレルムを作成して、Elasticsearch 認証チェーン内で構成します。
JWT レルムには、いくつかの必須設定と、JWT レルム設定 に記載されているオプション設定があります。
クライアント認証は、JWT レルムに対してデフォルトで有効になっています。クライアント認証を無効にすることは可能ですが、強く推奨されません。
- 1. あなたの JWT レルムを
elasticsearch.yml
ファイルに追加します。以下の例は、最も一般的な設定を含んでおり、すべてのユースケースに適しているわけではありません:
Yaml
xpack.security.authc.realms.jwt.jwt1:
order: 3
token_type: id_token
client_authentication.type: shared_secret
allowed_issuer: "https://issuer.example.com/jwt/"
allowed_audiences: [ "8fb85eba-979c-496c-8ae2-a57fde3f12d0" ]
allowed_signature_algorithms: [RS256,HS256]
pkc_jwkset_path: jwt/jwkset.json
claims.principal: sub
- `````order````` の `````3````` を指定し、ユーザーを認証する際に構成されたレルムがチェックされる順序を示します。レルムは昇順で参照され、最も低い順序値を持つレルムが最初に参照されます。
- `````token_type
- レルムに、受信した JWT を ID トークン (
id_token
) として扱い、検証するよう指示します。 client_authentication.type
- クライアント認証タイプを
shared_secret
として指定します。これは、クライアントが事前に構成された秘密値と一致する必要がある HTTP リクエストヘッダーを使用して認証されることを意味します。クライアントは、ES-Client-Authentication
ヘッダーでこの共有秘密をすべてのリクエストに提供する必要があります。ヘッダー値は、レルムのclient_authentication.shared_secret
に対して大文字と小文字を区別して一致する必要があります。 allowed_issuer
- JWT 発行者の検証可能な識別子を設定します。この値は通常、URL、UUID、または他の大文字と小文字を区別する文字列値です。
allowed_audiences
- レルムが許可する JWT 対象のリストを指定します。これらの値は通常、URL、UUID、または他の大文字と小文字を区別する文字列値です。
allowed_signature_algorithms
- Elasticsearch が JWT 発行者からの JWT の署名を検証するために
RS256
またはHS256
署名アルゴリズムを使用することを示します。 pkc_jwkset_path
- JWT レルムがトークン署名を検証するために使用する公開鍵素材を持つ JSON Web Key Set (JWKS) のファイル名または URL。値は
https
で始まらない場合、ファイル名と見なされます。ファイル名は Elasticsearch 構成ディレクトリに対して相対的に解決されます。URL が提供される場合、https://
で始まる必要があります (http://
はサポートされていません)。Elasticsearch は JWK セットを自動的にキャッシュし、署名検証失敗時に JWK セットを更新しようとします。これは、JWT プロバイダーが署名キーを回転させたことを示す可能性があります。 claims.principal
- ユーザーのプリンシパル (ユーザー名) を含む JWT クレームの名前。
JWT レルムを構成してアクセストークンを処理するための例のスニペットは次のとおりです:
Yaml
xpack.security.authc.realms.jwt.jwt2:
order: 4
token_type: access_token
client_authentication.type: shared_secret
allowed_issuer: "https://issuer.example.com/jwt/"
allowed_subjects: [ "[email protected]" ]
allowed_subject_patterns: [ "wild*@developer?.example.com", "/[a-z]+<1-10>\\@dev\\.example\\.com/"]
allowed_audiences: [ "elasticsearch" ]
required_claims:
token_use: access
version: ["1.0", "2.0"]
allowed_signature_algorithms: [RS256,HS256]
pkc_jwkset_path: "https://idp-42.example.com/.well-known/configuration"
fallback_claims.sub: client_id
fallback_claims.aud: scope
claims.principal: sub
- 受信した JWT をアクセストークン (`````access_token`````) として扱い、検証するようにレルムに指示します。
- `````allowed_subjects
- レルムが許可する JWT 主題のリストを指定します。これらの値は通常、URL、UUID、または他の大文字と小文字を区別する文字列値です。
allowed_subject_patterns
allowed_subjects
に類似していますが、許可された JWT 主題のために Lucene regexp とワイルドカードのリストを受け入れます。ワイルドカードは、*
および?
特殊文字 (これらは\
によってエスケープされます) を使用して「任意の文字列」と「任意の単一文字」を意味します。例えば「a?*」は「a1」や「abwhatever」に一致しますが、「a」、「abc」、または「abc」には一致しません (Java 文字列では\
自体が別の\
によってエスケープされる必要があります)。 Lucene regexp は/
で囲む必要があります。例えば「/https?://[^/]+/?/」は、パスコンポーネントのない任意の http または https URL に一致します (「https://elastic.co/」には一致しますが、「https://elastic.co/guide」には一致しません)。allowed_subjects
またはallowed_subject_patterns
の設定のいずれかを指定する必要があります (かつ非空である必要があります)token_type
がaccess_token
の場合。allowed_subjects
およびallowed_subject_patterns
の両方の設定が指定されている場合、受信した JWT のsub
クレームは、2 つのリストのいずれかに一致する場合に受け入れられます。required_claims
- JWT に対して追加の検証を実行するためのキー/値ペアのリストを指定します。値は文字列または文字列の配列です。
fallback_claims.sub
sub
クレームが存在しない場合に主題情報を抽出するための JWT クレームの名前。この設定はtoken_type
がaccess_token
の場合にのみ利用可能です。フォールバックはsub
クレームが使用されるすべての場所に適用されます。上記のスニペットでは、claims.principal
はclient_id
が存在しない場合にsub
にもフォールバックします。fallback_claims.aud
aud
クレームが存在しない場合に対象情報を抽出するための JWT クレームの名前。この設定はtoken_type
がaccess_token
の場合にのみ利用可能です。フォールバックはaud
クレームが使用されるすべての場所に適用されます。
- 2. 設定を定義した後、
elasticsearch-keystore
ツールを使用して、Elasticsearch キーストアに安全な設定の値を保存します。- 2.1.
shared_secret
の値をclient_authentication.type
に保存します:
- 2.1.
Shell
bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret
- 2.2.
allowed_signature_algorithms
の HMAC キーを保存します。これは、例のHS256
アルゴリズムを使用します:
Shell
bin/elasticsearch-keystore add-file xpack.security.authc.realms.jwt.jwt1.hmac_jwkset <path>
JWKS へのパス。これは、JSON でエンコードされた秘密鍵のセットのリソースです。 ファイルの内容を Elasticsearch キーストアにロードした後、ファイルを削除できます。 |
JWKS を使用することが推奨されます。ただし、次のコマンドを使用して文字列形式の HMAC キーを追加できます。この形式は HMAC UTF-8 キーと互換性がありますが、属性のない単一のキーのみをサポートします。HMAC 形式 (hmac_jwkset
または hmac_key
) を同時に 1 つだけ使用できます。
Shell
bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.hmac_key
JWT エンコーディングと検証
JWT は 3 つの部分に解析できます:
- ヘッダー
- トークンを検証する方法に関する情報を提供します。
- クレーム
- 呼び出しユーザーまたはアプリケーションに関するデータを含みます。
- 署名
- トークンを検証するために使用されるデータです。
Js
Header: {"typ":"JWT","alg":"HS256"}
Claims: {"aud":"aud8","sub":"security_test_user","iss":"iss8","exp":4070908800,"iat":946684800}
Signature: UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
この例は、JWT の部分的なデコードを示しています。有効期間は 2000 年から 2099 年 (両端を含む) で、発行時間 (iat
) と有効期限 (exp
) によって定義されています。JWT は通常、100 年未満の有効期間を持ち、1-2 時間または 1-7 日などであり、全人類の寿命ではありません。
この例の署名は決定論的です。なぜなら、ヘッダー、クレーム、および HMAC キーが固定されているからです。JWT は通常、署名を非決定論的にするための nonce
クレームを持っています。サポートされている JWT エンコーディングは JSON Web Signature (JWS) であり、JWS Header
および Signature
は OpenID Connect ID トークン検証ルールを使用して検証されます。一部の検証は、JWT レルム設定 を通じてカスタマイズ可能です。
ヘッダー クレーム
ヘッダー クレームは、トークンタイプとトークンに署名するために使用されるアルゴリズムを示します。
alg
- (必須、文字列) トークンに署名するために使用されたアルゴリズムを示します。例えば
HS256
のように。アルゴリズムはレルムの許可リストに含まれている必要があります。 typ
- (オプション、文字列) トークンタイプを示します。これは
JWT
でなければなりません。
ペイロード クレーム
トークンには、トークンを発行しているユーザーおよびトークン自体に関する情報を提供するいくつかのクレームが含まれています。トークンタイプに応じて、これらの情報は異なるクレームによって識別される場合があります。
JWT ペイロード クレーム
次のクレームは、OIDC ID トークンルールのサブセットによって検証されます。
Elasticsearch は nonce
クレームを検証しませんが、カスタム JWT 発行者は署名にエントロピーを導入するためにランダムな nonce
クレームを追加できます。
allowed_clock_skew
を設定することで、時間ベースのクレームの検証を緩和できます。この値は、認証時間 (auth_time
)、作成時間 (iat
)、有効前 (nbf
)、および有効期限 (exp
) に関して JWT を検証する前に許可される最大のクロックずれを設定します。
iss
- (必須、文字列) ID トークンを作成した発行者を示します。この値は
allowed_issuer
設定の値と正確に大文字と小文字を区別して一致する必要があります。 sub
- (必須*) ID トークンが作成される対象を示します。JWT レルムが
id_token
タイプの場合、このクレームは必須です。id_token
タイプの JWT レルムはデフォルトですべての主題を受け入れます。アクセストークンタイプの JWT レルムはallowed_subjects
設定を指定する必要があり、主題値は許可された主題の設定の CSV 値のいずれかに正確に大文字と小文字を区別して一致する必要があります。アクセストークンタイプの JWT レルムは、sub
クレームが存在しない場合に使用されるフォールバッククレームを指定できます。 aud
- (必須*) ID トークンの対象であるオーディエンスを示します。カンマ区切りの値 (CSV) として表現されます。値の 1 つは、
allowed_audiences
設定の CSV 値のいずれかに正確に大文字と小文字を区別して一致する必要があります。id_token
タイプの JWT レルムはこのクレームを必須とします。access_token
タイプの JWT レルムは、aud
クレームが存在しない場合に使用されるフォールバッククレームを指定できます。 exp
- (必須、整数) ID トークンの有効期限。エポックからの UTC 秒で表現されます。
iat
- (必須、整数) ID トークンが発行された時間。エポックからの UTC 秒で表現されます。
nbf
- (オプション、整数) JWT が受け入れられないべき時間を示します。エポックからの UTC 秒で表現されます。このクレームはオプションです。存在する場合、
id_token
タイプの JWT レルムはそれを検証し、access_token
タイプの JWT レルムはそれを無視します。 auth_time
- (オプション、整数) JWT 発行者に認証されたユーザーの時間。エポックからの UTC 秒で表現されます。このクレームはオプションです。存在する場合、
id_token
タイプの JWT レルムはそれを検証し、access_token
タイプの JWT レルムはそれを無視します。
JWT クレームを消費するための Elasticsearch 設定
Elasticsearch は、次の設定に対して JWT クレームを使用します。
principal
- (必須、文字列) ユーザーのプリンシパル (ユーザー名) を含みます。この値は、
claims.principal
レルム設定を使用して構成可能です。claim_patterns.principal
を使用してサブストリングを抽出するためのオプションの正規表現を構成できます。 groups
- (オプション、JSON 配列) ユーザーのグループメンバーシップを含みます。この値は、
claims.groups
レルム設定を使用して構成可能です。claim_patterns.groups
を使用してサブストリング値を抽出するためのオプションの正規表現を構成できます。 name
- (オプション、文字列) トークンの主題を識別する人間が読める識別子を含みます。この値は、
claims.name
レルム設定を使用して構成可能です。claim_patterns.name
を使用してサブストリング値を抽出するためのオプションの正規表現を構成できます。 mail
- (オプション、文字列) ユーザーに関連付けるメールアドレスを含みます。この値は、
claims.mail
レルム設定を使用して構成可能です。claim_patterns.mail
を使用してサブストリング値を抽出するためのオプションの正規表現を構成できます。 dn
- (オプション、文字列) ユーザーまたはグループを一意に識別するユーザーの識別名 (DN) を含みます。この値は、
claims.dn
レルム設定を使用して構成可能です。claim_patterns.dn
を使用してサブストリング値を抽出するためのオプションの正規表現を構成できます。
JWT レルムの認可
JWT レルムは、ロールマッピング API を使用して作成または更新する認可をサポートしています。また、別のレルムに認可を委任することもできます。これらの方法を同時に使用することはできないため、環境に最適な方法を選択してください。
JWT レルムでは、role_mapping.yml
ファイルを使用してロールをマッピングすることはできません。
ロールマッピング API での認可
ロールマッピングを定義するために create or update role mappings API を使用できます。これにより、ユーザーのユーザー名、グループ、またはその他のメタデータに基づいて、どのロールが各ユーザーに割り当てられるべきかを決定します。
Python
resp = client.security.put_role_mapping(
name="jwt1_users",
refresh=True,
roles=[
"user"
],
rules={
"all": [
{
"field": {
"realm.name": "jwt1"
}
},
{
"field": {
"username": "principalname1"
}
},
{
"field": {
"dn": "CN=Principal Name 1,DC=example.com"
}
},
{
"field": {
"groups": "group1"
}
},
{
"field": {
"metadata.jwt_claim_other": "other1"
}
}
]
},
enabled=True,
)
print(resp)
Js
const response = await client.security.putRoleMapping({
name: "jwt1_users",
refresh: "true",
roles: ["user"],
rules: {
all: [
{
field: {
"realm.name": "jwt1",
},
},
{
field: {
username: "principalname1",
},
},
{
field: {
dn: "CN=Principal Name 1,DC=example.com",
},
},
{
field: {
groups: "group1",
},
},
{
field: {
"metadata.jwt_claim_other": "other1",
},
},
],
},
enabled: true,
});
console.log(response);
コンソール
PUT /_security/role_mapping/jwt1_users?refresh=true
{
"roles" : [ "user" ],
"rules" : { "all" : [
{ "field": { "realm.name": "jwt1" } },
{ "field": { "username": "principalname1" } },
{ "field": { "dn": "CN=Principal Name 1,DC=example.com" } },
{ "field": { "groups": "group1" } },
{ "field": { "metadata.jwt_claim_other": "other1" } }
] },
"enabled": true
}
この API を JWT レルムで使用する場合、ロールマッピングに利用可能なクレームは次のとおりです:
principal
- (必須、文字列) Elasticsearch ユーザーのユーザー名として使用されるプリンシパルクレーム。
dn
- (オプション、文字列) Elasticsearch ユーザーの DN として使用される識別名 (DN)。
groups
- (オプション、文字列) Elasticsearch ユーザーのグループリストとして使用されるカンマ区切りの値 (CSV) リスト。
metadata
- (オプション、オブジェクト) ユーザーに関する追加のメタデータ。文字列、整数、ブール値、コレクションなど、Elasticsearch ユーザーのメタデータとして使用されます。これらの値は
metadata.jwt_claim_<key>
=<value>
の形式でキーと値のペアとしてフォーマットされます。
別のレルムへの JWT 認可の委任
JWT レルムから他のレルムに 認可を委任 する場合、ロールルックアップに利用可能なクレームは principal
のみです。JWT レルムから別のレルムにロールの割り当てとルックアップを委任する場合、dn
、groups
、mail
、metadata
、および name
のクレームは Elasticsearch ユーザーの値に使用されません。JWT principal
クレームのみが委任された認可レルムに渡されます。認可のために委任されたレルムは、JWT レルムではなく、すべての Elasticsearch ユーザーの値を設定する責任を負います。
以下の例は、JWT レルムから複数の他のレルムに委任認可を定義する方法を示しています。jwt2
という名前の JWT レルムが複数のレルムに認可を委任しています:
Yaml
xpack.security.authc.realms.jwt.jwt2.authorization_realms: file1,native1,ldap1,ad1
create or update role mappings API を使用して、認可レルムにロールをマッピングできます。以下の例は、native1
レルムの principalname1
JWT プリンシパルにロールをマッピングします。
Python
resp = client.security.put_role_mapping(
name="native1_users",
refresh=True,
roles=[
"user"
],
rules={
"all": [
{
"field": {
"realm.name": "native1"
}
},
{
"field": {
"username": "principalname1"
}
}
]
},
enabled=True,
)
print(resp)
Js
const response = await client.security.putRoleMapping({
name: "native1_users",
refresh: "true",
roles: ["user"],
rules: {
all: [
{
field: {
"realm.name": "native1",
},
},
{
field: {
username: "principalname1",
},
},
],
},
enabled: true,
});
console.log(response);
コンソール
PUT /_security/role_mapping/native1_users?refresh=true
{
"roles" : [ "user" ],
"rules" : { "all" : [
{ "field": { "realm.name": "native1" } },
{ "field": { "username": "principalname1" } }
] },
"enabled": true
}
jwt2
がプリンシパル principalname1
の JWT でクライアントを正常に認証し、native1
のようなリストされたレルムに認可を委任した場合、そのレルムは Elasticsearch ユーザーの値をルックアップできます。この定義されたロールマッピングにより、レルムは native1
レルムにリンクされたこのロールマッピングルールをルックアップすることもできます。
JWT レルムユーザーに run_as 特権を適用する
Elasticsearch は、ロールマッピングまたは委任された認可を通じて JWT ユーザーのロールを取得できます。どのオプションを選択しても、ユーザーが「他のユーザーとして実行する」ために認証されたリクエストを送信できるように、run_as
特権 をロールに適用できます。別のユーザーとしてリクエストを送信するには、リクエストに es-security-runas-user
ヘッダーを含めます。リクエストは、そのユーザーから発行されたかのように実行され、Elasticsearch はそのユーザーのロールを使用します。
例えば、ユーザー名が user123_runas
のユーザーがいると仮定します。次のリクエストは、jwt_role1
という名前のユーザーロールを作成します。これは、run_as
ユーザーを user123_runas
ユーザー名で指定します。jwt_role1
ロールを持つ任意のユーザーは、指定された run_as
ユーザーとしてリクエストを発行できます。
Python
resp = client.security.put_role(
name="jwt_role1",
refresh=True,
cluster=[
"manage"
],
indices=[
{
"names": [
"*"
],
"privileges": [
"read"
]
}
],
run_as=[
"user123_runas"
],
metadata={
"version": 1
},
)
print(resp)
Js
const response = await client.security.putRole({
name: "jwt_role1",
refresh: "true",
cluster: ["manage"],
indices: [
{
names: ["*"],
privileges: ["read"],
},
],
run_as: ["user123_runas"],
metadata: {
version: 1,
},
});
console.log(response);
コンソール
POST /_security/role/jwt_role1?refresh=true
{
"cluster": ["manage"],
"indices": [ { "names": [ "*" ], "privileges": ["read"] } ],
"run_as": [ "user123_runas" ],
"metadata" : { "version" : 1 }
}
特定のレルムのユーザーにロールをマッピングできます。次のリクエストは、jwt_role1
レルムのユーザー名 user2
に jwt2
ロールをマッピングします。これは、Elasticsearch が jwt2
レルムを使用して user2
という名前のユーザーを認証することを意味します。user2
が jwt_role1
ロールを持っているため、run_as
特権を含む user123_runas
ユーザーのロールマッピングを取得し、そのユーザーのロールを使用してリクエストを送信します。
Python
resp = client.security.put_role_mapping(
name="jwt_user1",
refresh=True,
roles=[
"jwt_role1"
],
rules={
"all": [
{
"field": {
"realm.name": "jwt2"
}
},
{
"field": {
"username": "user2"
}
}
]
},
enabled=True,
metadata={
"version": 1
},
)
print(resp)
Js
const response = await client.security.putRoleMapping({
name: "jwt_user1",
refresh: "true",
roles: ["jwt_role1"],
rules: {
all: [
{
field: {
"realm.name": "jwt2",
},
},
{
field: {
username: "user2",
},
},
],
},
enabled: true,
metadata: {
version: 1,
},
});
console.log(response);
コンソール
POST /_security/role_mapping/jwt_user1?refresh=true
{
"roles": [ "jwt_role1"],
"rules" : { "all" : [
{ "field": { "realm.name": "jwt2" } },
{ "field": { "username": "user2" } }
] },
"enabled": true,
"metadata" : { "version" : 1 }
}
ロールをマッピングした後、JWT を使用して Elasticsearch に 認証された呼び出し を行い、ES-Client-Authentication
ヘッダーを含めます:
curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiZXMwMSIsImVzMDIiLCJlczAzIl0sInN1YiI6InVzZXIyIiwiaXNzIjoibXktaXNzdWVyIiwiZXhwIjo0MDcwOTA4ODAwLCJpYXQiOjk0NjY4NDgwMCwiZW1haWwiOiJ1c2VyMkBzb21ldGhpbmcuZXhhbXBsZS5jb20ifQ.UgO_9w--EoRyUKcWM5xh9SimTfMzl1aVu6ZBsRWhxQA" -H "ES-Client-Authentication: sharedsecret test-secret" https://localhost:9200/_security/_authenticate
レスポンスには、リクエストを送信したユーザー (user2
) が含まれ、JWT レルムでこのユーザーにマッピングされた jwt_role1
ロールが含まれます:
{"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"[email protected]",
"metadata":{"jwt_claim_email":"[email protected]","jwt_claim_aud":["es01","es02","es03"],
"jwt_claim_sub":"user2","jwt_claim_iss":"my-issuer"},"enabled":true,"authentication_realm":
{"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"jwt2","type":"jwt"},"authentication_type":"realm"}
%
リクエストを run_as
ユーザーとして指定したい場合は、es-security-runas-user
ヘッダーにリクエストを送信したいユーザーの名前を含めます。次のリクエストは user123_runas
ユーザーを使用します:
curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiZXMwMSIsImVzMDIiLCJlczAzIl0sInN1YiI6InVzZXIyIiwiaXNzIjoibXktaXNzdWVyIiwiZXhwIjo0MDcwOTA4ODAwLCJpYXQiOjk0NjY4NDgwMCwiZW1haWwiOiJ1c2VyMkBzb21ldGhpbmcuZXhhbXBsZS5jb20ifQ.UgO_9w--EoRyUKcWM5xh9SimTfMzl1aVu6ZBsRWhxQA" -H "ES-Client-Authentication: sharedsecret test-secret" -H "es-security-runas-user: user123_runas" https://localhost:9200/_security/_authenticate
レスポンスでは、user123_runas
ユーザーがリクエストを送信したことがわかり、Elasticsearch は jwt_role1
ロールを使用しました:
{"username":"user123_runas","roles":["jwt_role1"],"full_name":null,"email":null,"metadata":{},
"enabled":true,"authentication_realm":{"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"native",
"type":"native"},"authentication_type":"realm"}%
PKC JWKS のリロード
JWT 認証は、PKC (公開鍵暗号) または HMAC アルゴリズムを使用した署名検証をサポートします。
PKC JSON Web Token キーセット (JWKS) には、公開 RSA および EC キーが含まれる場合があります。HMAC JWKS または HMAC UTF-8 JWK には秘密鍵が含まれます。JWT 発行者は通常、PKC JWKS をより頻繁に回転させます (例えば、毎日)。これは、RSA および EC 公開鍵が HMAC のような秘密鍵よりも配布が容易に設計されているためです。
JWT レルムは、起動時に PKC JWKS と HMAC JWKS または HMAC UTF-8 JWK をロードします。JWT レルムは、ランタイムで PKC JWKS の内容を再ロードすることもできます。再ロードは、署名検証の失敗によってトリガーされます。
HMAC JWKS または HMAC UTF-8 JWK の再ロードは、現時点ではサポートされていません。
ロード失敗、解析エラー、および構成エラーは、ノードの起動 (および再起動) を妨げます。ただし、ランタイム PKC 再ロードエラーと回復は、優雅に処理されます。
すべての他の JWT レルム検証は、署名失敗が PKC JWKS の再ロードをトリガーする前にチェックされます。単一の Elasticsearch ノードで同時に複数の JWT 認証署名失敗が発生した場合、再ロードは外部に送信される再ロードを減らすために結合されます。
JWT 署名の失敗がトリガーされた場合、別々の再ロード要求は結合できません:
- 異なる Elasticsearch ノードでの PKC JWKS の再ロード
- 同じ Elasticsearch ノードで異なる時間に PKC JWKS の再ロード
クライアント認証を有効にすること (client_authentication.type
) は強く推奨されます。信頼されたクライアントアプリケーションとレルム固有の JWT ユーザーのみが PKC 再ロードの試行をトリガーできます。さらに、次の JWT セキュリティ設定 を構成することを推奨します:
allowed_audiences
allowed_clock_skew
allowed_issuer
allowed_signature_algorithms
HMAC UTF-8 キーで JWT レルムに認可する
次の設定は、JWT 発行者、Elasticsearch、および Elasticsearch のクライアントに関するものです。例の HMAC キーは、HMAC と互換性のある OIDC 形式です。キーのバイトは、UNICODE 文字の UTF-8 エンコーディングです。
HMAC UTF-8 キーは、同じキー強度を達成するために HMAC ランダムバイトキーよりも長くする必要があります。
JWT 発行者
次の値は、特注の JWT 発行者に関するものです。
Js
Issuer: iss8
Audiences: aud8
Algorithms: HS256
HMAC UTF-8: hmac-oidc-key-string-for-hs256-algorithm
JWT レルム設定
JWT レルムを定義するには、次のレルム設定を elasticsearch.yml
に追加します。
Yaml
xpack.security.authc.realms.jwt.jwt8.order: 8
xpack.security.authc.realms.jwt.jwt8.allowed_issuer: iss8
xpack.security.authc.realms.jwt.jwt8.allowed_audiences: [aud8]
xpack.security.authc.realms.jwt.jwt8.allowed_signature_algorithms: [HS256]
xpack.security.authc.realms.jwt.jwt8.claims.principal: sub
xpack.security.authc.realms.jwt.jwt8.client_authentication.type: shared_secret
Elastic Cloud では、レルムの順序は 2 から始まります。0 と 1 は、Elastic Cloud のレルムチェーンで予約されています。 |
JWT レルムのセキュア設定
レルム設定を定義した後、elasticsearch-keystore
ツールを使用して、Elasticsearch キーストアに次のセキュア設定を追加します。Elastic Cloud では、デプロイメントの セキュリティ の下で Elasticsearch キーストアの設定を定義します。
Yaml
xpack.security.authc.realms.jwt.jwt8.hmac_key: hmac-oidc-key-string-for-hs256-algorithm
xpack.security.authc.realms.jwt.jwt8.client_authentication.shared_secret: client-shared-secret-string
JWT レルムのロールマッピングルール
次のリクエストは、ユーザー principalname1
のために jwt8
レルムで Elasticsearch のロールマッピングを作成します:
Python
resp = client.security.put_role_mapping(
name="jwt8_users",
refresh=True,
roles=[
"user"
],
rules={
"all": [
{
"field": {
"realm.name": "jwt8"
}
},
{
"field": {
"username": "principalname1"
}
}
]
},
enabled=True,
)
print(resp)
Js
const response = await client.security.putRoleMapping({
name: "jwt8_users",
refresh: "true",
roles: ["user"],
rules: {
all: [
{
field: {
"realm.name": "jwt8",
},
},
{
field: {
username: "principalname1",
},
},
],
},
enabled: true,
});
console.log(response);
コンソール
PUT /_security/role_mapping/jwt8_users?refresh=true
{
"roles" : [ "user" ],
"rules" : { "all" : [
{ "field": { "realm.name": "jwt8" } },
{ "field": { "username": "principalname1" } }
] },
"enabled": true
}
リクエストヘッダー
次のヘッダー設定は、Elasticsearch クライアントに関するものです。
Js
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
ES-Client-Authentication: SharedSecret client-shared-secret-string
このヘッダーを使用して、curl
リクエストでElasticsearchに認証された呼び出しを行うことができます。ベアラートークンとクライアント認証トークンは、-H
オプションを使用して別々のヘッダーとして指定する必要があります:
curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY" -H "ES-Client-Authentication: SharedSecret client-shared-secret-string" https://localhost:9200/_security/_authenticate
JWTレルムでロールマッピングを使用した場合、レスポンスにはユーザーのusername
、そのroles
、ユーザーに関するメタデータ、およびJWTレルム自体の詳細が含まれます。
{"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"[email protected]",
"metadata":{"jwt_claim_email":"[email protected]","jwt_claim_aud":["es01","es02","es03"],
"jwt_claim_sub":"user2","jwt_claim_iss":"my-issuer"},"enabled":true,"authentication_realm":
{"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"jwt2","type":"jwt"},"authentication_type":"realm"}