JWT 身份验证编辑

可以将 Elasticsearch 配置为信任从外部服务颁发的 JSON Web 令牌 (JWT) 作为承载令牌进行身份验证。

当使用 JWT 领域对 Elasticsearch 进行身份验证时,连接到 Elasticsearch 的*客户端*与应代表其运行请求的*用户*之间存在区别。JWT 对用户进行身份验证,而单独的凭据对客户端进行身份验证。

JWT 领域支持两种令牌类型,id_token(默认)和 access_token。它们分别设计用于以下两种场景

  1. id_token - 应用程序使用身份验证流程(例如 OpenID Connect (OIDC))对用户进行身份验证和识别,然后使用符合 OIDC ID 令牌规范的 JSON Web 令牌 (JWT) 代表已验证的用户访问 Elasticsearch。
  2. access_token - 应用程序使用其自身的身份(编码为 JWT)访问 Elasticsearch,例如,应用程序使用 OAuth2 客户端凭据流程向中央身份平台进行身份验证,然后使用生成的基于 JWT 的访问令牌连接到 Elasticsearch。

单个 JWT 领域只能使用一种令牌类型。要处理这两种令牌类型,您必须至少配置两个 JWT 领域。您应该根据用例仔细选择令牌类型,因为它会影响验证的执行方式。

JWT 领域根据其配置的令牌类型验证传入的 JWT。两种类型的 JSON Web 令牌 (JWT) 都必须包含以下 5 条信息。虽然基于 OIDC 规范的 ID 令牌对哪些声明应提供这些信息有严格的规定,但访问令牌允许某些声明是可配置的。

声明

信息

ID 令牌

访问令牌

颁发者

iss

iss

主题

sub

默认为 sub,但如果 sub 不存在,则可以回退到另一个声明

受众

aud

默认为 aud,但如果 aud 不存在,则可以回退到另一个声明

颁发时间

iat

iat

到期时间

exp

exp

此外,如果存在 nbfauth_time 声明,Elasticsearch 还会验证 ID 令牌的这些声明。但访问令牌会忽略这些声明。

总的来说,访问令牌类型的验证规则更宽松,适用于更通用的 JWT,包括自签名 JWT。

来自 OIDC 工作流的 ID 令牌编辑

Elasticsearch 中的 JWT 身份验证源自 OIDC 用户工作流,其中 OIDC 提供程序 (OP) 可以颁发不同的令牌,包括 ID 令牌。来自 OIDC 提供程序的 ID 令牌是定义明确的 JSON Web 令牌 (JWT),并且应始终与 id_token 令牌类型的 JWT 领域兼容。ID 令牌的主题声明表示最终用户。这意味着 ID 令牌通常会有许多允许的主题。因此,id_token 令牌类型的 JWT 领域*不*强制执行 allowed_subjects(或 allowed_subject_patterns)验证。

因为 JWT 是在 Elasticsearch 之外获取的,所以您可以定义自定义工作流,而不是使用 OIDC 工作流。但是,JWT 格式必须仍然是 JSON Web 签名 (JWS)。使用 OIDC ID 令牌验证规则验证 JWS 标头和 JWS 签名。

Elasticsearch 支持单独的 OpenID Connect 领域。对于 Elasticsearch 可以充当 OIDC RP 的任何用例,建议使用它。OIDC 领域是在 Kibana 中启用 OIDC 身份验证的唯一受支持方式。

使用 JWT 领域进行身份验证的用户可以选择使用 run_as 功能模拟另一个用户。另请参阅 run_as 特权应用于 JWT 领域用户

访问令牌编辑

获取访问令牌的常用方法是使用 OAuth2 客户端凭据流程。此流程的典型用法是应用程序获取自身的凭据。这是 access_token 令牌类型所针对的用例。此应用程序也可能为其最终用户获取 ID 令牌。为了防止最终用户 ID 令牌用于对为应用程序配置的 JWT 领域进行身份验证,当 JWT 领域的令牌类型为 access_token 时,我们强制执行 allowed_subjectsallowed_subject_patterns 验证。

并非每个访问令牌都格式化为 JSON Web 令牌 (JWT)。要使其与 JWT 领域兼容,它必须至少使用 JWT 格式并满足上表中的相关要求。

将 Elasticsearch 配置为使用 JWT 领域编辑

要使用 JWT 身份验证,请在 elasticsearch.yml 文件中创建领域,以在 Elasticsearch 身份验证链中对其进行配置。

JWT 领域有一些强制设置,以及 JWT 领域设置 中描述的可选设置。

