基於規則的授權外掛程式

Solr 提供授權外掛程式,可針對重要的 Solr API 和功能提供精細的使用者存取控制。

Solr 的驗證外掛程式以二進位方式控制使用者是否可以存取 Solr。使用者要嘛通過驗證,要嘛沒有通過驗證。為了更精細的存取控制,可以使用 Solr 的基於規則的授權外掛程式 (RBAP)。

Solr 的管理 UI 使用其常規 API 與 Solr 互動。當使用基於規則的授權時,未獲授權存取這些 API 全部範圍的已登入使用者可能會看到 UI 的某些部分顯示空白或「損壞」。

為了獲得最佳結果,管理 UI 應僅由具有完整 API 存取權限的使用者存取。

基於規則的驗證概念

「使用者」、「角色」和「權限」在正確設定授權方面發揮核心作用。

在基於規則的授權中,管理員會根據他們希望這些角色授予的權限定義一系列角色。然後,會為使用者指派一個或多個角色。

使用者

RBAP 看到的使用者來自已設定的任何驗證外掛程式。RBAP 與 Solr 開箱即用的所有驗證外掛程式相容。它也與使用者可能編寫的任何自訂驗證外掛程式相容,前提是該外掛程式在收到的 HttpServletRequest 上設定使用者主體。

在每種情況下,RBAP 看見的使用者值取決於正在使用的驗證外掛程式:如果正在使用Kerberos 驗證外掛程式,則為 Kerberos 主體;如果正在使用JWT 驗證外掛程式,則為「sub」JWT 宣告等。

角色

角色彌合了使用者和權限之間的差距。角色可以與任何驗證外掛程式或您建立的自訂驗證外掛程式一起使用。您只需要確保已登入的使用者會對應到外掛程式定義的角色即可。

外掛程式有兩種實作方式,它們的差異僅在於如何取得使用者的角色

  • RuleBasedAuthorizationPlugin:必須在 security.json 中明確定義每個可能已驗證使用者的角色對使用者映射。

  • ExternalRoleRuleBasedAuthorizationPlugin:角色對使用者映射在外部管理。此外掛程式期望 AuthenticationPlugin 提供一個主體,該主體也具有角色資訊,並實作 VerifiedUserRoles 介面。

權限

權限控制哪些角色(以及因此哪些使用者)可以存取哪些 Solr API。

每個權限都有兩個主要元件:權限套用的 API 的描述,以及應允許存取這組 API 的角色清單。

管理員可以使用預先定義選項清單中的權限,或定義他們自己的自訂權限,並且可以自由混合和配對兩者。

設定基於規則的授權外掛程式

與 Solr 的所有安全性外掛程式一樣,RBAP 的設定位於名稱為 security.json 的檔案或 ZooKeeper 節點中。請參閱設定 security.json,以取得有關如何在您的叢集中設定 security.json 的更多資訊。

Solr 提供授權 API,用於變更 RBAP 設定。在大多數情況下,授權管理員應使用此 API 進行變更。如果 security.json 儲存在 ZooKeeper 中,使用者也可以直接編輯它,但這是一項專家級功能,在大多數情況下都不建議使用。API 簡化了設定的某些方面,並提供編輯 ZooKeeper 時不會提供的錯誤回饋。

配置語法

RBAP 配置包含少數幾個必要的配置屬性。這些屬性都位於 security.json 中最上層的 authorization 屬性之下。

class

必要

預設值:無

要使用的授權外掛程式。有三個選項:solr.RuleBasedAuthorizationPluginsolr.ExternalRoleRuleBasedAuthorizationPluginsolr.MultiAuthRuleBasedAuthorizationPlugin

permissions

選用

預設值:無

用於限制存取 Solr API 各個部分的權限規則的 JSON 陣列。例如:

{
  "permissions": [
  { "name": "read", "collection": "techproducts", "role": ["admin", "dev"] },
  { "name": "all", "role": "admin"}
  ]
}

個別權限的語法比較複雜,會在下方詳細說明。

當您將 ExternalRoleRuleBasedAuthorizationPlugin 用於 class 時,使用者角色可能來自請求本身。在這種情況下,請跳過定義 permissions

如果您需要硬式編碼使用者角色對應,請為 class 定義 RuleBasedAuthorizationPlugin,並在 security.json 中定義使用者角色對應,如下所示:

user-role

選用

預設值:無

