日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Apache Ranger插件的美丽简洁

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

這篇文章后面的代碼分為兩個存儲庫:

  • Ranger HTTP插件
  • 護林員托管的Akka HTTP服務
  • 寫一個插件

    為了重申我們在這里試圖做的事情,我們將編寫一個REST服務,并讓Ranger管理它的授權。

    編寫Ranger插件實際上是兩部分的問題–編寫服務器端組件應用程序端組件

  • 服務器端組件是駐留在Ranger端的代碼/配置。
  • 應用程序端組件是駐留在我們的REST服務中的代碼,該代碼調用Ranger服務并檢查應用程序的最終用戶是否有權訪問他所請求的資源。
  • 我們將詳細研究這兩件事。 讓我們嘗試首先編寫服務器端組件。

    1.服務器端組件:

    作為啟發,如果我們打開Ranger代碼庫 ,我們可以看到一些內置插件。

    如圖所示,在Ranger代碼庫中,我們有許多插件,我們想添加自己的插件。

    放大上圖,插件上的服務器端組件將意味著編寫一個

  • servicedef配置
  • 繼承RangerBaseService的類
  • 因此,實際上需要在服務器端實現“一個”配置和“一個”類。

    1. SERVICEDEF配置

    讓我們看一下Hive的servicedef配置:

    我認為,我們在這里談論三件事:

    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的類。

    該類希望重寫兩個函數:

  • 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()}}
  • lookupResource :這是一個有趣的功能。 考慮以下屏幕截圖。
  • 稍后,當我們配置訪問策略時,我們將在其中配置資源 。 現在,此功能用于查找和自動填充這些資源。 假設,如果我們要輸入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",......

    完整的配置如下所示 。

    還有兩個較小的管理步驟:

  • 為了確保我們的類在Ranger類路徑上可用,我們將其捆綁到一個jar中,并將其放在<RANGER_HOME>/ews/webapp/WEB-INF/classes/ranger-plugins/httpservice 。 文件夾httpservice的名稱與servicedef配置中聲明的名稱相對應。
  • 將我們的配置上傳到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

    2.應用程序側組件:

    在應用程序方面,事情再簡單不過了。 為了使用Ranger中使用的策略,應用程序需要做的就是調用Ranger并檢查用戶是否有權訪問資源。 該函數從字面上稱為isAccessAllowed 。

    以下代碼幾乎是需要在應用程序端編寫的所有代碼:

    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)

    我們需要做的最后一件事是將audit和security xml復制到我們的類路徑中。 這些就像Ranger的站點xmls 。 對于本練習,我們將xmls放置在resources目錄中。

    audit xml和security xml可以從游俠代碼庫復制。 如果您正在運行本地管理員,則審核XML可以保持原樣,但是需要為我們的服務更改security xml。 實現此目的的最簡單方法是從護林員代碼庫中復制示例xml,然后開始將服務替換為httpservice如下所示:

    還有一個屬性,需要特別注意。 這就是名為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>

    試乘

    這將涉及兩個步驟

  • 配置Ranger策略
  • 驗證您的HTTP服務
  • 1.配置范圍政策

    2.驗證您的HTTP服務

    讓我們通過啟動HTTP服務來驗證策略-啟動com.arunma.RangerManagedHttpServer

    策略配置的用戶

    curl -X GET -H 'username:arunma' http://localhost:8080/users

    無效的用戶

    curl -X GET -H 'username:nobody' http://localhost:8080/users

    摘要

    Ranger插件有兩個部分–服務器端組件和客戶端組件。 對于服務器端組件,我們創建了一個servicedeef json和一個繼承了RangerBaseService的類。 對于客戶端組件,我們只調用了plugin的isAccessAllowed函數。

    您現在可以使用Ranger授權的HTTP服務。

    謝謝閱讀。 快樂黑客!

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

    總結

    以上是生活随笔為你收集整理的Apache Ranger插件的美丽简洁的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。