写点什么

使用 Json Web Token (JWT) 对 Open Distro for Elasticsearch 和 Kibana 进行身份验证

  • 2019-09-29
  • 本文字数:6342 字

    阅读完需:约 21 分钟

使用 Json Web Token (JWT) 对 Open Distro for Elasticsearch 和 Kibana 进行身份验证

基于令牌的身份验证系统在 Web 服务领域备受青睐。它们具有许多优势,包括(但不限于)安全性、可伸缩性、无状态性和可扩展性。借助 Amazon 的 Open Distro for Elasticsearch,用户现在可利用安全插件中包含的许多安全功能。其中一项功能是使用 JSON Web Token (JWT) 对用户进行身份验证,以提供单点登录体验。在本博文中,我将介绍如何生成有效的 JWT,配置安全插件以支持 JWT,并最终使用令牌中显示的申请信息对 Elasticsearch 和 Kibana 的请求进行身份验证。

先决条件

要完成此示例,请克隆或下载我们的社区存储库。 jwt-tokens 目录包含示例代码和配置,便于您跟随本博文进行学习。配置文件有两种 – kibana.yml 和 config.yml,后者即为 docker-compose.yml,以及一个带有 Java 代码和用来构建它的 .pom 的 token-gen 目录。

生成 JWT

JWT 由三个 Base64 编码的部分组成:一个标头、一个有效负载和一个与句点 (.) 连接的签名。在理想情况下,JWT 是在身份验证服务器验证用户提供的凭证后由此服务器提供的。用户发出的每个请求都包含此令牌,并且 Web 服务将根据令牌中显示的申请信息允许或拒绝该请求。在本博文中,您将使用共享密码(由 HS256 算法提供)生成一个此类令牌。


让我们先分析用于生成 JWT 的一些 Java 代码示例,该代码在 16 分钟内有效。此代码使用 jjwt library 生成令牌和签名密钥:


  1 import io.jsonwebtoken.Jwts;  2 import io.jsonwebtoken.SignatureAlgorithm;  3 import io.jsonwebtoken.security.Keys;  4 import java.security.Key;  5 import java.util.Date;  6 import java.util.HashMap;  7 import io.jsonwebtoken.io.Encoders;  8  9 public class JWTTest { 10     public static void main(String[] args) { 11         Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); 12         Date exp = new Date(System.currentTimeMillis() + 1000000); 13         HashMap<String,Object> hm = new HashMap<>(); 14         hm.put("roles","admin"); 15         String jws = Jwts.builder() 16                 .setClaims(hm) 17                 .setIssuer("https://localhost") 18                 .setSubject("admin") 19                 .setExpiration(exp) 20                 .signWith(key).compact(); 21         System.out.println("Token:"); 22         System.out.println(jws);  23         if(Jwts.parser().setSigningKey(key).parseClaimsJws(jws).getBody().getSubject().equals("test")) { 24             System.out.println("test"); 25         } 26         String encoded = Encoders.BASE64.encode(key.getEncoded()); 27         System.out.println("Shared secret:"); 28         System.out.println(encoded); 29     } 30 }
复制代码


  • 第 11 行为我们提供了基于 HMAC_SHA256 算法的随机签名密钥。这是在验证 JWT 令牌时安全插件使用的签名密钥。由于我们使用的是对称密钥算法,此签名密钥是 Base64 编码的共享密钥(第 28 行)。如果我们使用的是 RSA 或 ECDSA 等非对称算法,则签名密钥将为公有密钥。第 19 行用于设置申请。安全插件会自动识别算法。

  • 第 13-14 行创建了一个将密钥 roles 映射到值 admin 的申请。

  • 第 12 行生成了距当前时间 16 分钟的 Date。第 19 行在 Jwts.Builder 中使用此日期。

  • 第 20 行使用第 11 行创建的 signing_key 签署 JWT 令牌。

  • 您需要使用 Apache Maven 来编译和运行示例代码。我使用 Homebrew 通过以下命令安装 Maven 3.6.1


$ brew install maven。
复制代码


从 token-gen 目录中,构建并运行以下代码:


$ cd token-gen$ mvn clean install$ java -jar target/jwt-test-tokens-1.0-SNAPSHOT-jar-with-dependencies.jar
Token:eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3QiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTU1NDUyMjQzMH0.fnkQdBKqgOD-Tdf5Pv09NCiz0WlL-KFPU39CEXAMPLEShared Secret:usuxqaUmbbe0VqN+Q90KCk5sXHCfEVookMRyEXAMPLE=
复制代码