個別使用者與其指定角色的對應。此參數的值是一個 JSON 對應,其中每個屬性名稱都是一個使用者,而每個屬性值都是單一角色的名稱,或是指定使用者所屬的多個角色的 JSON 陣列。

例如:

{
  "user-role": {
  "user1": "role1",
  "user2": ["role1", "role2"]
  }
}
useShortName

選用

預設值:false

決定使用者角色對應是否會使用完整主體或由身份驗證外掛程式提供的縮短名稱來解析。例如,KerberosAuthPlugin 可能會提供 user@EXAMPLE.COM 的完整主體,而對應的縮短名稱則會是 user

對於某些外掛程式,主體名稱和縮短名稱可能相同。

RuleBasedAuthorizationPlugin 和 BasicAuth 的範例

這個 security.json 範例顯示 基本身份驗證外掛程式 如何與 RuleBasedAuthorizationPlugin 外掛程式搭配使用

{
  "authentication": {
    "class": "solr.BasicAuthPlugin", (1)
    "blockUnknown": true,
    "credentials": {
      "admin-user": "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=",
      "dev-user": "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="
    }
  },
  "authorization": {
    "class": "solr.RuleBasedAuthorizationPlugin", (2)
    "user-role": { (3)
      "admin-user": "admin",
      "dev-user": "dev"
    },
    "permissions": [ (4)
      { "name": "dev-private-collection", "collection": "dev-private", "role": "dev"},
      { "name": "security-read", "role": "admin"},
      { "name": "security-edit", "role": "admin"}
    ]
  }
}
1 Solr 使用基本身份驗證外掛程式進行身份驗證。此配置建立兩個使用者:admin-userdev-user
2 authorization 屬性開始進行授權配置。Solr 將使用 RBAP 進行授權。
3 定義了兩個角色:admindev。每個使用者都屬於一個角色:admin-useradmin,而 dev-userdev
4 三個權限限制了對 Solr 的存取。第一個權限(「自訂」權限)表示只有 dev 角色可以從名稱為 dev-private 的特殊集合讀取。最後兩個權限(「預先定義」的權限)表示只有 admin 角色才能使用 Solr 的安全 API。有關權限語法的詳細資訊,請參閱下方。

總之,此範例劃分了兩個受限區域。只有 admin-user 可以存取 Solr 的身份驗證和授權 API,而只有 dev-user 可以存取其 dev-private 集合。所有其他 API 都是開放的,兩個使用者都可以存取。

使用 JWT 驗證的 External Role RuleBasedAuthorizationPlugin 範例

這個 security.json 範例顯示 JWT 身份驗證外掛程式 如何與 ExternalRoleRuleBasedAuthorizationPlugin 外掛程式搭配使用,該外掛程式會從 JWT 宣告中提取使用者和使用者角色

{
"authentication":{
   "class": "solr.JWTAuthPlugin", (1)
   "jwksUrl": "https://my.key.server/jwk.json", (2)
   "rolesClaim": "roles" (3)
},
"authorization":{
   "class":"solr.ExternalRoleRuleBasedAuthorizationPlugin", (4)
   "permissions":[{"name":"security-edit",
      "role":"admin"}] (5)
}}

讓我們來逐步了解這個範例

1 已啟用 JWT 身份驗證外掛程式。
2 公開金鑰將透過 HTTPS 提取。
3 我們預期每個 JWT 權杖都包含「roles」宣告,該宣告將傳遞給授權。
4 已啟用外部角色規則型授權外掛程式。
5 已定義 'admin' 角色,並且具有編輯安全性設定的權限。

只有來自具有角色「admin」的 JWT 權杖的使用者的請求才會被授予 security-edit 權限。

多個授權外掛程式

如果您的 security.json 配置使用 MultiAuthPlugin,您會希望使用 MultiAuthRuleBasedAuthorizationPlugin 為每個身份驗證外掛程式使用不同的授權外掛程式。

以下範例說明如何使用 MultiAuthRuleBasedAuthorizationPluginBasicBearer 方案配置授權外掛程式

{
  "authorization": {
    "class": "solr.MultiAuthRuleBasedAuthorizationPlugin",
    "schemes": [
      {
        "scheme": "basic",
        "class": "solr.RuleBasedAuthorizationPlugin",
        "user-role": {
          "k8s-oper": ["k8s"]
        }
      },
      {
        "scheme": "bearer",
        "class": "solr.ExternalRoleRuleBasedAuthorizationPlugin"
      }
    ],
    "permissions": []
  }
}

