apache ranger_Apache Ranger插件的美丽简洁

apache ranger

如果您在这里,您已经知道什么是Apache Ranger 。 这是在Hadoop框架中管理安全性的最流行(即使不是唯一)的方法。 它与Active Directory,Kerberos和其他各种身份验证集成在一起,但是我认为最有趣的功能是其授权支持。 作为Hadoop生态系统的一部分,人们会对它对Hadoop生态系统中的大多数框架(Hive,HBase,HDFS等)具有内建的支持(通过插件)感到惊讶,但是,我发现旋转它实际上非常容易自己的游侠自定义插件。

这篇文章将重点介绍Ranger插件中设计的简单性,并展示为自己构建一个插件有多么容易。 例如,我们将构建一个Ranger插件,用于管理对使用Akka HTTP编写的简单HTTP服务的访问。

Note : You are not required to know about Akka HTTP to follow this post. All you needed to know is that Akka HTTP is just a way (albeit, a great way) to build HTTP services

这篇文章后面的代码分为两个存储库:

  1. Ranger HTTP插件
  2. 护林员托管的Akka HTTP服务

写一个插件

为了重申我们在这里试图做的事情,我们将编写一个REST服务,并让Ranger管理它的授权。

编写Ranger插件实际上是两部分的问题–编写服务器端组件应用程序端组件

  1. 服务器端组件是驻留在Ranger端的代码/配置。
  2. 应用程序端组件是驻留在我们的REST服务中的代码,该代码调用Ranger服务并检查应用程序的最终用户是否有权访问他所请求的资源。

我们将详细研究这两件事。 让我们尝试首先编写服务器端组件。

1.服务器端组件:

作为启发,如果我们打开Ranger代码库 ,我们可以看到一些内置插件。

Apache Ranger插件

如图所示,在Ranger代码库中,我们有许多插件,我们想添加自己的插件。

Apache Ranger插件

放大上图,插件上的服务器端组件将意味着编写一个

  1. servicedef配置
  2. 继承RangerBaseService的类

因此,实际上需要在服务器端实现“一个”配置和“一个”类。

Apache Ranger插件

1. SERVICEDEF配置

让我们看一下Hive的servicedef配置:

Apache Ranger插件

我认为,我们在这里谈论三件事:

A.资源:

在Hive示例中,对于Kafka,我们要保护的“资源”是数据库 ,对于HDFS,我们要保护的“资源”是Kafka 主题 ,它将是文件路径 。 对于我们的HTTP服务,我们要保护的资源是REST slug 。 我们称之为“路径”。