请务必复制此令牌和共享密钥,在一分钟后,您会用到此信息。您还可以在 token-gen 目录中的 README 中找到这些命令。

配置安全插件以使用 JWT

Open Distro for Elasticsearch 的安全插件包含一个配置文件,该配置文件可指定身份验证类型、质询以及 JWT 有效负载中必须存在的其他各种配置密钥,以便对请求进行身份验证。如要进一步验证请求,您还可以指定身份验证后端。当您启动容器时,您将使用 jwt-tokens 目录中名为 config.yml 的文件覆盖默认配置。


在您常用的编辑器中打开 jwt-tokens/config.yml 并将其更改为如下所示:


  ...  1   jwt_auth_domain:2     enabled: true3     http_enabled: true 4     transport_enabled: true5     order: 06     http_authenticator:7       type: jwt8       challenge: false9       config:10        signing_key: "usuxqaUmbbe0VqN+Q90KCk5sXHCfEVookMRyEXAMPLE="11        jwt_header: "Authorization"12        jwt_url_parameters: null13        roles_key: "roles"14        subject_key: "sub"15    authentication_backend:16      type: noop...
复制代码


  • 第 2 行使此域能够使用 JWT 进行身份验证。

  • 第 7 行选择 JWT 作为身份验证类型。

  • 第 8 行将密钥质询设置为“false”。 此处不需要质询,因为 JWT 令牌包含我们需要验证的所有内容。第 15 行由于相同的原因被设置为 noop。

  • 第 10 行将 signing_key 设置为我们在上述 Java 代码中生成的 Base64 编码的共享密钥。注意:确保使用您在上一部分中生成的密钥替换此密钥。

  • 第 11 行是传输令牌的 HTTP 标头。您将使用 authorization 标头和 bearer 方案。系统会默认使用“授权”标头,但您也可以使用 URL 参数传递 JWT。

  • 第 13 行用于指定将用户角色存储为以逗号分隔的列表的密钥。在本例中,我们仅指定管理员。

  • 第 14 行用于指定存储用户名的密钥。如果缺少此密钥,我们只会获得注册的主体申请。在上述代码中,我们只设置主体申请信息。

  • 如果您是 Docker 和 Open Distro for Elasticsearch 的新用户,我强烈建议您从 Open Distro for Elasticsearch 文档开始入门。在本教程中,我使用的集群包含一个 Elasticsearch 节点和一个 Kibana 节点。

Kibana 改动

要模拟当我们使用标准令牌提供程序时 Kibana 的工作方式,您只需在 kibana.yml 中再添加一行。编辑 jwt-tokens/kibana.yml 并添加:


opendistro_security.auth.type: "jwt"
复制代码

运行 Elasticsearch 和 Kibana

您需要一个正在运行的 Docker 环境才能继续。我使用的是 Docker Desktop for Mac。您可以在有关如何下载和配置 Docker Desktop 的博文中找到其设置和运行说明(使用来自 jwt-tokens 目录的 docker-compose.yml 而不是此博文中的配置文件)。从 jwt-tokens 目录运行以下命令:


$ docker-compose up
复制代码


下载图像并启动集群后,在新终端中运行 docker ps。您应看到与以下输出类似的内容:两个容器,其中一个运行 Elasticsearch 映像,另一个运行 Kibana 映像。


$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 63c3e9df19ac amazon/opendistro-for-elasticsearch-kibana:0.9.0 "/usr/local/bin/kiba…" 8 seconds ago Up 7 seconds 0.0.0.0:5601→5601/tcp odfe-kibana 0aa5316ffbc7 amazon/opendistro-for-elasticsearch:0.9.0 "/usr/local/bin/dock…" 8 seconds ago Up 7 seconds 0.0.0.0:9200→9200/tcp, 0.0.0.0:9600→9600/tcp, 9300/tcp odfe-node1
复制代码


重新初始化安全索引 [可选]


如果您仅在编辑了 config.yml 后运行 docker-compose,可以跳过此部分。如果您在编辑 config.yml 之前的任何时候运行了 docker-compose,则需要重新初始化安全索引并确保请求正在进行身份验证。


首先,找到带有 docker ps 的 Elasticsearch 容器:


