身份驗證是驗證訪問者是否是他們所聲稱的人的任何過程。授權是允許訪問者進入他們想去的地方或獲得他們想要的資訊的過程。
如果您的網站上的資訊僅對一小部分人使用,下麵這些技巧將幫助您確保看到這些網頁的人員是您想要查看的人。
本文還將介紹保護大多數人將要使用的網站部分的“標準”方法。
1. 前提條件
本文中討論的指令需要在主伺服器配置檔(通常在<Directory>
部分中)或每目錄配置檔(.htaccess
檔)中。
如果計畫使用.htaccess
檔,則需要具有允許在這些檔中放置身份驗證指令的伺服器配置。這是通過AllowOverride
指令完成的,該指令指定可以在每個目錄配置檔中放入哪些指令(如果有)。
由於我們在這裏談論身份驗證,所以需要如下所示的AllowOverride
指令:
AllowOverride AuthConfig
或者,如果您只是將指令直接放在主伺服器配置檔中,需要具有該檔的寫入許可權。
並且您需要瞭解伺服器的目錄結構,以便瞭解某些檔的保存位置。這應該不是非常困難,當到達那一點時,我們會盡力說清楚。
還需要確保模組mod_authn_core
和mod_authz_core
已內置到httpd二進位檔中或由httpd.conf
配置檔加載。這兩個模組都提供核心指令和功能,這些指令和功能對於在Web伺服器中配置和使用身份驗證和授權至關重要。
2. 配置工作
以下是密碼保護伺服器上目錄的基礎知識。
首先,您需要創建一個密碼檔。具體如何執行此操作將取決於您選擇的身份驗證提供程式。稍後會詳細介紹。首先,我們將使用文本密碼檔。
此檔應放置在無法從Web訪問的位置。這樣人們就無法下載密碼檔。例如,如果您的文檔是由/usr/local/apache/htdocs
提供的,則可能需要將密碼檔放在/usr/local/apache/passwd
中。
要創建該檔,請使用Apache附帶的htpasswd實用程式。這將位於安裝Apache的任何位置的bin目錄中。如果已從第三方軟體包安裝Apache,則它可能位於您的執行路徑中。
要創建檔,輸入以下命令:
$ htpasswd -c /usr/local/apache/passwd/passwords rbowen
htpasswd
會要求您輸入密碼,然後再次要求您輸入密碼進行確認:
# htpasswd -c /usr/local/apache/passwd/passwords rbowen
New password: mypassword
Re-type new password: mypassword
Adding password for user rbowen
如果htpasswd
不在你的路徑中,則需要輸入檔的完整路徑才能運行它。使用默認安裝時,它位於/usr/local/apache2/bin/htpasswd
接下來,需要配置伺服器以請求密碼並告知伺服器允許哪些用戶訪問。可以通過編輯httpd.conf
檔或使用.htaccess
檔來執行此操作。例如,如果您希望保護目錄/usr/local/apache/htdocs/secret
,則可以使用以下指令,這些指令放在檔/usr/local/apache/htdocs/secret/.htaccess
中,或放入httpd.conf
在<Directory "/usr/local/apache/htdocs/secret">
部分中。
AuthType Basic
AuthName "Restricted Files"
# (Following line optional)
AuthBasicProvider file
AuthUserFile "/usr/local/apache/passwd/passwords"
Require user rbowen
下麵分別看一看每個指令。AuthType
指令選擇用於驗證用戶身份的方法。最常用的方法是Basic,這是mod_auth_basic
實現的方法。但是,請務必注意,基本身份驗證會將密碼從客戶端發送到未加密的伺服器。因此,除非帶有mod_ssl
,否則此方法不應用於高度敏感的數據。Apache支持另一種身份驗證方法:AuthType Digest
。此方法由mod_auth_digest
實現,旨在更安全。這不再是這種情況,應該使用mod_ssl
加密連接。
AuthName
指令設置要在身份驗證中使用的Realm
。領域有兩個主要功能。首先,客戶端經常將此信息作為密碼對話框的一部分呈現給用戶。其次,客戶端使用它來確定為給定的已驗證區域發送的密碼。
因此,一旦客戶端在“受限檔”區域中進行了身份驗證,它將自動為同一伺服器上標有“受限檔”域的任何區域重試相同的密碼。因此,通過讓多個受限區域共用同一個域,可以防止用戶多次提示輸入密碼。當然,出於安全原因,只要伺服器的主機名發生更改,客戶端就始終需要再次詢問密碼。
在這種情況下,AuthBasicProvider
是可選的,因為file
是此指令的默認值。如果要為身份驗證選擇其他源,則需要使用此指令,例如mod_authn_dbm
或mod_authn_dbd
。
AuthUserFile
指令設置htpasswd
創建的密碼檔的路徑。如果需要填入大量用戶,則搜索純文本檔以在每個請求上對用戶進行身份驗證可能會非常慢。Apache還能夠將用戶資訊存儲在快速資料庫檔中。mod_authn_dbm
模組提供AuthDBMUserFile
指令。可以使用dbmmanage
和htdbm
程式創建和操作這些檔。Apache模組資料庫中的第三方模組提供了許多其他類型的身份驗證選項。
最後,Require指令通過設置允許訪問伺服器的此區域的用戶來提供進程的授權部分。
3. 允許多人進入
上面的指令只允許一個人(特別是用戶名為rbowen
的人)進入目錄。在大多數情況下,不止一個人進入訪問。這種情況下就要使用AuthGroupFile
了。
如果要允許多個人進入,則需要創建一個組檔,該組檔將組名與該組中的用戶列表相關聯。此檔的格式非常簡單,您可以使用自己喜歡的編輯器創建它。該檔的內容如下所示:
GroupName: rbowen dpitts sungo rshersey
這只是一個由空格分隔的長行中的成員列表。要將用戶添加到現有密碼檔,請鍵入:
htpasswd /usr/local/apache/passwd/passwords dpitts
您將獲得與以前相同的回應,但它將附加到現有檔,而不是創建新檔。(這裏是使用-c
來創建一個新的密碼檔)。
現在,需要修改.htaccess
檔或<Directory>
塊,如下所示:
AuthType Basic
AuthName "By Invitation Only"
# Optional line:
AuthBasicProvider file
AuthUserFile "/usr/local/apache/passwd/passwords"
AuthGroupFile "/usr/local/apache/passwd/groups"
Require group GroupName
現在,如果他們輸入正確的密碼,那麼GroupName
組中列出並且密碼檔中有條目的任何人都將被允許進入。
還有另一種方法可以讓多個用戶不那麼具體。可以使用以下指令,而不是創建組檔:
Require valid-user
使用它而不是Require
用戶rbowen
行將允許密碼檔中列出的任何人以及正確輸入密碼的人。
4. 可能的問題
由於指定了基本身份驗證的方式,因此每次從伺服器請求文檔時都必須驗證用戶名和密碼。即使您正在重新加載同一頁面以及頁面上的每個圖像(如果它們來自受保護的目錄),這也是如此。可以想像,這會減慢一些事情。減慢速度的因素與密碼檔的大小成正比,因為它必須打開該檔,然後沿用戶列表向下,直到找到名字。每次加載頁面時都必須這樣做。
這樣做的結果是,可以在一個密碼檔中放入多少用戶存在實際限制。此限制將根據您的特定伺服器電腦的性能而有所不同,但是一旦超過幾百個條目,速度可能會有一定下降,並且可能希望在此時考慮不同的身份驗證方法。
5. 替代密碼存儲
由於在純文本檔中存儲密碼存在上述問題,因此可能希望將密碼存儲在其他位置,例如資料庫中。
mod_authn_dbm
和mod_authn_dbd
是使這成為可能的兩個模組。可以選擇dbm
或dbd
作為存儲格式,而不是選擇AuthBasicProvider
檔。
要選擇dbm
檔而不是文本檔,例如:
<Directory "/www/docs/private">
AuthName "Private"
AuthType Basic
AuthBasicProvider dbm
AuthDBMUserFile "/www/passwords/passwd.dbm"
Require valid-user
</Directory>
6. 使用多個供應者
通過引入基於新提供程式的身份驗證和授權體系結構,您不再需要鎖定到單個身份驗證或授權方法。實際上,可以混合和匹配任意數量的提供者,以便為您提供滿足您需求的方案。在以下示例中,使用基於檔和LDAP的身份驗證提供程式。
<Directory "/www/docs/private">
AuthName "Private"
AuthType Basic
AuthBasicProvider file ldap
AuthUserFile "/usr/local/apache/passwd/passwords"
AuthLDAPURL ldap://ldaphost/o=yourorg
Require valid-user
</Directory>
在此示例中,檔提供程式將首先嘗試對用戶進行身份驗證。如果無法對用戶進行身份驗證,則將調用LDAP提供程式。如果您的組織實現了多種類型的身份驗證存儲,則可以擴展身份驗證範圍。其他認證和授權方案可以包括將一種類型的認證與不同類型的授權混合。例如,針對密碼檔進行身份驗證,然後針對LDAP目錄進行授權。
正如可以實現多個身份驗證提供程式一樣,也可以使用多種授權方法。在此示例中,正在使用檔組授權和LDAP組授權。
<Directory "/www/docs/private">
AuthName "Private"
AuthType Basic
AuthBasicProvider file
AuthUserFile "/usr/local/apache/passwd/passwords"
AuthLDAPURL ldap://ldaphost/o=yourorg
AuthGroupFile "/usr/local/apache/passwd/groups"
Require group GroupName
Require ldap-group cn=mygroup,o=yourorg
</Directory>
為了進一步授權,授權容器指令(例如<RequireAll>
和<RequireAny>
)允許應用邏輯,以便可以通過配置完全控制處理授權的順序。
7. 超越授權
現在,可以應用授權的方式比僅針對單個數據存儲的單個檢查更靈活。現在可以使用順序,邏輯和選擇授權方式。
應用邏輯和排序
控制授權的應用方式和順序過去一直是個謎。在Apache 2.2中,引入了基於提供程式的身份驗證機制,以將實際身份驗證過程與授權和支持功能分離。其中一個好處是可以按特定順序配置和調用身份驗證提供程式,而不依賴於auth模組本身的加載順序。同樣基於提供者的機制也已被提交給授權。這意味著Require
指令不僅指定應該使用哪些授權方法,還指定調用它們的順序。多個授權方法的調用順序與Require
指令在配置中出現的順序相同。
通過引入授權容器指令(例如<RequireAll>
和<RequireAny>
),配置還可以控制何時調用授權方法以及何時標準確定何時授予訪問許可權。有關如何使用它們表示複雜授權邏輯的示例,請參閱授權容器。
默認情況下,所有Require
指令的處理都像包含在<RequireAny>
容器指令中一樣。換句話說,如果任何指定的授權方法成功,則授予授權。
使用授權提供程式進行訪問控制
用戶名和密碼驗證只是故事的一部分。通常你想讓人們訪問基於他們授權以外的東西。
授權提供程式all,env,host和ip用於根據其他基於主機的條件允許或拒絕訪問,例如請求文檔的電腦的主機名或IP地址。
這些提供程式的用法通過Require
指令指定。該指令註冊將在請求處理的授權階段調用的授權提供程式。例如:
Require ip address
其中address是IP地址(或部分IP地址)或:
Require host domain_name
其中domain_name
是完全限定的功能變數名稱(或部分功能變數名稱); 如果需要,可以提供多個地址或功能變數名稱。
例如,如果有人向留言板發送垃圾郵件,並且你希望將其保留,則可以執行以下操作:
<RequireAll>
Require all granted
Require not ip 10.252.46.165
</RequireAll>
來自該地址的訪客將無法看到該指令涵蓋的內容。相反,如果您擁有機器名稱而不是IP地址,則可以使用它。
<RequireAll>
Require all granted
Require not host host.example.com
</RequireAll>
而且,如果您想阻止整個域的訪問,只能指定地址或功能變數名稱的一部分:
<RequireAll>
Require all granted
Require not ip 192.168.205
Require not host phishers.example.com moreidiots.example
Require not host ke
</RequireAll>