默认情况下,JWT 领域启用了客户端身份验证。可以禁用客户端身份验证,但强烈建议不要这样做。

  1. 将您的 JWT 领域添加到 elasticsearch.yml 文件中。以下示例包含最常见的设置,这些设置并非适用于所有用例

    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
    指定领域 order3,这表示在对用户进行身份验证时检查已配置领域的顺序。按升序查询领域,首先查询顺序值最低的领域。
    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 应使用 RS256HS256 签名算法来验证 JWT 颁发者 JWT 的签名。
    pkc_jwkset_path
    包含 JWT 领域用于验证令牌签名的公钥材料的 JSON Web 密钥集 (JWKS) 的文件名或 URL。如果值不是以 https 开头,则将其视为文件名。文件名是相对于 Elasticsearch 配置目录解析的。如果提供了 URL,则它必须以 https:// 开头(不支持 http://)。Elasticsearch 会自动缓存 JWK 集,并会在签名验证失败时尝试刷新 JWK 集,因为这可能表明 JWT 提供程序已轮换签名密钥。
    claims.principal
    包含用户主体(用户名)的 JWT 声明的名称。

    以下是为处理访问令牌配置 JWT 领域的示例代码段

    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
    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://elastic.ac.cn/”,但不匹配“https://elastic.ac.cn/guide”)。

    token_typeaccess_token 时,必须至少指定 allowed_subjectsallowed_subject_patterns 设置之一(并且不能为空)。

    当同时指定了 allowed_subjectsallowed_subject_patterns 设置时,如果传入 JWT 的 sub 声明与这两个列表中的任何一个匹配,则接受该声明。

    required_claims
    指定要对 JWT 执行的其他验证的键/值对列表。这些值可以是字符串或字符串数组。
    fallback_claims.sub
    如果 sub 声明不存在,则用于提取主题信息的 JWT 声明的名称。此设置仅在 token_typeaccess_token 时可用。回退适用于使用 sub 声明的任何地方。在上面的代码段中,这意味着如果 sub 不存在,claims.principal 也将回退到 client_id
    fallback_claims.aud
    如果 aud 声明不存在,则用于提取受众信息的 JWT 声明的名称。此设置仅在 token_typeaccess_token 时可用。回退适用于使用 aud 声明的任何地方。
  2. 定义设置后,使用 elasticsearch-keystore 工具将安全设置的值存储在 Elasticsearch 密钥库中。

    1. 存储 client_authentication.typeshared_secret

      bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret
    2. 存储 allowed_signature_algorithms 的 HMAC 密钥,在示例中使用 HMAC SHA-256 算法 HS256

      bin/elasticsearch-keystore add-file xpack.security.authc.realms.jwt.jwt1.hmac_jwkset <path> 

      JWKS 的路径,它是 JSON 编码密钥集的资源。将内容加载到 Elasticsearch 密钥库后,可以删除该文件。

      建议使用 JWKS。但是,您可以使用以下命令添加字符串格式的 HMAC 密钥。此格式与 HMAC UTF-8 密钥兼容,但仅支持没有属性的单个密钥。您只能同时使用一种 HMAC 格式(hmac_jwksethmac_key)。

      bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.hmac_key

JWT 编码和验证编辑

JWT 可以解析为三个部分

标头
提供有关如何验证令牌的信息。
声明
包含有关调用用户或应用程序的数据。
签名
用于验证令牌的数据。
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 签名 (JWS),并且 JWS HeaderSignature 使用 OpenID Connect ID 令牌验证规则进行验证。某些验证可以通过JWT 领域设置进行自定义。

标头声明编辑

标头声明指示令牌类型和用于对令牌进行签名的算法。

alg
(必填,字符串)指示用于对令牌进行签名的算法,例如 HS256。该算法必须在领域的允许列表中。
typ
(可选,字符串)指示令牌类型,必须为 JWT

有效负载声明编辑

令牌包含多个声明,这些声明提供有关签发令牌的用户以及令牌本身的信息。根据令牌类型,可以选择使用不同的声明来标识这些信息。

JWT 有效负载声明编辑

以下声明由 OIDC ID 令牌规则的子集验证。

Elasticsearch 不验证 nonce 声明,但自定义 JWT 签发者可以添加随机 nonce 声明以在签名中引入熵。

您可以通过设置 allowed_clock_skew 来放宽对任何基于时间的声明的验证。此值设置在验证 JWT 的身份验证时间(auth_time)、创建时间(iat)、不早于时间(nbf)和到期时间(exp)之前允许的最大时钟偏差。

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 令牌的到期时间,以自纪元以来的 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
(必填,字符串)包含用户的 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 进行授权,或将授权委托给另一个领域。您不能同时使用这些方法,因此请选择最适合您的环境的方法。

您不能使用 role_mapping.yml 文件在 JWT 领域中映射角色。

使用角色映射 API 进行授权编辑