$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES533f03ee0fdc amazon/opendistro-for-elasticsearch:0.9.0 "/usr/local/bin/dock…" 2 days ago Up 20 seconds 0.0.0.0:9200→9200/tcp, 0.0.0.0:9600→9600/tcp, 9300/tcp odfe-node13a2c4a582165 amazon/opendistro-for-elasticsearch-kibana:0.9.0 "/usr/local/bin/kiba…" 2 days ago Up 20 seconds 0.0.0.0:5601→5601/tcp odfe-kiban复制 amazon/opendistro-for-elasticsearch 容器的 CONTAINER ID。在我讲的示例中,容器 ID 为 533f03ee0fdc。您可以通过运行以下命令授权 Bash 访问该容器:
$ docker exec -it 533f03ee0fdc /bin/bash
复制代码


请务必在上述命令中使用您的容器 ID。重新初始化安全索引并退出:


$ plugins/opendistro_security/tools/securityadmin.sh -f plugins/opendistro_security/securityconfig/config.yml -icl -nhnv -cert config/kirk.pem -cacert config/root-ca.pem -key config/kirk-key.pem -t configOpen Distro Security Admin v6Will connect to localhost:9300 ... doneElasticsearch Version: 6.5.4Open Distro Security Version: 0.9.0.0Connected as CN=kirk,OU=client,O=client,L=test,C=deContacting elasticsearch cluster 'elasticsearch' and wait for YELLOW clusterstate ...Clustername: odfe-clusterClusterstate: YELLOWNumber of nodes: 1Number of data nodes: 1.opendistro_security index already exists, so we do not need to create one.Populate config from /usr/share/elasticsearchWill update 'security/config' with plugins/opendistro_security/securityconfig/config.ymlSUCC: Configuration for 'config' created or updatedDone with success$ exit
复制代码

测试您的更改

现在,您可以通过添加 authorization 标头来测试一些基本命令。请务必使用上面生成的令牌替换以下命令中的令牌:


$ curl -XGET https://localhost:9200/_cat/nodes -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3QiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTU1NDc1Nzk3M30.KY5gC4yrBXXYYcaEJOl-xyiEr98h9Sw9dIWwEXAMPLE" --insecure172.21.0.3 37 38 3 0.03 0.11 0.09 mdi * WTNYA_5$ curl -XGET https://localhost:9200/_cluster/health\?pretty -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3QiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTU1NDc1Nzk3M30.KY5gC4yrBXXYYcaEJOl-xyiEr98h9Sw9dIWwlzJYpBg" --insecure{  "cluster_name" : "odfe-cluster",  "status" : "yellow",  "timed_out" : false,  "number_of_nodes" : 1,  "number_of_data_nodes" : 1,  "active_primary_shards" : 7,  "active_shards" : 7,  "relocating_shards" : 0,  "initializing_shards" : 0,  "unassigned_shards" : 5,  "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" : 58.333333333333336}$ curl -XGET https://localhost:9200/_opendistro/_security/authinfo\?pretty -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3QiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTU1NDc1Nzk3M30.KY5gC4yrBXXYYcaEJOl-xyiEr98h9Sw9dIWwlzJYpBg" --insecure { "user" : "User [name=admin, roles=[admin], requestedTenant=null]", "user_name" : "admin", "user_requested_tenant" : null, "remote_address" : "172.23.0.1:53104", "backend_roles" : [ "admin" ], "custom_attribute_names" : [ "attr.jwt.iss", "attr.jwt.sub", "attr.jwt.exp", "attr.jwt.roles" ], "roles" : [ "all_access", "own_index" ], "tenants" : { "admin_tenant" : true, "admin" : true }, "principal" : null, "peer_certificates" : "0", "sso_logout_url" : null }
复制代码


然后,您可以从终端向 Kibana 发出请求,并记下成功的响应:


