Apache Ranger插件的美丽简洁
如果您在這里,您已經(jīng)知道什么是Apache Ranger 。 它是管理Hadoop框架中安全性的最流行(即使不是唯一)的方法。 它與Active Directory,Kerberos和其他各種身份驗證集成在一起,但是我認為最有趣的功能是其授權(quán)支持。 作為Hadoop生態(tài)系統(tǒng)的一部分,人們會對它對Hadoop生態(tài)系統(tǒng)中的大多數(shù)框架(Hive,HBase,HDFS等)具有內(nèi)建的支持(通過插件)感到驚訝,但是,我發(fā)現(xiàn)旋轉(zhuǎn)它實際上非常容易自己的游俠自定義插件。
這篇文章將重點介紹Ranger插件中設(shè)計的簡單性,并展示為自己構(gòu)建一個插件有多么容易。 作為示例,我們將構(gòu)建一個Ranger插件,用于管理對使用Akka HTTP編寫的簡單HTTP服務(wù)的訪問。
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這篇文章后面的代碼分為兩個存儲庫:
寫一個插件
為了重申我們在這里試圖做的事情,我們將編寫一個REST服務(wù),并讓Ranger管理它的授權(quán)。
編寫Ranger插件實際上是兩部分的問題–編寫服務(wù)器端組件和應(yīng)用程序端組件 。
我們將詳細研究這兩件事。 讓我們嘗試首先編寫服務(wù)器端組件。
1.服務(wù)器端組件:
作為啟發(fā),如果我們打開Ranger代碼庫 ,我們可以看到一些內(nèi)置插件。
如圖所示,在Ranger代碼庫中,我們有許多插件,我們想添加自己的插件。
放大上圖,插件上的服務(wù)器端組件將意味著編寫一個
因此,實際上需要在服務(wù)器端實現(xiàn)“一個”配置和“一個”類。
1. SERVICEDEF配置
讓我們看一下Hive的servicedef配置:
我認為,我們在這里談?wù)撊?#xff1a;
A.資源:
在Hive示例中,對于Kafka,我們要保護的“資源”是數(shù)據(jù)庫 , 表和列 ,對于HDFS,我們要保護的“資源”是Kafka 主題 ,它將是文件路徑 。 對于我們的HTTP服務(wù),我們試圖保護的資源是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來說, select , create , delete就是示例。 對于HDFS, read , write , execute是示例。 對于Kafka, 發(fā)布并使用 。 對于我們的HTTP服務(wù),訪問類型將為HTTP方法– GET , POST , DELETE 。
"accessTypes": [{"itemId": 1,"name": "get","label": "get"},{"itemId": 2,"name": "post","label": "post"},{"itemId": 3,"name": "delete","label": "delete"}]C.配置:
我們知道Ranger可以管理多個Kakfa主題,HDFS和HBase群集的安全性。 每個服務(wù)都將在不同的主機中運行,并且對每個服務(wù)進行身份驗證的方式將有所不同。 捕獲此信息的地方將是此configs部分。 為了簡化本示例,我們不關(guān)心HTTP服務(wù)的身份驗證。 因此,我們只是捕獲了可以ping通的URL,以確保我們的服務(wù)已啟動并正在運行。
"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插件實現(xiàn)服務(wù)器端組件的第二部分和最后一部分是編寫一個繼承RangerBaseService的類。
該類希望重寫兩個函數(shù):
稍后,當(dāng)我們配置訪問策略時,我們將在其中配置資源 。 現(xiàn)在,此功能用于查找和自動填充這些資源。 假設(shè),如果我們要輸入HDFS資源或Hive表,那么選項的數(shù)量就很多,而且很容易打錯字。 對于Hive,此功能將連接到metastore并為我們填充表和數(shù)據(jù)庫。
對于HTTP服務(wù),請記住service_list_url ? 該URL將僅返回逗號分隔的REST資源列表。 為了實現(xiàn)此功能,我只是再次調(diào)用服務(wù)并標(biāo)記響應(yīng)。
override def lookupResource(resourceLookupContext: ResourceLookupContext): util.List[String] = {val serviceUrl = configs.get("services_list_url")HttpServiceClient.getServicePaths(serviceUrl).asJava}現(xiàn)在,作為代碼的最后一步,我們需要將RangerServiceHTTP這個類和servicedef配置聯(lián)系在一起。 我們這樣做的方法是通過在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",......完整的配置如下所示 。
還有兩個較小的管理步驟:
重新啟動Ranger服務(wù)器。
耶! 現(xiàn)在,我們在Ranger UI上看到HTTPSERVICE
2.應(yīng)用程序側(cè)組件:
在應(yīng)用程序方面,事情再簡單不過了。 為了使用Ranger中使用的策略,應(yīng)用程序需要做的就是調(diào)用Ranger并檢查用戶是否有權(quán)訪問資源。 該函數(shù)從字面上稱為isAccessAllowed 。
以下代碼幾乎是需要在應(yīng)用程序端編寫的所有代碼:
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()函數(shù)用作我們進入Ranger服務(wù)的入口。 注意RangerBasePlugin的httpservice參數(shù)。 該名稱必須與servicedef配置中提供的名稱匹配。
authorize函數(shù)是攔截器在客戶端被授予對REST資源的訪問權(quán)之前調(diào)用的函數(shù)。 該函數(shù)只是構(gòu)造一個AccessRequest – RangerAccessRequestImpl并調(diào)用插件的isAccessAllowed函數(shù),該函數(shù)返回Boolean 。
攔截器指令 authorize調(diào)用isRangerAuthorized函數(shù),然后在RangerAuthorizer中調(diào)用authorize函數(shù)。
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)我們需要做的最后一件事是將audit和security xml復(fù)制到我們的類路徑中。 這些就像Ranger的站點xmls 。 對于本練習(xí),我們將xmls放置在resources目錄中。
audit xml和security xml可以從游俠代碼庫復(fù)制。 如果您正在運行本地管理員,則審核XML可以保持原樣,但是需要為我們的服務(wù)更改security xml。 實現(xiàn)此目的的最簡單方法是從護林員代碼庫中復(fù)制示例xml,然后開始將服務(wù)替換為httpservice如下所示:
還有一個屬性,需要特別注意。 這就是名為ranger.plugin.httpservice.service.name的屬性。 此屬性的值必須與您在Ranger UI中使用的服務(wù)名稱相同。
<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>試乘
這將涉及兩個步驟
1.配置范圍政策
2.驗證您的HTTP服務(wù)
讓我們通過啟動HTTP服務(wù)來驗證策略-啟動com.arunma.RangerManagedHttpServer
策略配置的用戶
curl -X GET -H 'username:arunma' http://localhost:8080/users無效的用戶
curl -X GET -H 'username:nobody' http://localhost:8080/users摘要
Ranger插件有兩個部分–服務(wù)器端組件和客戶端組件。 對于服務(wù)器端組件,我們創(chuàng)建了一個servicedeef json和一個繼承了RangerBaseService的類。 對于客戶端組件,我們只調(diào)用了plugin的isAccessAllowed函數(shù)。
您現(xiàn)在可以使用Ranger授權(quán)的HTTP服務(wù)。
謝謝閱讀。 快樂黑客!
翻譯自: https://www.javacodegeeks.com/2019/05/beautiful-simplicity-apache-ranger-plugin.html
總結(jié)
以上是生活随笔為你收集整理的Apache Ranger插件的美丽简洁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何有效防御ddos攻击(怎么去抵御dd
- 下一篇: (device linux)