Apache 模块 mod_authz_core

Description:Core Authorization
Status:Base
Module Identifier:authz_core_module
Source File:mod_authz_core.c
Compatibility:在 Apache HTTPD 2.3 和更高版本中可用

Summary

该模块提供了核心授权功能,因此可以允许或拒绝通过身份验证的用户访问网站的某些部分。 mod_authz_core提供了注册各种授权提供者的功能。它通常与诸如mod_authn_file之类的身份验证提供程序模块和诸如mod_authz_user之类的授权模块结合使用。它还允许将高级逻辑应用于授权处理。

Authorization Containers

授权容器指令<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指令一起使用的通用授权提供程序。

Require env

env提供程序允许基于environment variable的存在来控制对服务器的访问。指定Require env env-variable时,如果环境变量 env-variable 存在,则允许访问请求。服务器可以使用mod_setenvif提供的指令,根据 Client 端请求的 Feature 灵活地设置环境变量。因此,此指令可用于允许基于 Client 端User-Agent(浏览器类型),Referer或其他 HTTP 请求 Headers 字段等因素进行访问。

SetEnvIf User-Agent "^KnockKnock/2\.0" let_me_in
<Directory "/docroot">
    Require env let_me_in
</Directory>

在这种情况下,用户代理字符串以KnockKnock/2.0开头的浏览器将被允许访问,所有其他浏览器将被拒绝。

当服务器通过内部subrequest查找路径(例如查找DirectoryIndex或使用mod_autoindex生成目录列表)时,在子请求中不会继承每个请求的环境变量。此外,由于 API 阶段mod_setenvif会采取行动,因此在子请求中不会单独评估SetEnvIf指令。

Require all

all提供程序模仿了以前的“所有人允许”和“所有人拒绝”指令提供的功能。此提供程序可以采用“授予”或“拒绝”两个参数之一。以下示例将授予或拒绝访问所有请求的权限。

Require all granted
Require all denied

Require method

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>

Require expr

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指令以与基本授权提供者相同的方式引用别名提供者。除了具有创建扩展提供者并为其别名的功能外,它还允许多个位置引用同一扩展授权提供者。

Example

下面的示例基于 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 Directive

Description:控制将每个配置部分的授权逻辑与先前配置部分的授权逻辑组合的方式。
Syntax:AuthMerging Off | And | Or
Default:AuthMerging Off
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

启用授权后,除非指定了不同的授权指令集,否则通常由每个后续configuration section继承。这是默认操作,对应于显式设置AuthMerging Off

但是,在某些情况下,可能希望在合并配置节时将配置节的授权与其前身的授权相结合。在这种情况下,有两个选项AndOr

当配置节包含AuthMerging AndAuthMerging Or时,其授权逻辑将与最接近的前任(根据配置节的整体 Sequences)的授权逻辑相结合,后者也包含授权逻辑,就好像这两个节共同包含在<RequireAll><RequireAny>指令中,分别。

Note

AuthMerging的设置不会在显示该设置的配置部分之外继承。在下面的示例中,仅属于组alpha的用户可以访问/www/docs。属于alphabeta组的用户可以访问/www/docs/ab。但是,默认的Off设置AuthMerging适用于/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>


Directive

Description:包含一组指令,这些指令代表基本授权提供程序的扩展,并由指定的别名引用
Syntax:<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias>
Context:server config
Status:Base
Module: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>

AuthzSendForbiddenOnFailure Directive

Description:如果身份验证成功但授权失败,则发送“ 403 FORBIDDEN”而不是“ 401 UNAUTHORIZED”
Syntax:AuthzSendForbiddenOnFailure On|Off
Default:AuthzSendForbiddenOnFailure Off
Context:directory, .htaccess
Status:Base
Module:mod_authz_core
Compatibility:在 Apache HTTPD 2.3.11 和更高版本中可用

如果认证成功但授权失败,则默认情况下,Apache HTTPD 将使用 HTTP 响应代码“ 401 UNAUTHORIZED”进行响应。这通常会导致浏览器再次向用户显示密码对话,并非在所有情况下都需要。 AuthzSendForbiddenOnFailure允许将响应代码更改为“ 403 FORBIDDEN”。

Security Warning

在缺少授权的情况下修改响应会削弱密码的安全性,因为它向可能的攻击者表明他猜测的密码是正确的。

Require Directive

Description:测试验证的用户是否被授权提供者授权。
Syntax:Require [not] entity-name [entity-name] ...
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

