Apache HTTP Server 2.4 版
描述 | 核心授权 |
---|---|
状态 | 基础 |
模块标识符 | authz_core_module |
源文件 | mod_authz_core.c |
兼容性 | 在 Apache HTTPD 2.3 及更高版本中可用 |
此模块提供核心授权功能,以便允许或拒绝已验证用户访问网站的某些部分。 mod_authz_core
提供注册各种授权提供者的功能。它通常与身份验证提供者模块(如 mod_authn_file
)和授权模块(如 mod_authz_user
)一起使用。它还允许将高级逻辑应用于授权处理。
授权容器指令 <RequireAll>
、<RequireAny>
和 <RequireNone>
可以相互组合,也可以与 Require
指令组合,以表达复杂的授权逻辑。
以下示例表达了以下授权逻辑。为了访问资源,用户必须是 superadmin
用户,或者同时属于 admins
组和 Administrators
LDAP 组,并且要么属于 sales
组,要么具有 LDAP dept
属性 sales
。此外,为了访问资源,用户不能属于 temps
组或 LDAP 组 Temporary Employees
。
<Directory "/www/mydocs"> <RequireAll> <RequireAny> Require user superadmin <RequireAll> Require group admins Require ldap-group "cn=Administrators,o=Airius" <RequireAny> Require group sales Require ldap-attribute dept="sales" </RequireAny> </RequireAll> </RequireAny> <RequireNone> Require group temps Require ldap-group "cn=Temporary Employees,o=Airius" </RequireNone> </RequireAll> </Directory>
mod_authz_core
提供了一些通用授权提供者,可与 Require
指令一起使用。
env
提供者允许根据 环境变量 的存在来控制对服务器的访问。当指定 Require env env-variable
时,如果存在环境变量 env-variable,则请求将被允许访问。服务器提供了基于客户端请求的特征以灵活的方式设置环境变量的能力,使用 mod_setenvif
提供的指令。因此,此指令可用于根据客户端的 User-Agent
(浏览器类型)、Referer
或其他 HTTP 请求标头字段等因素来允许访问。
SetEnvIf User-Agent "^KnockKnock/2\.0" let_me_in <Directory "/docroot"> Require env let_me_in </Directory>
在本例中,用户代理字符串以 KnockKnock/2.0
开头的浏览器将被允许访问,而其他所有浏览器将被拒绝访问。
当服务器通过内部 子请求(如查找 DirectoryIndex
或使用 mod_autoindex
生成目录列表)查找路径时,每个请求的环境变量在子请求中不会被继承。此外,由于 mod_setenvif
在其中采取操作的 API 阶段,SetEnvIf
指令不会在子请求中单独评估。
all
提供者模拟了以前由 'Allow from all' 和 'Deny from all' 指令提供的功能。此提供者可以接受两个参数之一,即 'granted' 或 'denied'。以下示例将授予或拒绝所有请求的访问权限。
Require all granted
Require all denied
method
提供者允许在授权决策中使用 HTTP 方法。GET 和 HEAD 方法被视为等效。TRACE 方法对该提供者不可用,请改用 TraceEnable
。
以下示例将仅允许 GET、HEAD、POST 和 OPTIONS 请求
Require method GET POST OPTIONS
以下示例将允许 GET、HEAD、POST 和 OPTIONS 请求无需身份验证,并要求所有其他方法的有效用户
<RequireAny> Require method GET POST OPTIONS Require valid-user </RequireAny>
expr
提供者允许根据任意表达式来进行授权决策。
Require expr "%{TIME_HOUR} -ge 9 && %{TIME_HOUR} -le 17"
<RequireAll> Require expr "!(%{QUERY_STRING} =~ /secret/)" Require expr "%{REQUEST_URI} in { '/example.cgi', '/other.cgi' }" </RequireAll>
Require expr "!(%{QUERY_STRING} =~ /secret/) && %{REQUEST_URI} in { '/example.cgi', '/other.cgi' }"
语法在 ap_expr 文档中描述。在 httpd 2.4.16 之前,必须省略周围的双引号。
通常,表达式在身份验证之前进行评估。但是,如果表达式返回 false 并引用变量 %{REMOTE_USER}
,则将执行身份验证,并且表达式将重新评估。
可以在配置文件中创建扩展授权提供者,并为其分配别名。然后,可以通过 Require
指令以与基本授权提供者相同的方式引用别名提供者。除了创建和别名扩展提供者的能力之外,它还允许同一个扩展授权提供者被多个位置引用。
以下示例基于 ldap-group 授权提供者创建了两个不同的 ldap 授权提供者别名。此示例允许单个授权位置检查多个 ldap 主机中的组成员资格
<AuthzProviderAlias ldap-group ldap-group-alias1 "cn=my-group,o=ctx"> AuthLDAPBindDN "cn=youruser,o=ctx" AuthLDAPBindPassword yourpassword AuthLDAPUrl "ldap://ldap.host/o=ctx" </AuthzProviderAlias> <AuthzProviderAlias ldap-group ldap-group-alias2 "cn=my-other-group,o=dev"> AuthLDAPBindDN "cn=yourotheruser,o=dev" AuthLDAPBindPassword yourotherpassword AuthLDAPUrl "ldap://other.ldap.host/o=dev?cn" </AuthzProviderAlias> Alias "/secure" "/webpages/secure" <Directory "/webpages/secure"> Require all granted AuthBasicProvider file AuthType Basic AuthName LDAP_Protected_Place #implied OR operation Require ldap-group-alias1 Require ldap-group-alias2 </Directory>
描述 | 控制每个配置部分的授权逻辑与前面配置部分的授权逻辑的组合方式。 |
---|---|
语法 | AuthMerging Off | And | Or |
默认值 | AuthMerging Off |
上下文 | directory, .htaccess |
覆盖 | AuthConfig |
状态 | 基础 |
模块 | mod_authz_core |
当启用授权时,它通常会由每个后续的 配置部分 继承,除非指定了不同的授权指令集。这是默认操作,对应于显式设置 AuthMerging Off
。
但是,在某些情况下,可能希望将配置部分的授权与它的前驱者的授权结合起来,同时合并配置部分。对于这种情况,有两个选项可用,And
和 Or
。
当配置部分包含 AuthMerging And
或 AuthMerging Or
时,它的授权逻辑将与最近的前驱者(根据配置部分的总体顺序)的授权逻辑结合起来,该前驱者也包含授权逻辑,就好像这两个部分都共同包含在一个 <RequireAll>
或 <RequireAny>
指令中一样。
AuthMerging
的设置不会继承到它出现的配置部分之外。在以下示例中,只有属于 alpha
组的用户才能访问 /www/docs
。属于 alpha
或 beta
组的用户可以访问 /www/docs/ab
。但是,AuthMerging
的默认 Off
设置应用于 /www/docs/ab/gamma
的 <Directory>
配置部分,因此该部分的授权指令将覆盖前面部分的授权指令。因此,只有属于 gamma
组的用户才能访问 /www/docs/ab/gamma
。<Directory "/www/docs"> AuthType Basic AuthName Documents AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" Require group alpha </Directory> <Directory "/www/docs/ab"> AuthMerging Or Require group beta </Directory> <Directory "/www/docs/ab/gamma"> Require group gamma </Directory>
描述 | 包含一组表示基本授权提供者扩展的指令,并由指定的别名引用 |
---|---|
语法 | <AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> |
上下文 | 服务器配置 |
状态 | 基础 |
模块 | mod_authz_core |
<AuthzProviderAlias>
和 </AuthzProviderAlias>
用于包含一组授权指令,这些指令可以通过使用 Require
指令的别名来引用。
如果 Require-Parameters 中需要多个参数,则必须将它们括在引号中。否则,只考虑第一个参数。
# In this example, for both addresses to be taken into account, they MUST be enclosed # between quotation marks <AuthzProviderAlias ip reject-ips "XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY"> </AuthzProviderAlias> <Directory "/path/to/dir"> <RequireAll> Require not reject-ips Require all granted </RequireAll> </Directory>
描述 | 如果身份验证成功但授权失败,则发送 '403 FORBIDDEN' 而不是 '401 UNAUTHORIZED' |
---|---|
语法 | AuthzSendForbiddenOnFailure On|Off |
默认值 | AuthzSendForbiddenOnFailure Off |
上下文 | directory, .htaccess |
状态 | 基础 |
模块 | mod_authz_core |
兼容性 | 在 Apache HTTPD 2.3.11 及更高版本中可用 |
如果身份验证成功但授权失败,Apache HTTPD 默认情况下将以 '401 UNAUTHORIZED' 的 HTTP 响应代码进行响应。这通常会导致浏览器再次向用户显示密码对话框,这在所有情况下都不希望出现。 AuthzSendForbiddenOnFailure
允许将响应代码更改为 '403 FORBIDDEN'。
在缺少授权的情况下修改响应会削弱密码的安全性,因为它会向可能的攻击者透露他猜测的密码是正确的。
描述 | 测试已验证用户是否被授权提供者授权。 |
---|---|
语法 | Require [not] entity-name [entity-name] ... |
上下文 | directory, .htaccess |
覆盖 | AuthConfig |
状态 | 基础 |
模块 | mod_authz_core |
此指令测试已验证用户是否根据特定授权提供者和指定的限制获得授权。 mod_authz_core
提供以下通用授权提供者
Require all granted
Require all denied
Require env env-var [env-var] ...
Require method http-method [http-method] ...
Require expr expression
由 mod_authz_user
、mod_authz_host
和 mod_authz_groupfile
提供的一些允许的语法是
Require user userid [userid] ...
Require group group-name [group-name] ...
需要有效用户
需要 IP 10.172.20.192.168.2
需要正向 DNS dynamic.example.org
实现 require 选项的其他授权模块包括 mod_authnz_ldap
、mod_authz_dbm
、mod_authz_dbd
、mod_authz_owner
和 mod_ssl
。
在大多数情况下,为了完成身份验证和授权配置,Require
必须与 AuthName
、AuthType
和 AuthBasicProvider
或 AuthDigestProvider
指令以及 AuthUserFile
和 AuthGroupFile
等指令(用于定义用户和组)一起使用才能正常工作。示例
AuthType Basic AuthName "Restricted Resource" AuthBasicProvider file AuthUserFile "/web/users" AuthGroupFile "/web/groups" Require group admin
以这种方式应用的访问控制对所有方法都有效。这通常是期望的结果。如果您希望仅对特定方法应用访问控制,而将其他方法保持不受保护,则将 Require
语句放在 <Limit>
部分中。
可以使用 not
选项否定 Require
指令的结果。与其他被否定的授权指令 <RequireNone>
一样,当 Require
指令被否定时,它只能失败或返回中性结果,因此可能永远无法独立授权请求。
在以下示例中,alpha
和 beta
组中的所有用户都被授权,除了那些也在 reject
组中的用户。
<Directory "/www/docs"> <RequireAll> Require group alpha beta Require not group reject </RequireAll> </Directory>
当在单个 配置部分 中使用多个 Require
指令,并且没有包含在另一个授权指令(如 <RequireAll>
)中时,它们隐式地包含在 <RequireAny>
指令中。因此,第一个授权用户的指令将授权整个请求,后续的 Require
指令将被忽略。
在 Location
部分中设置授权指令时要小心,这些部分与从文件系统中提供的內容重叠。默认情况下,这些 配置部分 将覆盖 Directory
和 Files
部分中的授权配置。
可以使用 AuthMerging
指令来控制授权配置部分的合并方式。
描述 | 将一组授权指令括起来,这些指令中不能有任何指令失败,并且至少要有一条指令成功,才能使封闭指令成功。 |
---|---|
语法 | <RequireAll> ... </RequireAll> |
上下文 | directory, .htaccess |
覆盖 | AuthConfig |
状态 | 基础 |
模块 | mod_authz_core |
<RequireAll>
和 </RequireAll>
用于将一组授权指令括起来,这些指令中不能有任何指令失败,并且至少要有一条指令成功,才能使 <RequireAll>
指令成功。
如果 <RequireAll>
指令中包含的指令都没有失败,并且至少有一条指令成功,则 <RequireAll>
指令成功。如果没有任何指令成功,也没有任何指令失败,则它将返回中性结果。在所有其他情况下,它将失败。
描述 | 将一组授权指令括起来,这些指令中至少要有一条指令成功,才能使封闭指令成功。 |
---|---|
语法 | <RequireAny> ... </RequireAny> |
上下文 | directory, .htaccess |
覆盖 | AuthConfig |
状态 | 基础 |
模块 | mod_authz_core |
<RequireAny>
和 </RequireAny>
用于将一组授权指令括起来,这些指令中至少要有一条指令成功,才能使 <RequireAny>
指令成功。
如果 <RequireAny>
指令中包含的一条或多条指令成功,则 <RequireAny>
指令成功。如果没有任何指令成功,也没有任何指令失败,则它将返回中性结果。在所有其他情况下,它将失败。
<RequireAny>
指令的结果。(最多它们会导致指令失败,在这种情况下,它们失败了,而所有其他指令都返回了中性值。)因此,被否定的授权指令不允许在 <RequireAny>
指令中使用。描述 | 将一组授权指令括起来,这些指令中不能有任何指令成功,才能使封闭指令不失败。 |
---|---|
语法 | <RequireNone> ... </RequireNone> |
上下文 | directory, .htaccess |
覆盖 | AuthConfig |
状态 | 基础 |
模块 | mod_authz_core |
<RequireNone>
和 </RequireNone>
用于将一组授权指令括起来,这些指令中不能有任何指令成功,才能使 <RequireNone>
指令不失败。
如果 <RequireNone>
指令中包含的一条或多条指令成功,则 <RequireNone>
指令失败。在所有其他情况下,它将返回中性结果。因此,与其他被否定的授权指令 Require not
一样,它永远无法独立授权请求,因为它永远无法返回成功结果。但是,它可以用来限制有权访问资源的用户集。
<RequireNone>
指令的结果。因此,被否定的授权指令不允许在 <RequireNone>
指令中使用。