$ curl -XGET http://localhost:5601 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3QiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTU1MzY0Mjc1NX0.2RVy0VEObwduF9nNZas498LTJMRLC9luTuebEXAMPLE" -i
HTTP/1.1 302 Found location: /app/kibana kbn-name: kibana set-cookie: security_storage=Fe26.2**a86a495463a9ed2aef99e9499025b000888bc70232d006765c9990f8c9d7412*viOmkphhLLIDeBTxX9_OkQ*lIBpboN6gQ07QvwY7mMp-48IsrvI0qtfaRR8_VmPesYmlqlNizId2smn-kXtIJdsmZBpz7y4WLJzmqP0hKKCBAAJ9Bccj-fVh5QJdHW6mWEhuS870VlB9PUMZAnQ8ju6D8Gs-70A16rodBDSI4b601EhJET4vtMObTFmvYkiavqKvc9CPbwMpHRQdIKwX9AzSjbekMC8CSn1PgzMbtNijYNFd3sLZHrDxrqTSQijm8M**ba624f98f91081024b49264a08c692287b30bca4f185aa8925c1bb238cdf27ef*fc9z6yinUj2Xp920Iy-GoKdVzO5G4aZRsxQWi_bVH-Y; Path=/ set-cookie: security_preferences=Fe26.2**a2791807692cd418aa644804fd0e6e5cd33421a899e0797d8a97ec4e7f2cbf0*guZ5n6zMcCwylCPOazyyew*1n43XcDV1NcGvgl-VwD07njHLkxn-VdgQNVMk5ZQSsw**f25a10407839cc2869b06826eb5459f166baf6fcea11df6b1f4a316152fec3e4*K5wr95D7cVoetpvEFjdzjSN-mgvBEU9tWpx6QiLgEuE; Max-Age=2217100485; Expires=Mon, 27 Jun 2089 17:56:50 GMT; Path=/ set-cookie: security_authentication=Fe26.2**5ca6f12884a00a406f89887bb91f33ee7a68f22c815996a9adbda934698364d*OuII1jATnWfYzaHIv4_HvQ*qoTlwVqRvpDzkWmq-JYZbXpSbEJ6DyG5qhmNenM0GB6vbGEcnkXmpUFvOICkAyRuzmKwl9Uut1GYM98TLwhTZbzFb6Z1d5Sb4MOpk6DJNFjuokIm0u9tqsCwCGMEO_avmosVy4gceAluSX-7vN-vC461jt2B3_DIbyeREjPLtjr91a2I95nGQRir_-4cypkjUaS3Blub1ZC7fNnkBcK5POvo-nKTXJmx5KQx4O_6zVc3vFfoQLJ7_AUrLAID_htMHMv5o7_qn1oMHP-LTr5zvO4iDLlY1UgBJCmikpMatxPg8ophKxWkMRuIdo4UaZEjrzXwQPJtYBmpJxwQtolJQB5jwOnNNVqtUeiI7sWitHM**1c4cf336b71a513045bf0bfe50ff96447c213f70dfd3745d713e57235a7edff9*fLp9DLSMhgKHjOIJ8VDHMbVI9Z7W56Velx4Pi5STK4s; Max-Age=3600; Expires=Tue, 26 Mar 2019 21:42:05 GMT; HttpOnly; Path=/ cache-control: no-cache content-length: 0 connection: close Date: Tue, 26 Mar 2019 20:42:05 GMT
复制代码

小结

祝贺您! 您已创建 JWT 令牌,用于验证和控制对 Open Distro for Elasticsearch 集群的访问。您已修改安全插件的配置以接受 JWT。您已在容器中运行修改后的 Elasticsearch 和 Kibana,并成功发送查询。


作者介绍:


Neeraj Prashar


AWS 软件开发人员,base 在帕洛阿尔托的 ElasticSearch team.工作项目主要围绕亚马逊基于安全空间的 ElasticSearch 服务。在加入 AWS 之前,作为软件开发者服务过包括微软(Azure)、Apple(Media Cudio)和 IBM(DB2/编译器)等。持有温哥华英属哥伦比亚大学计算机工程学士学位和西雅图华盛顿大学计算机科学硕士学位。


Jon Handler


Jon Handler (@_searchgeek) 是总部位于加利福尼亚州帕罗奥图市的 Amazon Web Services 的首席解决方案架构师。Jon 与 CloudSearch 和 Elasticsearch 团队密切合作,为想要将搜索工作负载迁移到 AWS 云的广大客户提供帮助和指导。在加入 AWS 之前,Jon 作为一名软件开发人员,曾为某个大型电子商务搜索引擎编写代码长达四年。Jon 拥有宾夕法尼亚大学的文学学士学位,以及西北大学计算机科学和人工智能理学硕士和博士学位。


本文转载自 AWS 技术博客


文章链接:


https://amazonaws-china.com/cn/blogs/china/json-web-tokens-jwt-authenticate-open-distro-for-elasticsearch-kibana/


