Elasticsearch:无需基本身份验证即可创建用于访问的不记名令牌
Posted Elastic 中国社区官方博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch:无需基本身份验证即可创建用于访问的不记名令牌相关的知识,希望对你有一定的参考价值。
在很多的时候我们并不希望把用户名及密码分发出去,这是因为一旦拥有用户名及密码,你就可以直接登录系统,你甚至可以做更多的事情。另外一方面,用户名及密码还没有期限设定,除非我们在系统中把这个用户删除掉。为了能够使得客户端能够正常访问 Elasticsearch 集群,我们可以创建 API key 来进行访问。如果你想了解更多,请阅读我之前的文章 “Elasticsearch:创建 API key 接口访问 Elasticsearch”。为了方便,Elasticsearch 也提供了创建 bearer token 的方式来供我们使用。
请求方式
POST /_security/oauth2/token
前提条件
- 要使用此 API,你必须具有 manage_token 集群权限。
描述
Token 由 Elasticsearch Token 服务创建,该服务在你在 HTTP 接口上配置 TLS 时自动启用。请参阅为 Elasticsearch 加密 HTTP 客户端通信。或者,你可以显式启用 xpack.security.authc.token.enabled 设置。当你在生产模式下运行时,引导检查会阻止你启用 token 服务,除非你还在 HTTP 接口上启用了 TLS。如果你想为你的 Elasticsearch 集群启动 HTTPS 访问,请参阅我之前的文章 “Security:如何安装 Elastic SIEM 和 EDR”。
获取 token API 采用与典型 OAuth 2.0 token API 相同的参数,但使用 JSON 请求正文。
成功的获取 token API 调用会返回一个 JSON 结构,其中包含访问 token、token 过期时间(秒)、类型和范围(如果可用)。
由获取 token API 返回的 token 具有有效的有限时间段,在该时间段之后,它们将无法再使用。该时间段由 xpack.security.authc.token.timeout 设置定义。有关详细信息,请参阅 token 服务设置。
如果你想立即使 token 无效,可以使用 invalidate token API 来实现。
请求正文
可以在 POST 请求的正文中指定以下参数,并与创建 token 有关:
grant_type
(必需,字符串)授予的类型。 支持的授权类型有:password、_kerberos、client_credentials 和 refresh_token。
类型 | 描述 |
---|---|
client_credentials | 此授权类型实现 OAuth2 的客户端凭据授权。 它适用于机器对机器的通信,不适合或设计用于自助式用户创建 token。 它只生成无法刷新的访问 token。 前提是使用 client_credentials 的实体可以持续访问一组(客户端,而不是最终用户)凭据,并且可以随意对自己进行身份验证。 |
_kerberos | 这种授权类型在内部得到支持,并实现了基于 SPNEGO 的 Kerberos 支持。 _kerberos 授权类型可能会因版本而异。 |
password | 此授权类型实现了 OAuth2 的资源所有者密码凭据授权。 在此授权中,受信任的客户端将最终用户的凭据交换为访问 token 和(可能)刷新 token。 该请求需要由经过身份验证的用户发出,但代表另一个经过身份验证的用户(其凭据作为请求参数传递的用户)进行。 此授权类型不适合或设计用于自助式用户创建 token。 |
refresh_token | 该授权类型实现了 OAuth2 的 Refresh Token Grant。 在此授权中,用户将先前发布的刷新 token 交换为新的访问 token 和新的刷新 token。 |
password
(可选*,字符串)用户的密码。 如果你指定 password 授予类型,则此参数是必需的。 此参数对任何其他受支持的授权类型均无效。
kerberos_ticket
(可选*,字符串)base64 编码的 kerberos 票证。 如果你指定 _kerberos 授权类型,则此参数是必需的。 此参数对任何其他受支持的授权类型均无效。
refresh_token
(可选*,字符串)创建 token 时返回的字符串,可以延长其寿命。 如果你指定 refresh_token 授权类型,则此参数是必需的。 此参数对任何其他受支持的授权类型均无效。
scope
(可选,字符串)token 的范围。 目前,token 仅在 FULL 范围内发布,无论随请求发送的值如何。
username
(可选*,字符串)标识用户的用户名。 如果你指定 password 授予类型,则此参数是必需的。 此参数对任何其他受支持的授权类型均无效。
例子
以下示例使用 client_credentials 授权类型获取 token,它只是创建一个作为经过身份验证的用户的 token。我们在 Kibana 中打入如下的命令:
POST /_security/oauth2/token
"grant_type": "client_credentials"
上面的错误信息显示,当前的 license 不支持这种请求。我们在 订阅 | Elastic Stack 产品和支持 | Elastic 上进行查看:
这是一个收费的功能。我们必须启动白金试用版来进行验证:
这样我们就启动了白金试用功能。我们再次运行上面的命令:
这次它返回了 access_token,它是 Bearer 类型的。请注意上面的 expires_in 返回参数为 1200。它的意思是 1200 秒后这个 token 将失效,并且这个 token 不可以被 refresh。可以通过发送带有 Authorization 标头的请求来使用此 API 返回的 token,该请求的值具有前缀“Bearer”,后跟 access_token 的值。 比如我们可以使用如下的方法来访问 Elasticsearch:
curl -k -H "Authorization: Bearer o93qAxZtdEpsUDk3MFM0TzBVR01iQ1k2LU1RAAAAAAAAAAAA==" https://localhost:9200/_cluster/health | jq
$ curl -k -H "Authorization: Bearer o93qAxZtdEpsUDk3MFM0TzBVR01iQ1k2LU1RAAAAAAAAAAAA==" https://localhost:9200/_cluster/health | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 391 100 391 0 0 19634 0 --:--:-- --:--:-- --:--:-- 26066
"cluster_name": "elasticsearch",
"status": "green",
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 13,
"active_shards": 13,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 100
还比如:
curl -k -H "Authorization: Bearer o93qAxZtdEpsUDk3MFM0TzBVR01iQ1k2LU1RAAAAAAAAAAAA==" https://localhost:9200/
$ curl -k -H "Authorization: Bearer o93qAxZtdEpsUDk3MFM0TzBVR01iQ1k2LU1RAAAAAAAAAAAA==" https://localhost:9200/
"name" : "liuxgm.local",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "6ikO418_STeOL_sjYa708w",
"version" :
"number" : "8.4.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "f56126089ca4db89b631901ad7cce0a8e10e2fe5",
"build_date" : "2022-08-19T19:23:42.954591481Z",
"build_snapshot" : false,
"lucene_version" : "9.3.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
,
"tagline" : "You Know, for Search"
以下示例使用 password 授予类型为 test_admin 用户获取 token。 此请求需要由具有足够权限的经过身份验证的用户发出,该权限可能与在 username 参数中传递的用户名相同,也可能不同:
POST /_security/oauth2/token
"grant_type" : "password",
"username" : "elastic",
"password" : "V_USqc1cWM40W_pIHnni"
在上面它返回了 access_token,同时这个 token 的有效期只有 1200 秒。我们可以使用之前的方法来进行验证:
curl -k -H "Authorization: Bearer o93qAxZYNEIwYWlHSFFSaVlSOWtzTDdqcWJRAAAAAAAAAAAA" https://localhost:9200/
$ curl -k -H "Authorization: Bearer o93qAxZYNEIwYWlHSFFSaVlSOWtzTDdqcWJRAAAAAAAAAAAA" https://localhost:9200/
"name" : "liuxgm.local",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "6ikO418_STeOL_sjYa708w",
"version" :
"number" : "8.4.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "f56126089ca4db89b631901ad7cce0a8e10e2fe5",
"build_date" : "2022-08-19T19:23:42.954591481Z",
"build_snapshot" : false,
"lucene_version" : "9.3.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
,
"tagline" : "You Know, for Search"
显然这个访问是成功的。
由于这个 token 的有效期是 1200 秒,要延长使用 password 授予类型获得的现有 token 的生命周期,你可以在 token 创建后 24 小时内使用刷新令牌再次调用 API。 例如:
如上所示,它又会再次返回 access_token 及一个 refresh_token。你可以按照这样的方式来一直延长它的生命周期。
以下示例使用 kerberos 授权类型获取访问 token 和刷新 token,它只是创建一个 token 以换取 base64 编码的 kerberos 票证:
POST /_security/oauth2/token
"grant_type" : "_kerberos",
"kerberos_ticket" : "YIIB6wYJKoZIhvcSAQICAQBuggHaMIIB1qADAgEFoQMCAQ6iBtaDcp4cdMODwOsIvmvdX//sye8NDJZ8Gstabor3MOGryBWyaJ1VxI4WBVZaSn1WnzE06Xy2"
如果 kerberos 身份验证成功,API 将返回一个新的 token 和刷新 token。 每个刷新 token 只能使用一次。 当在 Spnego GSS 上下文中请求相互身份验证时,服务器将在 kerberos_authentication_response_token 中返回一个 base64 编码的令牌,供客户端使用并完成身份验证。
"access_token" : "dGhpcyBpcyBub3QgYSByZWFsIHRva2VuIGJ1dCBpdCBpcyBvbmx5IHRlc3QgZGF0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==",
"type" : "Bearer",
"expires_in" : 1200,
"refresh_token": "vLBPvmAB6KvwvJZr27cS"
"kerberos_authentication_response_token": "YIIB6wYJKoZIhvcSAQICAQBuggHaMIIB1qADAg",
"authentication" :
"username" : "test_admin",
"roles" : [
"superuser"
],
"full_name" : null,
"email" : null,
"metadata" : ,
"enabled" : true,
"authentication_realm" :
"name" : "file",
"type" : "file"
,
"lookup_realm" :
"name" : "file",
"type" : "file"
,
"authentication_type" : "realm"
以上是关于Elasticsearch:无需基本身份验证即可创建用于访问的不记名令牌的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:Firebase身份验证无需登录即可创建用户