您可以使用创建或更新角色映射 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
}

如果在 JWT 领域中使用此 API,则以下声明可用于角色映射

principal
(必填,字符串)用作 Elasticsearch 用户用户名的 Principal 声明。
dn
(可选,字符串)用作 Elasticsearch 用户 DN 的专有名称 (DN)。
groups
(可选,字符串)用作 Elasticsearch 用户的组列表的逗号分隔值 (CSV) 列表。
metadata
(可选,对象)有关用户的其他元数据,例如用作 Elasticsearch 用户元数据的字符串、整数、布尔值和集合。这些值是格式为 metadata.jwt_claim_<key> = <value> 的键值对。

将 JWT 授权委托给另一个领域编辑

如果您从 JWT 领域将授权委托给其他领域,则只有 principal 声明可用于角色查找。将角色的分配和查找从 JWT 领域委托给另一个领域时,dngroupsmailmetadataname 的声明不会用作 Elasticsearch 用户的值。只有 JWT principal 声明会传递到委托的授权领域。负责授权的领域(而不是 JWT 领域)负责填充所有 Elasticsearch 用户的值。

以下示例显示了如何在 elasticsearch.yml 文件中定义从 JWT 领域到多个其他领域的委托授权。名为 jwt2 的 JWT 领域正在将授权委托给多个领域

xpack.security.authc.realms.jwt.jwt2.authorization_realms: file1,native1,ldap1,ad1

然后,您可以使用创建或更新角色映射 API将角色映射到授权领域。以下示例在 native1 领域中为 principalname1 JWT principal 映射角色。

PUT /_security/role_mapping/native1_users?refresh=true
{
  "roles" : [ "user" ],
  "rules" : { "all" : [
      { "field": { "realm.name": "native1" } },
      { "field": { "username": "principalname1" } }
  ] },
  "enabled": true
}

如果领域 jwt2 使用 JWT 成功地对 principal 为 principalname1 的客户端进行身份验证,并将授权委托给列出的领域之一(例如 native1),则该领域可以查找 Elasticsearch 用户的值。使用此定义的角色映射,该领域还可以查找链接到领域 native1 的此角色映射规则。

run_as 特权应用于 JWT 领域用户编辑

Elasticsearch 可以通过角色映射或委托授权来检索 JWT 用户的角色。无论您选择哪种选项,都可以将run_as 特权应用于角色,以便用户可以提交经过身份验证的请求以“作为”另一个用户运行。要作为另一个用户提交请求,请在请求中包含 es-security-runas-user 标头。请求将像从该用户发出一样运行,并且 Elasticsearch 将使用其角色。

例如,假设有一个用户名为 user123_runas 的用户。以下请求创建一个名为 jwt_role1 的用户角色,该角色指定了一个用户名为 user123_runasrun_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 具有包含 run_as 特权的角色(jwt_role1 角色),所以 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://127.0.0.1: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://127.0.0.1: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 密钥集 (JWKS) 可以包含 RSA 和 EC 公钥。HMAC JWKS 或 HMAC UTF-8 JWK 包含密钥。JWT 颁发者通常更频繁地轮换 PKC JWKS(例如每天),因为与 HMAC 等密钥相比,RSA 和 EC 公钥更容易分发。

JWT 领域在启动时加载 PKC JWKS 和 HMAC JWKS 或 HMAC UTF-8 JWK。JWT 领域还可以在运行时重新加载 PKC JWKS 内容;重新加载由签名验证失败触发。

目前不支持 HMAC JWKS 或 HMAC UTF-8 JWK 重新加载。

加载失败、解析错误和配置错误会阻止节点启动(和重新启动)。但是,运行时 PKC 重新加载错误和恢复可以正常处理。

在签名失败触发 PKC JWKS 重新加载之前,会检查所有其他 JWT 领域验证。如果在单个 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 颁发者。

Issuer:     iss8
Audiences:  aud8
Algorithms: HS256
HMAC UTF-8: hmac-oidc-key-string-for-hs256-algorithm

JWT 领域设置编辑

要定义 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 开始。01 在 Elastic Cloud 上的领域链中保留。

JWT 领域安全设置编辑

定义领域设置后,使用 elasticsearch-keystore 工具将以下安全设置添加到 Elasticsearch 密钥库。在 Elastic Cloud 中,您可以在部署的安全下定义 Elasticsearch 密钥库的设置。

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 领域角色映射规则编辑

以下请求为用户 principalname1jwt8 领域中创建 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 进行身份验证调用。承载令牌和客户端授权令牌必须使用 -H 选项指定为单独的标头。

curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY" -H "ES-Client-Authentication: SharedSecret client-shared-secret-string" https://127.0.0.1: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"}