2019-09-29 16:291345
用户头像

发布了 1855 篇内容, 共 122.7 次阅读, 收获喜欢 79 次。

关注

评论

发布
暂无评论
发现更多内容

MySQL系列——连接查询、子查询、union合并、limit

胖虎不秃头

MySQL 数据库 9月月更

软件测试 | 测试开发 | Pytest 测试框架,零基础也能轻松 hold 住

测吧(北京)科技有限公司

软件测试 测试

画一个 “月饼” 陪我过中秋,使用 ESP32-C3 制作炫彩月饼

矜辰所致

电路设计 ESP32-C3 9月月更

负载均衡

阿柠xn

负载均衡 运维 MQ 9月月更

Python 自动化测试(五): Pytest 结合 Allure 生成测试报告

测吧(北京)科技有限公司

Python 自动化测试 pytest

BI系统的分布式部署原理和技术实现

葡萄城技术团队

分布式 BI 部署 可视化数据

MySQL系列——数据库表、查询、排序、数据处理函数

胖虎不秃头

MySQL 数据库 9月月更

字节一面:服务端挂了,客户端的 TCP 连接还在吗?

Java全栈架构师

程序员 面试 TCP 计算机网络 秋招

如何在 ACK 中使用 MSE Ingress

阿里巴巴中间件

阿里云 容器 微服务 云原生 ingress

Android技术分享| Activity 过渡动画 — 让切换更加炫酷

anyRTC开发者

android 音视频 动画 移动开发 Activity

大咖说 | 无影携手实在智能助力企业“数智化”转型

大咖说

无影 实在智能

一文带你了解K8S 容器编排(下)

霍格沃兹测试开发学社

JDBC系列——JDBC编程六步

胖虎不秃头

MySQL 数据库 9月月更

软件测试 | 测试开发 | Jenkins 踩坑(四)|基于接口自动化测试完成 Jenkins+GitHub+Allure 的结合

测吧(北京)科技有限公司

测试

探索编译软件栈新范式;高端GPU禁售的影响;陈天奇DL系统免费课程|AI系统前沿动态

OneFlow

内容合集

python os模块

zxhtom

9月月更

融云视频会议,助力政企高效协同

融云 RongCloud

会议 音视频技术 政企

堡垒机定义、由来以及价值简单说明-行云管家

行云管家

网络安全 数据安全 堡垒机 行云管家

微服务治理热门技术揭秘:动态读写分离

阿里巴巴中间件

数据库 阿里云 微服务 云原生

设计模式的艺术 第十四章享元设计模式练习(开发一个多功能文档编辑器,在文本文档中可以插入图片、动画、视频等多媒体资料。为了节省系统资源,相同的图片、动画和视频在同一个文档中只需保存一份,但是可以多次重复出现,而且它们每次出现时位置和大小均可不同)

代廉洁

设计模式的艺术

只懂黑盒测试也能学会的代码覆盖率及精准化测试

霍格沃兹测试开发学社

软件测试 自动化测试 测试开发

如何设计一个高并发系统?这篇文章全部给你讲清楚了

Java永远的神

程序员 面试 后端 高并发 架构师

日志易正式加入华为云云商店联营模式,并受邀参与首届828 B2B企业节

IT资讯搬运工

华为 华为云

NFT软件开发:什么是数字藏品?

开源直播系统源码

NFT 数字藏品 数字藏品系统软件开发 数字藏品开发

备战2023秋招,应届生应做好哪些准备

C++后台开发

应届生 C++后台开发 校招 秋招 C++开发

OpenHarmony3.0如何轻松连接华为云IoT设备接入平台

华为云开发者联盟

后端 物联网 华为云 企业号九月金秋榜

CodeLab:一款让你体验丝滑般的云化JupyterLab

华为云开发者联盟

人工智能 华为云 企业号九月金秋榜

GaussDB(for Redis)双活容灾支持4大应用场景,全新守护业务安全

华为云开发者联盟

数据库 后端 企业号九月金秋榜

软件测试 | 测试开发 | java远程连接ssh的实现

测吧(北京)科技有限公司

java;

Linux vim的使用和配置

挚爱光小胖

Linux vim教程

elasticsearch的字符串动态映射

程序员欣宸

elasticsearch 9月月更

使用 Json Web Token (JWT) 对 Open Distro for Elasticsearch 和 Kibana 进行身份验证_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章