同一個使用者帳戶同時存在於這兩個外掛程式中並不常見。但是,MultiAuthRuleBasedAuthorizationPlugin 會在判斷使用者的角色時,將所有外掛程式的角色組合在一起。

使用基本身份驗證時,使用者應特別注意鎖定服務帳戶需要存取的精確端點集。例如,如果 MultiAuthPlugin 允許 k8s-oper 使用者使用基本身份驗證(而所有其他使用者都通過 OIDC),則為 k8s-oper 使用者配置的權限應只允許存取特定端點,例如 /admin/info/system

權限

Solr 的規則型授權外掛程式支援彈性且強大的權限語法。RBAP 支援兩種權限類型,每種權限的語法略有不同。

自訂權限

管理員可以編寫自己的自訂權限,這些權限可以根據集合、請求處理常式、HTTP 方法、特定請求參數等來比對請求。

每個自訂權限都是 permissions 參數下的 JSON 物件,具有以下一個或多個屬性

name

選用

預設值:無

權限的識別碼。

對於自訂權限,這僅用作管理員了解此權限功能的線索。

設定此參數時必須小心,避免與 Solr 的預先定義權限之一衝突,這些權限的名稱是保留的。如果此名稱與預先定義的權限相符,Solr 會忽略設定的任何其他屬性,而是使用預先定義權限的語意。

collection

選用

預設值:* (全部)

定義權限套用的集合。值可以是單一集合名稱,也可以是包含多個集合的 JSON 陣列。

萬用字元 * 用於表示此規則套用於所有集合。同樣,特殊值 null 可用於表示此權限管理 Solr 不受集合限制(「管理」)的 API。

collection 參數只能包含真實的集合名稱。目前無法用於比對別名。

+ 別名會在叫用 Solr 的安全外掛程式之前解析。如果給定一個別名作為值的 collection 參數將永遠不會比對,因為 RBAP 會將別名名稱與已解析的集合名稱進行比較。

+ 請改為設定一個 collection 參數,其中包含相關別名中的所有集合(或 * 萬用字元)。

path

選用

預設值:null

定義權限套用的路徑。值可以是單一路徑字串,也可以是包含多個字串的 JSON 陣列。

對於存取集合的 API,路徑值應在集合名稱之後開始,並且通常看起來就像請求處理常式(例如,"/select")。

對於不受集合限制(又稱「管理」)的 API,路徑值應從 "/admin 路徑段開始。萬用字元 \* 可用於表示此權限套用於所有路徑。

method

選用

預設值:*

定義此權限套用的 HTTP 方法。選項包括 HEADPOSTPUTGETDELETE 和萬用字元 \*。也可以使用 JSON 陣列指定多個值。

params

選用

預設值:無

定義權限套用的查詢參數。該值是一個 JSON 物件,其中包含必須比對的請求參數的名稱和值,此權限才能套用。

例如,可以使用此參數來限制角色允許使用集合 API 執行的動作。如果只允許角色執行 LIST 或 CLUSTERSTATUS 請求,您將定義如下

{"params": {
   "action": ["LIST", "CLUSTERSTATUS"]
   }
 }

請求參數值可以是簡單字串或正規表示式。使用前綴 REGEX: 來使用正規表示式比對,而不是更簡單的字串比對。

如果命令 LIST 和 CLUSTERSTATUS 不區分大小寫,則可以將以上範例寫為如下

{"params": {
   "action": ["REGEX:(?i)LIST", "REGEX:(?i)CLUSTERSTATUS"]
 }
}
role

必要

預設值:無

定義允許哪些角色存取此權限控制的 API。可以使用 JSON 陣列指定多個值。萬用字元 * 可用於表示所有角色都可以存取描述的功能。

預先定義的權限

自訂權限讓管理員可以彈性地配置精細的存取控制。但是為了盡可能簡化配置,RBAP 還提供了一些預先定義的權限,涵蓋了許多常見的用例。

管理員可以選擇一個與 Solr 的預先定義權限選項(如下所列)之一相符的 name,來叫用預先定義的權限。Solr 有自己對每個權限的定義,並且在檢查預先定義的權限是否與傳入的請求相符時會使用此資訊。這會犧牲彈性來換取簡單性:預先定義的權限不支援自訂權限允許的 pathparamsmethod 屬性。

