【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

使用 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:291117
用户头像

发布了 1835 篇内容, 共 91.8 次阅读, 收获喜欢 73 次。

关注

评论

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

昇腾AI创新大赛2023开发者套件创新赛道专题解读篇

彭飞

开源铸剑,五载匠心!Zilliz Cloud云服务盛装登场,引领向量数据库云时代!

Zilliz

阿里云 SaaS 云服务 Zilliz zillizcloud

一个提高go开发效率的秘密武器,一天开发完成一个极简版社区后端服务

vison

crud gorm gin #go 代码自动生成

Boundless Hackathon @Stanford 主题黑客松活动闭幕,一文回顾

股市老人

Boundless Hackathon @Stanford 主题黑客松活动闭幕,一文回顾

EOSdreamer111

从零开始构建一个电影知识图谱,实现KBQA智能问答[上篇]:本体建模、RDF、D2RQ、SPARQL endpoint与两种交互方式详细教学

汀丶人工智能

人工智能 自然语言处理 nlp 知识图谱 本体建模

如果AI能帮我 | 社区征文

六月的雨在InfoQ

AIGC ChatGPT 年中技术盘点 通义听悟

数码时代的奇迹:低代码开发助力数字经济的蓝海探索

快乐非自愿限量之名

人工智能 低代码 数字化 数字经济

接口文档阅读方法:程序员必备的技术指南

Liam

程序员 接口文档 API

直播预告 | 博睿学院:海量数据实时可信认证

博睿数据

智能运维 博睿数据 数据要素 博睿学院

重塑未来的1课:组装式交付新引擎——华为云智能化低代码平台

华为云PaaS服务小智

云计算 低代码 华为云 华为开发者大会

《面试1v1》开篇

JavaPub

Java redis elasticsearch 面试 计算机

从零开始构建一个电影知识图谱,实现KBQA智能问答[下篇]:Apache jena SPARQL endpoint及推理、KBQA问答Demo超详细教学

汀丶人工智能

人工智能 自然语言处理 知识图谱 智能问答 KBQA

实例分享| anyRTC 部署安徽某市应急实战指挥平台

anyRTC开发者

音视频 快对讲 融合会议 视频监控 综合调度

浅谈如何向上管理

光毅

团队管理 向上管理

2023-07-11:给定正整数 n, 返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数。 输入:n = 100。 输出:10。

福大大架构师每日一题

Go 算法 rust 福大大架构师每日一题

小程序开发这么简单,还需要App吗?

FinFish

小程序生态 APP开发 小程序开发

es笔记六之聚合操作之指标聚合

Hunter熊

elasticsearch

软件测试/测试开发丨Selenium环境安装配置

测试人

Python 程序员 软件测试 selenium chromedriver

开启时空大数据新纪元:JNPF快速开发平台引领AI与自然资源融合

EquatorCoco

人工智能 AI 数据 时空大数据

MatrixOne悲观事务实现

MatrixOrigin

数据库 分布式 云原生 矩阵起源

Docker学习路线2:底层技术

小万哥

Docker 程序员 容器 后端 开发

科兴未来|“追光逐电 才聚紫琅”光电产业创新创业大赛

科兴未来News

创新引领!矩阵起源荣获中国信通院双重认可!

MatrixOrigin

数据库 分布式 云原生 超融合 矩阵起源

低代码技术分享官丨inBuilder使用有向无环图助力元数据工程依赖管理

inBuilder低代码平台

对象存储、数据库、NAS、标注数据集,均支持元信息配置|ModelWhale 版本更新

ModelWhale

人工智能 数据库 云计算 数据分析 大模型

HDC.Cloud 2023 |华为云5大开源项目发布与更新,助力开发者实现应用创新

华为云开源

开源 云原生 HDC.Cloud

Cloud Kernel SIG月度动态:ANCK 5.10-016将落地kABI机制,5.10-015版本规划发布

OpenAnolis小助手

操作系统 内核 anck 龙蜥sig 版本规划

GPT-4被破解!数智时代大突破!低代码开发平台揭秘:AI模型架构演进的利器

不在线第一只蜗牛

人工智能 低代码 模型调参 ChatGPT GPT-4

大学生活动社交小程序开发笔记(1)

CC同学

分布式系统常见问题

互联网工科生

分布式

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