基於自定義 Header (Apache) 的授權
我有一個在 Apache 反向代理後面執行的服務,它使用自定義標頭“使用者名”和“角色”來辨識使用者及其角色。
我希望 Apache HTTPD 限制對自定義 HTTP 標頭“groupmembership”包含以下之一的人的訪問:“viewer”、“publisher”、“administrator”。
Apache 位於另一個代理之後,該代理對使用者進行身份驗證並填充 HTTP 標頭“使用者名”和“組成員”,其中“組成員”的內容是逗號分隔的組列表。
作為參考,我已經包含了架構的草案。 http-proxy-auth
這怎麼可能?我嘗試使用像
Require expr %{HTTP:iv_groupmembership} in { 'viewer', 'publisher', 'administrator' }
inside這樣的 require 指令<Location />
,但無濟於事。這可以與 mod_rewrite 一起使用嗎?
這是使用 mod_proxy 和 mod_rewrite 的反向代理配置:
RewriteEngine on <Proxy *> Allow from all </Proxy> ProxyRequests Off # store variable values with dummy rewrite rules RewriteRule . - [E=req_scheme:%{REQUEST_SCHEME}] RewriteRule . - [E=http_host:%{HTTP_HOST}] RewriteRule . - [E=req_uri:%{REQUEST_URI}] # set header with variables RequestHeader set X-RSC-Request "%{req_scheme}e://%{http_host}e%{req_uri}e" RewriteCond %{HTTP:Upgrade} =websocket RewriteRule /(.*) ws://localhost:3939/$1 [P,L] RewriteCond %{HTTP:Upgrade} !=websocket RewriteRule /(.*) http://localhost:3939/$1 [P,L] ProxyPass / http://172.17.0.1:3939/ ProxyPassReverse / http://172.17.0.1:3939/
感謝您的任何提示。
編輯:基本上,問題歸結為:如何檢查
groupmembership
標題中以逗號分隔的列表是否包含“管理員”、“發布者”或“查看者”
這應該這樣做。如果您在 header 中有一個逗號分隔的列表
groupmembership
,則使用第一個正則表達式。列表中的一個值必須匹配才能授予訪問權限。如果要匹配 中的確切值
iv_groupmembership
,請取消註釋第二個第三個表達式(並註釋第一個)。編輯:
- 添加
RequestHeader set role
範例,根據需要取消註釋。我只測試了這個Header set role
(在響應中,沒有後端),但應該以RequestHeader
相同的方式工作。編輯2:
<Location/>
為清楚起見已刪除- 添加了
X-Auth-Token
檢查的範例groupmembership
範例配置:
# test for string in comma-separated values, one of the values must match <If "%{HTTP:groupmembership} !~ /(^|,)(viewer|publisher|administrator)(,|$)/"> # combined: X-Auth-Token must be set or one of the roles must exist # <If "%{HTTP:X-Auth-Token} == '' && %{HTTP:groupmembership} !~ /(^|,)(viewer|publisher|administrator)(,|$)/"> # alternative: test for a single value in "iv_groupmembership" (exact match) # <If "! %{HTTP:iv_groupmembership} in { 'viewer', 'publisher', 'administrator' }"> Require all denied </If> # set role of groupmembership # <If "%{HTTP:groupmembership} =~ /(^|,)viewer(,|$)/"> # RequestHeader set role viewer # </If> # <ElseIf "%{HTTP:groupmembership} =~ /(^|,)publisher(,|$)/"> # RequestHeader set role publisher # </ElseIf> # <ElseIf "%{HTTP:groupmembership} =~ /(^|,)administrator(,|$)/"> # RequestHeader set role administrator # </ElseIf> # set role of iv_groupmembership # RequestHeader set role "expr=%{HTTP:iv_groupmembership}"
修改 Apache 中的標頭(如
RequestHeader set iv_groupmembership "viewer"
)以調試/測試配置不起作用,您需要儘早設置標頭。https://httpd.apache.org/docs/2.4/expr.html#vars
表達式解析器提供了許多 %{HTTP_HOST} 形式的變數。請注意,變數的值可能取決於對其求值的請求處理階段。例如,在完成身份驗證之前評估 <If > 指令中使用的表達式。因此,在這種情況下不會設置 %{REMOTE_USER}。
您可以從命令行使用 wget 測試配置,替換
localhost
為您的主機名。# HTTP/1.1 403 Forbidden wget -S -O - http://localhost wget -S -O - --header='groupmembership: xviewer' http://localhost wget -S -O - --header='groupmembership: administratorx' http://localhost wget -S -O - --header='iv_groupmembership: xviewer' http://localhost # HTTP/1.1 200 OK wget -S -O - --header='groupmembership: foo,viewer' http://localhost wget -S -O - --header='groupmembership: publisher,foo' http://localhost wget -S -O - --header='iv_groupmembership: viewer' http://localhost wget -S -O - --header='iv_groupmembership: publisher' http://localhost wget -S -O - --header='iv_groupmembership: administrator' http://localhost
使用 Apache/2.4.25 (Debian) 測試