預先定義的權限名稱(及其效果)如下

  • security-edit:此權限允許編輯安全性配置,這表示任何通過 API 修改 security.json 的更新動作都將被允許。

  • security-read:此權限允許讀取安全性配置,這表示任何通過 API 讀取 security.json 設定的動作都將被允許。

  • schema-edit:此權限允許使用架構 API編輯集合的架構。請注意,這允許所有集合的架構編輯權限。如果編輯權限應僅套用於特定集合,則需要建立自訂權限。

  • schema-read:此權限允許使用架構 API讀取集合的架構。請注意,這允許所有集合的架構讀取權限。如果讀取權限應僅套用於特定集合,則需要建立自訂權限。

  • config-edit:此權限允許使用 Config APIRequest Parameters API 以及其他修改 configoverlay.json 的 API 來編輯集合的組態。由於組態可以從各種位置新增程式庫/自訂程式碼,因此明確允許具有此權限的使用者透過信任的 SolrConfig 載入任何新程式碼。請注意,這允許所有集合的組態編輯權限。如果編輯權限僅應適用於特定集合,則需要建立自訂權限。

  • config-read:此權限允許使用 Config APIRequest Parameters APIConfigsets API、管理 UI 的 檔案畫面 以及其他存取組態的 API 來讀取集合的組態。請注意,這允許所有集合的組態讀取權限。如果讀取權限僅應適用於特定集合,則需要建立自訂權限。

  • metrics-read:此權限允許存取 Solr 的 Metrics API、一些隱式管理處理常式 (例如 solr/<collection>/admin/mbeanssolr/<collection>/admin/segments) 以及其他公開指標的管理 API。

  • health:此權限允許存取 Solr 的 Health Check 和 Ping 端點,通常用於監控節點或核心是否正常運作。

  • core-admin-edit:可以變更系統狀態的核心管理命令。

  • core-admin-read:核心管理 API 的讀取操作。

  • collection-admin-edit:此權限允許使用 Collections API 來編輯集合的組態。請注意,這允許所有集合的組態編輯權限。如果編輯權限僅應適用於特定集合,則需要建立自訂權限。

    具體而言,將允許 Collections API 的以下動作:

    CREATE

    RELOAD

    SPLITSHARD

    CREATESHARD

    DELETESHARD

    CREATEALIAS

    DELETEALIAS

    DELETE

    DELETEREPLICA

    ADDREPLICA

    CLUSTERPROP

    MIGRATE

    ADDROLE

    REMOVEROLE

    ADDREPLICAPROP

    DELETEREPLICAPROP

    BALANCESHARDUNIQUE

    REBALANCELEADERS

  • collection-admin-read:此權限允許使用 Collections API 來讀取集合的組態。請注意,這允許所有集合的組態讀取權限。如果讀取權限僅應適用於特定集合,則需要建立自訂權限。

    具體而言,將允許 Collections API 的以下動作:

    LIST
    OVERSEERSTATUS
    CLUSTERSTATUS
    REQUESTSTATUS

  • update:此權限允許對任何集合執行任何更新動作。這包括傳送文件以進行索引 (使用更新請求處理常式)。預設情況下,這適用於所有集合 (collection:"*")。

  • read:此權限允許對任何集合執行任何讀取動作。這包括使用搜尋處理常式 (使用請求處理常式) 進行查詢,例如 /select/get/tvrh/terms/clustering/elevate/export/spell/clustering/sql。預設情況下,這適用於所有集合 (collection:"*")。

  • zk-read:從 ZK 讀取內容的權限 (/api/cluster/zk/data/ , /api/cluster/zk/ls/ )

  • all:傳送到 Solr 的任何請求。

權限排序和解析

上面討論的權限語法並不能防止多個權限重疊並應用於相同的 Solr API。在多個權限與傳入請求匹配的情況下,Solr 會選擇第一個匹配的權限並忽略所有其他權限,即使其他權限也會與傳入請求匹配!

由於 Solr 僅使用它找到的第一個匹配權限,因此管理員必須了解 Solr 在處理權限清單時使用的排序方式。

Solr 使用的排序方式很複雜。Solr 會先嘗試檢查任何特定於或與傳入請求相關的權限,只有在沒有任何更具體的權限匹配時,才會移至更通用的權限。實際上,這意味著不同的請求可能會以非常不同的順序檢查相同的權限。