该指令测试是否根据特定的授权提供者和指定的限制对已认证的用户进行了授权。 mod_authz_core提供以下通用授权提供者:

  • Require all granted

    • 无条件允许访问。
  • Require all denied

    • 访问被无条件拒绝。
  • Require env env-var [env-var] ...

    • 仅在设置了给定环境变量之一的情况下才允许访问。
  • Require method http-method [http-method] ...

    • 仅允许使用给定的 HTTP 方法进行访问。
  • Require expr expression

    • 如果 expression 的计算结果为 true,则允许访问。

mod_authz_usermod_authz_hostmod_authz_groupfile提供的一些允许的语法是:

  • Require user userid [userid] ...

    • 只有指定的用户可以访问资源。
  • Require group group-name [group-name] ...

    • 只有命名组中的用户才能访问资源。
  • Require valid-user

    • 所有有效用户都可以访问资源。
  • Require ip 10 172.20 192.168.2

    • 指定 IP 地址范围内的 Client 端可以访问资源。

实现要求选项的其他授权模块包括mod_authnz_ldapmod_authz_dbmmod_authz_dbdmod_authz_ownermod_ssl

在大多数情况下,为了完整的身份验证和授权配置,Require必须随附AuthNameAuthTypeAuthBasicProviderAuthDigestProvider指令以及AuthUserFileAuthGroupFile之类的指令(以定义用户和组)才能正常工作。例:

AuthType Basic
AuthName "Restricted Resource"
AuthBasicProvider file
AuthUserFile "/web/users"
AuthGroupFile "/web/groups"
Require group admin

以这种方式应用的访问控制对“所有”方法均有效。 这通常是需要的. 如果您希望仅将访问控制应用于特定方法,而其他方法不受保护,则将Require语句放在<Limit>部分中。

通过使用not选项可以否定Require指令的结果。与其他否定授权指令<RequireNone>一样,如果否定Require指令,它只会失败或返回中立的结果,因此可能永远不会独立授权请求。

在下面的示例中,alphabeta组中的所有用户均得到授权,但同时也在reject组中的用户除外。

<Directory "/www/docs">
    <RequireAll>
        Require group alpha beta
        Require not group reject
    </RequireAll>
</Directory>

当在单个configuration section中使用多个Require指令并且不包含在另一个授权指令(如<RequireAll>)中时,它们将隐式包含在<RequireAny>指令中。因此,第一个授权用户的用户会授权整个请求,随后的Require指令将被忽略。

Security Warning

Location部分中设置与从文件系统提供的内容重叠的授权指令时,请谨慎行事。默认情况下,这些configuration sections覆盖DirectoryFiles部分中的授权配置。

AuthMerging指令可用于控制如何合并授权配置节。

See also


Directive

Description:封装一组授权伪指令,其中的任何一个授权伪指令都必须失败,并且至少一个必须成功才能使封闭伪指令成功。
Syntax:<RequireAll> ... </RequireAll>
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

<RequireAll></RequireAll>用于封装一组授权指令,这些授权指令中的任何一个都必须失败,并且至少一个必须成功才能使<RequireAll>指令成功。

如果<RequireAll>指令中包含的所有指令均未失败,并且至少有一个成功,则<RequireAll>指令成功。如果没有成功也没有失败,则返回中立结果。在所有其他情况下,它都会失败。

See also


Directive

Description:封装一组授权指令,其中一个授权指令必须成功才能使封装指令成功。
Syntax:<RequireAny> ... </RequireAny>
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

<RequireAny></RequireAny>用于封装一组授权指令,为了使<RequireAny>指令成功,必须授权一组授权指令。

如果<RequireAny>指令中包含的一个或多个指令成功,则<RequireAny>指令成功。如果没有成功也没有失败,则返回中立结果。在所有其他情况下,它都会失败。

Note

由于否定的授权指令无法返回成功的结果,因此它们不会显着影响<RequireAny>指令的结果。 (在它们失败并且所有其他指令返回中性值的情况下,它们最多可能导致该指令失败.)因此,在<RequireAny>指令中不允许使用否定的授权指令。

See also


Directive

Description:封闭一组授权伪指令,其中的任何一个授权伪指令都必须成功才能使封闭伪指令不失败。
Syntax:<RequireNone> ... </RequireNone>
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

<RequireNone></RequireNone>用于封装一组授权伪指令,为了使<RequireNone>伪指令不会失败,必须不授权它们。

如果<RequireNone>指令中包含的一个或多个指令成功,则<RequireNone>指令失败。在所有其他情况下,它返回中性结果。因此,与其他否定授权指令Require not一样,它永远不能独立地授权请求,因为它永远不会返回成功的结果。但是,可以使用它来限制有权访问资源的用户集。

Note

由于否定的授权指令无法返回成功的结果,因此它们不会显着影响<RequireNone>指令的结果。因此,否定的授权指令在<RequireNone>指令内是不允许的。

See also