"resources": [{"itemId": 1,"name": "path","type": "path","level": 10,"parent": "","mandatory": true,"lookupSupported": true,"recursiveSupported": true,"excludesSupported": true,"matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher","matcherOptions": {"wildCard": true,"ignoreCase": true},"validationRegEx": "","validationMessage": "","uiHint": "","label": "HTTP Path","description": "HTTP Path"}
访问类型:

访问类型只是意味着用户需要的访问类型–例如,对于Hive来说, selectcreatedelete就是示例。 对于HDFS, readwriteexecute是示例。 对于Kafka, 发布使用 。 对于我们的HTTP服务,访问类型将为HTTP方法-GETPOSTDELETE

"accessTypes": [{"itemId": 1,"name": "get","label": "get"},{"itemId": 2,"name": "post","label": "post"},{"itemId": 3,"name": "delete","label": "delete"}]
C.配置:

我们知道Ranger可以管理多个Kakfa主题,HDFS和HBase群集的安全性。 每个服务都将在不同的主机中运行,并且对每个服务进行身份验证的方式将有所不同。 捕获此信息的地方将是此configs部分。 为了简化本示例,我们不关心HTTP服务的身份验证。 因此,我们只是捕获可以ping通的URL,以确保我们的服务已启动并正在运行。

"configs": [{"itemId": 1,"name": "services_list_url","type": "string","subType": "","mandatory": true,"validationRegEx": "","validationMessage": "","uiHint": "","label": "HTTP URL for the services list eg. http://localhost:8080/services"}]

2.继承RANGERBASESERVICE的类

RangerBaseService插件实现服务器端组件的第二部分和最后一部分是编写一个继承RangerBaseService的类。

Apache Ranger插件

该类希望重写两个函数:

  1. validateConfig :请记住servicedef的configs部分。 显然,我们将接受这些参数的值,对吗? 现在,这个validateConfig是我们验证传递的值的地方。 对于我们的HTTP服务,我们在配置中接受的只是services_list_url 。 现在,此功能的实现将是使用一个简单的HTTP客户端ping并检查服务是否已启动并正在运行。
class RangerServiceHTTP extends RangerBaseService {override def validateConfig(): util.Map[String, AnyRef] = {if (configs.containsKey("services_list_url")) {val serviceUp = HttpServiceClient.isServiceUp(configs.get("services_list_url"))if (serviceUp) retSuccessMap() else returnFailureMap()}else {returnFailureMap()}}
  1. lookupResource :这是一个有趣的功能。 考虑以下屏幕截图。
Apache Ranger插件

稍后,当我们配置访问策略时,我们将在其中配置资源 。 现在,此功能用于查找和自动填充这些资源。 假设,如果我们要输入HDFS资源或Hive表,则选项的数量很多,而且很容易打错字。 对于Hive,此功能将连接到metastore并为我们填充表和数据库。

对于HTTP服务,还记得service_list_url吗? 该URL将仅返回逗号分隔的REST资源列表。 为了实现此功能,我只是再次调用服务并标记响应。

override def lookupResource(resourceLookupContext: ResourceLookupContext): util.List[String] = {val serviceUrl = configs.get("services_list_url")HttpServiceClient.getServicePaths(serviceUrl).asJava}

现在,作为代码的最后一步,我们需要将RangerServiceHTTP这个类和servicedef配置联系在一起。 我们这样做的方法是通过在implClass属性中配置类。 还要注意,我们正在将该Ranger插件的名称配置为httpservice

{"name": "httpservice","label": "HTTP Service","description": "Rudimentary Ranger plugin to enforce security on top of a HTTP Service","guid": "b8290b7f-6f69-44a9-89cc-06b6975ea676","implClass": "com.arunma.ranger.http.RangerServiceHTTP",
* *   "version": 1,"isEnabled": 1,"resources": [{"itemId": 1,"name": "path",......

完整的配置如下所示 。

还有两个较小的管理步骤:

  1. 为了确保在Ranger类路径上可以使用我们的类,我们将其捆绑到jar中,并将其放在<RANGER_HOME>/ews/webapp/WEB-INF/classes/ranger-plugins/httpservice 。 文件夹httpservice的名称与servicedef配置中声明的名称相对应。
Apache Ranger插件
  1. 将我们的配置上传到Ranger中,以便我们的服务在Ranger UI中可见。
curl -u admin:admin -X POST -H "Accept: application/json" -H "Content-Type: application/json" --data @http-ranger.json http://localhost:6080/service/plugins/definitions

重新启动Ranger服务器。

耶! 现在,我们在Ranger UI上看到HTTPSERVICE

Apache Ranger插件

2.应用程序侧组件:

在应用程序方面,事情再简单不过了。 为了使用Ranger中使用的策略,应用程序需要做的就是调用Ranger并检查用户是否有权访问资源。 该函数从字面上称为isAccessAllowed

Apache Ranger插件

以下代码几乎是需要在应用程序端编写的所有代码:

package com.arunma.rangerimport org.apache.ranger.plugin.audit.RangerDefaultAuditHandler
import org.apache.ranger.plugin.policyengine.{RangerAccessRequestImpl, RangerAccessResourceImpl}
import org.apache.ranger.plugin.service.RangerBasePluginimport scala.collection.JavaConverters._object RangerAuthorizer {lazy val plugin = {val plg = new RangerBasePlugin("httpservice", "httpservice")plg.setResultProcessor(new RangerDefaultAuditHandler)plg.init()plg}def authorize(path: String, accessType: String, userName: String, userGroups: Set[String] = Set("public")): Boolean = {val resource = new RangerAccessResourceImpl()resource.setValue("path", path)val request = new RangerAccessRequestImpl(resource, accessType, userName, userGroups.asJava)val result = plugin.isAccessAllowed(request)result != null && result.getIsAllowed}
}

RangerBasePlugin("httpservice", "httpservice")init()函数用作我们进入Ranger服务的入口点。 注意RangerBasePlugin内的httpservice参数。 该名称必须与servicedef配置中提供的名称匹配。

authorize函数是拦截器在客户端被授予对REST资源的访问权之前调用的函数。 该函数只是构造一个AccessRequest – RangerAccessRequestImpl并调用插件的isAccessAllowed函数,该函数返回Boolean

拦截器指令 authorize调用isRangerAuthorized函数,然后在RangerAuthorizer中调用authorize函数。

def isRangerAuthorized(path: String, httpMethod: String, userName: String): Boolean = RangerAuthorizer.authorize(path, httpMethod.toLowerCase, userName)  lazy val userRoutes: Route =headerValueByName("username") { userName =>extractMethod { method =>pathPrefix("users") {extractMatchedPath { matchedPath =>authorize(isRangerAuthorized(matchedPath.toString(), method.name(), userName)) {concat(pathEnd {concat(get {val users: Future[Users] =(userRegistryActor ? GetUsers).mapTo[Users]complete(users)

我们需要做的最后一件事是将auditsecurity xml复制到我们的类路径中。 这些就像Ranger的站点xmls 。 对于本练习,我们将xmls放置在resources目录中。

audit xml和security xml可以从游侠代码库复制。 如果您正在运行本地管理员,则审核XML可以保持原样,但是需要为我们的服务更改security xml。 实现此目的最简单的方法是从护林员代码库中复制示例xml,然后开始将服务替换为httpservice如下所示:

Apache Ranger插件

还有一个属性,需要特别注意。 该属性称为ranger.plugin.httpservice.service.name 。 此属性的值必须与您在Ranger UI中使用的服务名称相同。

<property><name>ranger.plugin.httpservice.service.name</name><value>MyService</value><description>Name of the Ranger service containing policies for this httpservice instance</description>
</property>
Apache Ranger插件

试乘

这将涉及两个步骤

  1. 配置巡警策略
  2. 验证您的HTTP服务

1.配置范围政策

Apache Ranger插件

2.验证您的HTTP服务

让我们通过启动HTTP服务来验证策略-启动com.arunma.RangerManagedHttpServer

策略配置的用户

curl -X GET -H 'username:arunma' http://localhost:8080/users
Apache Ranger插件

无效的用户

curl -X GET -H 'username:nobody' http://localhost:8080/users
Apache Ranger插件

摘要

Ranger插件有两个部分–服务器端组件和客户端组件。 对于服务器端组件,我们创建了一个servicedeef json和一个继承了RangerBaseService的类。 对于客户端组件,我们只调用了pluginisAccessAllowed函数。

您现在可以使用Ranger授权的HTTP服务。

谢谢阅读。 快乐黑客!

翻译自: https://www.javacodegeeks.com/2019/05/beautiful-simplicity-apache-ranger-plugin.html

apache ranger

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可重定位目标文件

【0】GCC将源代码转化成可执行代码的流程 &#xff08;1&#xff09;C预处理器cpp扩展源代码&#xff0c;插入所有用#include命令指定的文件&#xff0c;并扩展声明的宏&#xff1b;&#xff08;2&#xff09;编译器ccl产生两个源代码的汇编代码&#xff1a;*.s&#xff1b;&a…

经典颜色的RGB值

红 RED    品红Magenta&#xff08;热情&#xff09;    CMYK&#xff1a;C15 M100 Y20 K0   RGB: R207 G0 B112    洋红Carmine&#xff08;大胆&#xff09;   CMYK: C100 M0 Y60 K10   RGB: R215 G0 B64    宝石红Ruby&#xff08;富贵&#xff09;   CMYK…

python中for x in range_python教程:对 [lambda x: x*i for i in range(4)] 理解

题目&#xff1a;lst [lambda x: x*i for i in range(4)]res [m(2) for m in lst]print res实际输出&#xff1a;[6, 6, 6, 6]想要输出 [0, 2, 4, 6] 应该怎么改&#xff1f;如下&#xff1a;lst [lambda x, ii: x*i for i in range(4)]res [m(2) for m in lst]print res这…

adf.test_在ADF 12.2.1.3中使用基于JSON的REST Web服务

adf.test以前&#xff0c;我曾发布过有关在ADF中使用基于ADF BC的REST Web服务的信息。 现在&#xff0c;本文讨论使用通用数据控件使用基于JSON的REST Web服务。 您还可以查看有关Web服务的先前文章&#xff0c;以获取更多信息。 在ADF 12.2.1中使用应用程序模块快速创建SOA…

JSON字符串封装成Bean对象/JSON串反序列化成实体类对象/JSON字符串转换成Java对象

文章目录使用阿里巴巴的 JSON使用 ObjectMapperJSON字段与实体类属性不一致首先&#xff0c;我们建立一个实体类&#xff0c;这里简单定义了 name、sex、age 三个属性&#xff0c;以及 get、set、tostring方法。public class Student {private String name;private String sex;…

端到端的地址翻译(虚拟地址是怎样取到相应高速缓存的数据的?)

【0】写在前面-为什么需要虚拟存储器? 0.1&#xff09;定义&#xff1a;虚拟存储器其实就是借用了磁盘地址空间&#xff0c;还记得当初我们安装CentOS&#xff0c;划分的swap 文件系统吗&#xff1f; 0.2&#xff09;VM简化了链接和加载、代码和数据共享&#xff0c;以及应用…

python gevent教程_Python的gevent框架的入门教程

Python通过yield提供了对协程的基本支持&#xff0c;但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。gevent是第三方库&#xff0c;通过greenlet实现协程&#xff0c;其基本思想是&#xff1a;当一个greenlet遇到IO操作时&#xff0c;比如访问网络&#xff0c…

qa/qc_专业QA如何实施可靠的CI / CD管道?

qa/qc过时的传统软件开发方法并不能接管不断升级的市场趋势&#xff0c;并且这些方法缺乏解决方案&#xff0c;无法解决引入“ 持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09; ”的快速软件发布需求的增长。 除了CI / CD之外&#xff0c;您还需要具有…

程序员分类

1.优秀的debug能力 10K程序员&#xff1a;实现功能就不错了 20K程序员&#xff1a;编程我最牛&#xff0c;debug&#xff1f;我不太会&#xff01; 30K程序员&#xff1a;编程有点慢&#xff0c;debug快速搞定&#xff0c;回家睡觉&#xff01; 40K程序员&#xff1a;基本不写…

三菱q系列plc连接电脑步骤_三菱Q系列PLC与三菱变频器的CC-link通讯技术(我的学习笔记)...

三菱变频器可以通过CC-LINK的接线进行控制&#xff08;但需要另购买选件FR-A7NC&#xff0c;这选件是与变频器配套的通讯适配器&#xff0c;插在三菱变频器的选件插槽中&#xff09;&#xff0c;从而可以减少接线提高效率减少错误&#xff0c;接CC-LINK只需4根线就可以完全控制…

react提交数据到数据库_React型关系数据库事务

react提交数据到数据库Spring Framework最近宣布将提供对React式事务管理的支持 。 让我们深入研究它对R2DBC&#xff08;SQL数据库访问的React式规范&#xff09;如何工作。 事务管理是一种模式&#xff0c;而不是特定于技术的。 从这个角度来看&#xff0c;它的属性和运行时…

实模式切换到保护模式,为什么要开启A20地址线(系统升级产生的兼容性问题)

【-1】写在前面&#xff1a; 以下部分内容总结于 http://blog.csdn.net/ruyanhai/article/details/7181842 complementary: 兼容性是指运行在前期CPU&#xff0c;如8086/8088上的的程序&#xff0c;也可以运行在其以后的处理器&#xff0c;如80286上&#xff1b; 【0】看看in…

Windows 记事本的 ANSI、Unicode、UTF-8 这三种编码模式有什么区别?

先来解释一下这三种编码的历史吧&#xff1a; ANSI&#xff1a;最早的时候计算机ASCII码只能表示256个符号&#xff08;含控制符号&#xff09;&#xff0c;这个字符集表示英文字母足够&#xff0c;其中&#xff0c;我们键盘上可见的符号的编码范围是从32到126&#xff08;大小…

python编程、abc最大值_Python中abc

import abc指定metaclass属性将类设置为抽象类&#xff0c;抽象类本身只是用来约束子类的&#xff0c;不能被实例化class Animal(metaclassabc.ABCMeta): # 统一所有子类的方法abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法def say(self):print(‘动物基…

(实模式+保护模式)模式切换的过程步骤(代码+文字解析)

【0】写在前面 文末的个人总结是干货&#xff0c;前面代码仅供参考的&#xff0c;且source code from orange’s implemention of a os. ; ; pmtest2.asm ; 编译方法&#xff1a;nasm pmtest2.asm -o pmtest2.com ; %include "pm.inc" ; 常量, 宏, 以及一些说…

骆驼(camel)命名法_Apache Camel 3 –骆驼核心vs骆驼核心引擎(较小的核心)

骆驼(camel)命名法Camel团队目前正在忙于Apache Camel 3的开发。已经完成了许多工作&#xff0c;到目前为止&#xff0c;我们已经发布了3个里程碑版本。 下一个里程碑版本4具有一些出色的新创新功能&#xff0c;这些功能我将在接下来的几个月中发布。 该博客的主题是我们在将骆…

Maven的依赖插件

文章目录mvn dependency:copy-dependenciesmvn dependency:treemvn dependency:listmvn dependency:copy-dependencies 导出项目所依赖的所有 jar 包&#xff0c;默认导出到 target/dependency 目录中。 1.第一种方式 在命令终端中&#xff0c;进入 pom.xml 所在的目录&…

安装telnet_Flask干货:Memcached缓存系统——Memcached的安装

图 | 源网络文 | 5号程序员Memcached缓存系统是目前使用最广泛的高性能分布式内存缓存系统&#xff0c;是一个自由开源的高性能分布式内存对象缓存系统。国内外众多大型互联网应用都选择Memcached以提高网站的访问性能。缓存系统一般可以将一些不需要实时更新但是又极其消耗数据…

jep和jsr_候选JEP:记录和密封类型

jep和jsr马克莱因霍尔德&#xff08;Mark Reinhold &#xff09;本周在OpenJDK琥珀色开发者邮件列表上宣布了两个新的紧密相关的候选 JDK增强提案&#xff08; JEP&#xff09; &#xff0c;其帖子分别为“ 新候选JEP&#xff1a;359&#xff1a;记录&#xff08;预览&#xff…

局部描述符表LDT的作用+定义+初始化+跳转相关

【0】写在前面 0.1&#xff09;本代码的作用&#xff1a; 旨在说明局部描述符表的作用&#xff0c;及其相关定义&#xff0c;初始化和跳转等内容&#xff1b; 0.2&#xff09;文末的个人总结是干货&#xff0c;前面代码仅供参考的&#xff0c;且source code from orange’s i…