如果傳入請求與集合無關 (不適用於特定集合),Solr 會依下列順序檢查權限:

  1. collection 值為 nullpath 值與請求的請求處理常式匹配的權限

  2. collection 值為 nullpath 值為 * 的權限

  3. collection 值為 nullpath 值為 null 的權限

如果傳入請求是針對集合,Solr 會依下列順序檢查權限:

  1. collectionpath 值與請求完全匹配的權限 (不是萬用字元匹配)

  2. collection 與請求完全匹配,且 path 值為 * 的權限

  3. collection 與請求完全匹配,且 path 值為 null 的權限

  4. path 與請求完全匹配,且 collection 值為 * 的權限

  5. collectionpath 值皆為 * 的權限。

  6. collection 值為 *path 值為 null 的權限

舉例來說,請考慮以下權限:

{"name": "read", "role": "dev"}, (1)
{"name": "coll-read", "path": "/select", "role": "*"}, (2)
{"name": "techproducts-read", "collection": "techproducts", "role": "other", "path": "/select"}, (3)
{"name": "all", "role": "admin"} (4)

此清單中的所有權限都與 /select 查詢匹配。但是,將根據查詢的集合使用不同的權限。

對於 "techproducts" 集合的查詢,將使用權限 3,因為它專門針對 "techproducts"。只有具有 other 角色的使用者才會獲得授權。

另一方面,對於名為 collection1 的集合的查詢,最明確存在的權限是權限 2,因此所有角色都會獲得存取權。

授權 API

授權 API 端點

/admin/authorization:接受一組指令來建立權限、將權限對應至角色,以及將角色對應至使用者。

管理權限

三個命令控制管理權限:

  • set-permission:建立新的權限、覆寫現有的權限定義,或將預定義的權限指派給角色。

  • update-permission:更新現有權限定義的某些屬性。

  • delete-permission:移除權限定義。

建立的屬性可以是自訂的或預定義的。

除了上面討論的權限語法之外,這些命令也允許權限具有 before 屬性,其值與此新權限應放置在 security.json 中之前權限的索引匹配。

以下程式碼會建立一個名為 "collection-mgr" 的新權限,該權限允許建立和列出集合。此權限將放置在 "read" 權限之前。另請注意,我們已將 collection 定義為 null,因為對 Collections API 的請求從來都不是集合特定的。

curl --user solr:SolrRocks -H 'Content-type:application/json' -d '{
  "set-permission": {"collection": null,
                     "path":"/admin/collections",
                     "params":{"action":["LIST", "CREATE"]},
                     "before": 3,
                     "role": "admin"}
}' https://127.0.0.1:8983/solr/admin/authorization

將對所有集合的更新權限套用至名為 dev 的角色,並將讀取權限套用至名為 guest 的角色

curl --user solr:SolrRocks -H 'Content-type:application/json' -d '{
  "set-permission": {"name": "update", "role":"dev"},
  "set-permission": {"name": "read", "role":"guest"}
}' https://127.0.0.1:8983/solr/admin/authorization

更新或刪除權限

可以使用它們在清單中的索引來存取權限。使用 /admin/authorization API 來查看現有的權限及其索引。

以下範例更新索引 3 處權限的 'role' 屬性

curl --user solr:SolrRocks -H 'Content-type:application/json' -d '{
  "update-permission": {"index": 3,
                       "role": ["admin", "dev"]}
}' https://127.0.0.1:8983/solr/admin/authorization

以下範例刪除索引 3 處的權限

curl --user solr:SolrRocks -H 'Content-type:application/json' -d '{
  "delete-permission": 3
}' https://127.0.0.1:8983/solr/admin/authorization

將角色對應至使用者

單一命令允許將角色對應至使用者:

  • set-user-role:將使用者對應至權限。

若要移除使用者的權限,您應將角色設定為 null。沒有任何命令可以刪除使用者角色。

提供給命令的值只是一個使用者 ID 以及使用者應該擁有的角色。

例如,以下程式碼會授予使用者 "solr" "admin" 和 "dev" 角色,並從使用者 ID "harry" 中移除所有角色

curl -u solr:SolrRocks -H 'Content-type:application/json' -d '{
   "set-user-role" : {"solr": ["admin","dev"],
                      "harry": null}
}' https://127.0.0.1:8983/solr/admin/authorization