JWT 身份验证
可以将 Elasticsearch 配置为信任外部服务签发的 JSON Web Token (JWT) 作为承载令牌 (bearer token) 进行身份验证。
使用 JWT 域向 Elasticsearch 进行身份验证时,连接到 Elasticsearch 的客户端与代表其运行请求的用户是有区别的。JWT 用于验证用户,而单独的凭据用于验证客户端。
JWT 域支持两种令牌类型:id_token(默认)和 access_token
id_token:应用程序通过身份验证流程(例如 OpenID Connect (OIDC))对用户进行身份验证和识别,然后使用符合 OIDC ID 令牌规范的 JSON Web Token (JWT) 代表已身份验证的用户访问 Elasticsearch。此选项适用于使用 Elastic Stack 8.2+ 的部署。access_token:应用程序使用其自身的身份(编码为 JWT)访问 Elasticsearch。例如,应用程序使用 OAuth2 客户端凭据流程向中央身份平台验证自身,然后使用生成的基于 JWT 的访问令牌连接到 Elasticsearch。此选项适用于使用 Elastic Stack 8.7+ 的部署。
单个 JWT 域只能使用一种令牌类型。要处理这两种令牌类型,您必须配置至少两个 JWT 域。您应根据使用场景仔细选择令牌类型,因为它会影响验证的执行方式。
JWT 域会根据其配置的令牌类型验证传入的 JWT。这两种类型的 JSON Web Token (JWT) 都必须包含以下 5 项信息。虽然基于 OIDC 规范的 ID 令牌对哪些声明应提供这些信息有着严格的规则,但访问令牌允许某些声明是可配置的。
声明
| 信息 | ID 令牌 | 访问令牌 |
|---|---|---|
| 签发者 (Issuer) | iss |
iss |
| 主题 | sub |
默认为 sub,但如果 sub 不存在,可以回退到另一个声明 |
| 受众 (Audiences) | aud |
默认为 aud,但如果 aud 不存在,可以回退到另一个声明 |
| 签发时间 | iat |
iat |
| 过期时间 | exp |
exp |
此外,对于 ID 令牌,如果存在 nbf 和 auth_time 声明,Elasticsearch 还会验证它们。但对于访问令牌,这些声明会被忽略。
总体而言,访问令牌类型具有更宽松的验证规则,适用于更通用的 JWT(包括自签名 JWT)。
Elasticsearch 中的 JWT 身份验证源自 OIDC 用户工作流,其中不同的令牌可以由 OIDC 提供商 (OP) 签发,包括 ID 令牌。来自 OIDC 提供商的 ID 令牌是结构明确的 JSON Web Token (JWT),并且始终应与令牌类型为 id_token 的 JWT 域兼容。ID 令牌的主题 (subject) 声明代表最终用户。这意味着 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 格式并满足上表中的相关要求。
要使用 JWT 身份验证,请在 elasticsearch.yml 文件中创建该域,以在 Elasticsearch 身份验证链中对其进行配置。
JWT 域包含一些必需设置以及可选设置,这些设置在 JWT 域设置中有所说明。
JWT 域默认已启用客户端身份验证。禁用客户端身份验证是可行的,但强烈不建议这样做。
- 使用您偏好的令牌类型配置域
以下示例包含了最常见的设置,并不适用于所有使用场景
xpack.security.authc.realms.jwt.jwt1:
order: 3
token_type: id_token
client_authentication.type: shared_secret
allowed_issuer: "<example-issuer-url>/jwt/"
allowed_audiences: [ "8fb85eba-979c-496c-8ae2-a57fde3f12d0" ]
allowed_signature_algorithms: [RS256,HS256]
pkc_jwkset_path: jwt/jwkset.json
claims.principal: sub
order- 将域的
order指定为3,这指示在对用户进行身份验证时检查已配置域的顺序。域按升序咨询,其中具有最低 order 值的域将最先被咨询。 token_type- 指示域将传入的 JWT 作为 ID 令牌 (
id_token) 进行处理和验证。 client_authentication.type- 将客户端身份验证类型指定为
shared_secret,这意味着客户端使用 HTTP 请求标头进行身份验证,该标头必须与预先配置的密钥值相匹配。客户端必须在每个请求的ES-Client-Authentication标头中并使用SharedSecret方案提供此共享密钥。标头值必须与域的client_authentication.shared_secret区分大小写地精确匹配。 allowed_issuer- 为您的 JWT 签发者设置可验证的标识符。该值通常是 URL、UUID 或其他区分大小写的字符串值。
allowed_audiences- 指定域将允许的 JWT 受众列表。这些值通常是 URL、UUID 或其他区分大小写的字符串值。
allowed_signature_algorithms- 指示 Elasticsearch 应使用
RS256或HS256签名算法来验证来自 JWT 签发者的 JWT 的签名。 pkc_jwkset_path- 包含公钥材料的 JSON Web Key Set (JWKS) 的文件名或 URL,JWT 域使用该公钥材料来验证令牌签名。如果不以
https开头,则该值将被视为文件名。文件名是相对于 Elasticsearch 配置目录进行解析的。如果提供了 URL,则它必须以https://开头(不支持http://)。Elasticsearch 会自动缓存 JWK 集,并在签名验证失败时尝试刷新 JWK 集,因为这可能表明 JWT 提供商已轮换签名密钥。后台 JWKS 重新加载也可以通过设置pkc_jwkset_reload.enabled进行配置。这可以确保自动发现已轮换的密钥并将其用于验证 JWT 签名。 pkc_jwkset_reload.enabled- 指示是否启用 JWKS 后台重新加载。默认为
false。 pkc_jwkset_reload.file_interval- 指定基于文件的 JWKS 的重新加载间隔。默认为
5m。 pkc_jwkset_reload.url_interval_min- 指定基于 URL 的 JWKS 的最小重新加载间隔。
Expires和Cache-ControlHTTP 响应标头告知重新加载间隔。此配置设置是考虑值的下限,在缺乏有用响应标头的情况下,也是默认间隔。默认为1h。 pkc_jwkset_reload.url_interval_max- 指定基于 URL 的 JWKS 的最大重新加载间隔。此配置设置是从标头响应中考虑值的上限 (
5d)。 claims.principal-
包含用户 Principal(主体/用户名)的 JWT 声明名称。默认为
username。
以下是用于配置 JWT 域以处理访问令牌的示例代码段
xpack.security.authc.realms.jwt.jwt2:
order: 4
token_type: access_token
client_authentication.type: shared_secret
allowed_issuer: "<example-issuer-url>/jwt/"
allowed_subjects: [ "123456-compute@admin.example.com" ]
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: "<example-idp-url>/.well-known/configuration"
fallback_claims.sub: client_id
fallback_claims.aud: scope
claims.principal: sub
token_type- 指示域将传入的 JWT 作为访问令牌 (
access_token) 进行处理和验证。 allowed_subjects- 指定域将允许的 JWT 主题列表。这些值通常是 URL、UUID 或其他区分大小写的字符串值。
allowed_subject_patterns- 类似于
allowed_subjects,但它接受允许的 JWT 主题的 Lucene 正则表达式 和通配符列表。通配符使用*和?特殊字符(通过\转义)分别表示“任意字符串”和“任意单字符”,例如a?\**匹配a1*和ab*whatever,但不匹配a、abc或abc*(在 Java 字符串中,\本身必须通过另一个\转义)。Lucene 正则表达式必须括在/之间,例如/https?://[^/]+/?/匹配不带路径组件的任何 http 或 https URL(匹配https://esdocs.cn/但不匹配https://esdocs.cn/docs)。
当 token_type 为 access_token 时,必须指定 allowed_subjects 或 allowed_subject_patterns 设置中的至少一个(且不能为空)。
当同时指定了 allowed_subjects 和 allowed_subject_patterns 设置时,如果传入 JWT 的 sub 声明匹配这两个列表中的任何一个,则被接受。
required_claims- 指定要对 JWT 执行的附加验证的键/值对列表。值可以为字符串或字符串数组。
fallback_claims.sub- 如果不存在
sub声明,用于提取主题信息的 JWT 声明名称。仅当token_type为access_token时,此设置才可用。回退机制应用于使用sub声明的所有地方。在上文代码段中,这意味着如果sub不存在,claims.principal也将回退到client_id。 fallback_claims.aud- 如果不存在
aud声明,用于提取受众信息的 JWT 声明名称。仅当token_type为access_token时,此设置才可用。回退机制应用于使用aud声明的所有地方。
向 Elasticsearch keystore 添加安全设置
适用于
client_authentication.type的shared_secret值(
xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret)适用于
allowed_signature_algorithms的 HMAC 密钥(
xpack.security.authc.realms.jwt.jwt1.hmac_jwkset)此设置可以是 JWKS 的路径,JWKS 是一组经过 JSON 编码的密钥资源的集合。将内容加载到 Elasticsearch keystore 后,可以删除该文件。
推荐使用 JWKS。但是,您可以使用 xpack.security.authc.realms.jwt.jwt1.hmac_key 添加字符串格式的 HMAC 密钥。此格式与 HMAC UTF-8 密钥兼容,但仅支持无属性的单密钥。一次只能使用一种 HMAC 格式(hmac_jwkset 或 hmac_key)。
JWT 可以解析为三个部分
- Header
- 提供有关如何验证令牌的信息。
- 声明
- 包含有关调用用户或应用程序的数据。
- 特征码
- 用于验证令牌的数据。
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。
令牌包含多个声明,这些声明提供有关签发令牌的用户以及令牌本身的信息。根据令牌类型的不同,这些信息可以选择性地通过不同的声明来识别。
以下声明由 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 域默认接受所有主题。类型为 access_token 的 JWT 域必须指定allowed_subjects设置,且主题值必须与 allowed_subjects 设置中任何 CSV 值区分大小写精确匹配。类型为 access_token 的 JWT 域可以指定一个回退声明,在不存在sub声明的地方使用该声明。 aud- (必需*,字符串) 指示 ID 令牌面向的受众,表示为逗号分隔值 (CSV)。其中一个值必须与
allowed_audiences设置中的任何 CSV 值区分大小写精确匹配。如果 JWT 域的类型为id_token,则此声明是强制性的。类型为access_token的 JWT 域可以指定一个回退声明,在不存在aud声明的地方使用该声明。 exp- (必需,整数) ID 令牌的过期时间,表示为自 Epoch 纪元以来的 UTC 秒数。
iat- (必需,整数) ID 令牌的签发时间,表示为自 Epoch 纪元以来的 UTC 秒数。
nbf- (可选,整数) 指示不得接受该 JWT 之前的时间,表示为自 Epoch 纪元以来的 UTC 秒数。此声明是可选的。如果存在,类型为
id_token的 JWT 域将对其进行验证,而类型为access_token的 JWT 域将忽略它。 auth_time- (可选,整数) 用户向 JWT 签发者进行身份验证的时间,表示为自 Epoch 纪元以来的 UTC 秒数。此声明是可选的。如果存在,类型为
id_token的 JWT 域将对其进行验证,而类型为access_token的 JWT 域将忽略它。
Elasticsearch 将 JWT 声明用于以下设置。
principal- (必需,字符串) 包含用户的 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 组映射到角色
有关详细信息,请参阅将用户和组映射到角色。
您无法使用 role_mapping.yml 文件在 JWT 域中映射角色。
您可以使用 创建或更新角色映射 API 来定义角色映射,根据用户名、组或其他元数据确定应将哪些角色分配给每个用户。
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
}
- 映射名称。
- 要映射到的 Elastic Stack 角色。
- 指定要从中映射的 JWT 角色的规则。
realm.name可以是仅包含字母数字字符、下划线和连字符的任何字符串。
如果您在 JWT 域中使用此 API,则以下声明可用于角色映射
principal- (必需,字符串) 用作 Elasticsearch 用户的用户名的 Principal 声明。
dn- (可选,字符串) 用作 Elasticsearch 用户的 DN 的专有名称 (DN)。
groups- (可选,字符串) 用作 Elasticsearch 用户的组列表的逗号分隔值 (CSV) 列表。
metadata- (可选,对象) 有关用户的附加元数据,例如用作 Elasticsearch 用户的元数据的字符串、整数、布尔值和集合。这些值是格式化为
metadata.jwt_claim_<key>=<value>的键值对。
如果您从 JWT 域委托授权给其他域,则仅 principal 声明可用于角色查找。当将角色的分配和查找从 JWT 域委托给另一个域时,dn、groups、mail、metadata 和 name 的声明不会用于 Elasticsearch 用户的值。只有 JWT principal 声明会被传递到被委托的授权域。被委托进行授权的域(而不是 JWT 域)将负责填充所有 Elasticsearch 用户的值。
以下示例显示如何在 elasticsearch.yml 文件中定义从 JWT 域到多个其他域的委托授权。名为 jwt2 的 JWT 域正在将授权委托给多个域
xpack.security.authc.realms.jwt.jwt2.authorization_realms: file1,native1,ldap1,ad1
然后,您可以使用创建或更新角色映射 API 将角色映射到授权域。以下示例为 principalname1 JWT principal 映射 native1 域中的角色。
PUT /_security/role_mapping/native1_users?refresh=true
{
"roles" : [ "user" ],
"rules" : { "all" : [
{ "field": { "realm.name": "native1" } },
{ "field": { "username": "principalname1" } }
] },
"enabled": true
}
如果域 jwt2 成功使用 Principal principalname1 的 JWT 验证了客户端,并将授权委托给列出的域之一(例如 native1),则该域可以查找 Elasticsearch 用户的值。通过此定义的角色映射,该域还可以查找链接到域 native1 的此角色映射规则。
Elasticsearch 可以通过角色映射或委托授权来检索 JWT 用户的角色。无论选择哪种选项,您都可以将 run_as 权限应用于角色,以便用户可以提交已身份验证的请求以“以”另一个用户的身份运行(run as)。要作为另一个用户提交请求,请在您的请求中包含 es-security-runas-user 标头。请求的运行方式就如同它们是由该用户发起的,并且 Elasticsearch 会使用他们的角色。
例如,假设有一个用户名为 user123_runas 的用户。以下请求创建一个名为 jwt_role1 的用户角色,该角色指定了一个用户名为 user123_runas 的 run_as 用户。具有 jwt_role1 角色的任何用户都可以作为指定的 run_as 用户发起请求。
POST /_security/role/jwt_role1?refresh=true
{
"cluster": ["manage"],
"indices": [ { "names": [ "*" ], "privileges": ["read"] } ],
"run_as": [ "user123_runas" ],
"metadata" : { "version" : 1 }
}
然后,您可以将该角色映射到特定域中的用户。以下请求将 jwt_role1 角色映射到 jwt2 JWT 域中用户名为 user2 的用户。这意味着 Elasticsearch 将使用 jwt2 域来验证名为 user2 的用户。由于 user2 拥有的角色(jwt_role1 角色)包含 run_as 权限,Elasticsearch 会检索 user123_runas 用户的角色映射,并使用该用户的角色来提交请求。
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://:9200/_security/_authenticate
响应包含提交请求的用户 (user2),包括您在 JWT 域中映射到此用户的 jwt_role1 角色
{"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"user2@something.example.com",
"metadata":{"jwt_claim_email":"user2@something.example.com","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://: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"}%
JWT 身份验证支持使用 PKC(公钥加密)或 HMAC 算法进行签名验证。
PKC JSON Web Token Key Sets (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 内容;签名验证失败会触发重新加载。
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_audiencesallowed_clock_skewallowed_issuerallowed_signature_algorithms
以下设置适用于 JWT 签发者、Elasticsearch 和 Elasticsearch 客户端。示例 HMAC 密钥采用了与 HMAC 兼容的 OIDC 格式。密钥字节是 UNICODE 字符的 UTF-8 编码。
HMAC UTF-8 密钥需要比 HMAC 随机字节密钥更长,才能达到相同的密钥强度。
以下值适用于定制的 JWT 签发者。
Issuer: iss8
Audiences: aud8
Algorithms: HS256
HMAC UTF-8: hmac-oidc-key-string-for-hs256-algorithm
要定义 JWT 域,请将以下域设置添加到 elasticsearch.yml。
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 的域链中被保留。
定义域设置后,使用 elasticsearch-keystore 工具将以下安全设置添加到 Elasticsearch keystore。在 Elastic Cloud 中,您可以在部署中的 Security(安全)下为 Elasticsearch keystore 定义设置。
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
以下请求在 jwt8 域中为用户 principalname1 创建 Elasticsearch 角色映射
PUT /_security/role_mapping/jwt8_users?refresh=true
{
"roles" : [ "user" ],
"rules" : { "all" : [
{ "field": { "realm.name": "jwt8" } },
{ "field": { "username": "principalname1" } }
] },
"enabled": true
}
以下标头设置适用于 Elasticsearch 客户端。
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
ES-Client-Authentication: SharedSecret client-shared-secret-string
您可以在 curl 请求中使用此标头来发起对 Elasticsearch 的身份验证调用。承载令牌 (bearer token) 和客户端授权令牌必须都作为独立的标头通过 -H 选项指定
curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY" -H "ES-Client-Authentication: SharedSecret client-shared-secret-string" https://:9200/_security/_authenticate
如果您在 JWT 域中使用了角色映射,则响应将包含用户的 username、其 roles、关于用户的元数据以及有关 JWT 域本身的详细信息。
{"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"user2@something.example.com",
"metadata":{"jwt_claim_email":"user2@something.example.com","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"}