Apache 模块 mod_authnz_fcgi

Description:允许 FastCGI 授权者应用程序处理 Apache httpd 身份验证和授权
Status:Extension
Module Identifier:authnz_fcgi_module
Source File:mod_authnz_fcgi.c
Compatibility:在版本 2.4.10 和更高版本中可用

Summary

此模块允许 FastCGI 授权者应用程序对用户进行身份验证并授权对资源的访问。它支持参与单个阶段的身份验证和授权的通用 FastCGI 授权者,以及参与一个或两个阶段的 Apache httpd 特定的认证者和授权者。

FastCGI 授权者可以使用用户 ID 和密码进行身份验证,例如用于基本身份验证,也可以使用任意机制进行身份验证。

Invocation modes

该模块支持的 FastCGI 授权者的调用模式有两个 Feature,即* type *和 auth * mechanism *。

类型只是用于身份验证的authn,用于授权的authz或用于组合的身份验证和授权的authnz

Auth * mechanism *是指 Apache httpd 的配置机制和处理阶段,可以是AuthBasicProviderRequirecheck_user_id。其中的前两个对应于用于参与适当处理阶段的指令。

每种模式的说明:

  • 类型 authn机制 AuthBasicProvider

    • 在此模式下,FCGI_ROLE设置为AUTHORIZER,而FCGI_APACHE_ROLE设置为AUTHENTICATOR。必须使用AuthnzFcgiDefineProvider将应用程序定义为提供程序类型* authn *,并使用AuthBasicProvider启用该应用程序。调用时,应用程序应使用提供的用户 ID 和密码对 Client 端进行身份验证。示例应用程序:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHENTICATOR";
    die if $ENV{'FCGI_ROLE'}        ne "AUTHORIZER";
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" ) {
        print "Status: 200\n";
        print "Variable-AUTHN_1: authn_01\n";
        print "Variable-AUTHN_2: authn_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
    }
}

Example configuration:

AuthnzFcgiDefineProvider authn FooAuthn fcgi://localhost:10102/
<Location "/protected/">
  AuthType Basic
  AuthName "Restricted"
  AuthBasicProvider FooAuthn
  Require ...
</Location>
  • 类型 authz机制 Require

    • 在此模式下,FCGI_ROLE设置为AUTHORIZER,而FCGI_APACHE_ROLE设置为AUTHORIZER。必须使用AuthnzFcgiDefineProvider将应用程序定义为提供程序类型* authz *。调用时,应用程序应使用提供的用户 ID 和其他请求数据来授权 Client 端。示例应用程序:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHORIZER";
    die if $ENV{'FCGI_ROLE'}        ne "AUTHORIZER";
    die if $ENV{'REMOTE_PASSWD'};

    print STDERR "This text is written to the web server error log.\n";

    if ($ENV{'REMOTE_USER'} eq "foo1") {
        print "Status: 200\n";
        print "Variable-AUTHZ_1: authz_01\n";
        print "Variable-AUTHZ_2: authz_02\n";
        print "\n";
    }
    else {
        print "Status: 403\n\n";
    }
}

Example configuration:

AuthnzFcgiDefineProvider authz FooAuthz fcgi://localhost:10103/
<Location "/protected/">
  AuthType ...
  AuthName ...
  AuthBasicProvider ...
  Require FooAuthz
</Location>
  • 类型 authnz机制 AuthBasicProvider * * Require

    • 在此模式下,该模式支持与 Web 服务器无关的 FastCGI AUTHORIZER协议,将FCGI_ROLE设置为AUTHORIZER而不设置FCGI_APACHE_ROLE。必须使用AuthnzFcgiDefineProvider将应用程序定义为提供程序类型* authnz *。该应用程序应使用用户 ID,密码和其他请求数据在同一调用中处理身份验证和授权。调用发生在 Apache httpd API 身份验证阶段。如果应用程序返回 200 并且在授权阶段(通过Require)调用了相同的提供程序,则 mod_authnz_fcgi 将在授权阶段成功返回,而无需调用该应用程序。示例应用程序:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'};
    die if $ENV{'FCGI_ROLE'} ne "AUTHORIZER";
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" &&
        $ENV{'REQUEST_URI'} =~ m%/bar/.*%) {
        print "Status: 200\n";
        print "Variable-AUTHNZ_1: authnz_01\n";
        print "Variable-AUTHNZ_2: authnz_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
    }
}

Example configuration:

AuthnzFcgiDefineProvider authnz FooAuthnz fcgi://localhost:10103/
<Location "/protected/">
  AuthType Basic
  AuthName "Restricted"
  AuthBasicProvider FooAuthnz
  Require FooAuthnz
</Location>
  • 类型 authn机制 check_user_id

#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHENTICATOR";
    die if $ENV{'FCGI_ROLE'} ne "AUTHORIZER";

    # This authorizer assumes that the RequireBasicAuth option of 
    # AuthnzFcgiCheckAuthnProvider is On:
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" ) {
        print "Status: 200\n";
        print "Variable-AUTHNZ_1: authnz_01\n";
        print "Variable-AUTHNZ_2: authnz_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
        # If a response body is written here, it will be returned to
        # the client.
    }
}

Example configuration:

AuthnzFcgiDefineProvider authn FooAuthn fcgi://localhost:10103/
<Location "/protected/">
  AuthType ...
  AuthName ...
  AuthnzFcgiCheckAuthnProvider FooAuthn \
                               Authoritative On \
                               RequireBasicAuth Off \
                               UserExpr "%{reqenv:REMOTE_USER}"
  Require ...
</Location>

Additional examples

  • 如果您的应用程序支持单独的身份验证和授权角色(AUTHENTICATORAUTHORIZER),则即使它们 Map 到同一应用程序,也请按照以下方式定义单独的提供程序:
AuthnzFcgiDefineProvider authn  FooAuthn  fcgi://localhost:10102/
AuthnzFcgiDefineProvider authz  FooAuthz  fcgi://localhost:10102/

AuthBasicProvider上指定 authn 提供程序,在Require上指定 authz 提供程序:

AuthType Basic
AuthName "Restricted"
AuthBasicProvider FooAuthn
Require FooAuthz
  • 如果您的应用程序支持通用的AUTHORIZER角色(一次调用中的身份验证和授权者),请按以下方式定义一个提供程序:
AuthnzFcgiDefineProvider authnz FooAuthnz fcgi://localhost:10103/

AuthBasicProviderRequire上指定 authnz 提供程序:

AuthType Basic
AuthName "Restricted"
AuthBasicProvider FooAuthnz
Require FooAuthnz

Limitations

以下是当前尚未实现的潜在功能:

  • Apache httpd 访问检查器

    • Apache httpd API“访问检查”阶段是与身份验证和授权分开的阶段。其他一些 FastCGI 实现实现了此阶段,该阶段由FCGI_APACHE_ROLEACCESS_CHECKER的设置表示。
  • 本地(Unix)套接字或管道

    • 当前仅支持 TCP 套接字。
  • 支持 mod_authn_socache

    • 应该为参与 Apache httpd 样式认证的应用程序实现 mod_authn_socache 交互。
  • 支持使用 AuthDigestProvider 进行摘要身份验证

    • 预计这将是一个永久性的限制,因为没有用于检索哈希的授权者流程。
  • 应用程序 Management

    • 预期这将永久超出此模块的范围。申请过程必须通过其他方式控制。例如,fcgistarter可用于启动它们。
  • AP_AUTH_INTERNAL_PER_URI

    • 当前,所有提供程序都已注册为 AP_AUTH_INTERNAL_PER_CONF,这意味着不会再对具有与初始请求相同的访问控制配置的内部子请求进行检查。
  • 协议数据字符集转换

    • 如果 mod_authnz_fcgi 在 EBCDIC 编译环境中运行,则所有 FastCGI 协议数据都将写入 EBCDIC 中,并有望在 EBCDIC 中接收。
  • 每个连接多个请求

    • 当前,在处理的每个阶段之后都关闭与 FastCGI 授权者的连接。例如,如果授权者分别处理* authn authz *阶段,则将使用两个连接。
  • URI Mapping

    • 无法 Map 来自 Client 端的 URI,例如与 FastCGI 响应器一起使用的ProxyPass

Logging

  • 处理错误记录在日志级别error或更高级别。

  • 应用程序编写的消息记录在日志级别warn

  • 用于调试的常规消息记录在日志级别debug

  • 传递给应用程序的环境变量以日志级别trace2记录。 REMOTE_PASSWD变量的值将被遮盖,但“其他任何敏感数据将在日志中可见” **。

  • 模块和 FastCGI 应用程序之间的所有 I/O(包括所有环境变量)将以可打印和十六进制格式记录在日志级别trace5所有敏感数据将在日志中可见.

LogLevel可用于配置特定于 mod_authnz_fcgi 的日志级别。例如:

LogLevel info authnz_fcgi:trace8

AuthnzFcgiCheckAuthnProvider Directive

Description:使 FastCGI 应用程序能够处理 check_authn 身份验证钩子。
Syntax:AuthnzFcgiCheckAuthnProvider provider-name|None option ...
Default:none
Context:directory
Status:Extension
Module:mod_authnz_fcgi

此伪指令用于使 FastCGI 授权者处理认证或授权的特定处理阶段。

FastCGI 授权者的某些功能要求使用此伪指令而不是AuthBasicProvider来启用:

  • 非基本认证;通常,确定 Client 端的用户 ID 并从授权者处返回。请参阅下面的UserExpr选项

  • 选择自定义响应代码;对于来自授权者的非 200 响应,来自授权者的代码将是响应的状态

  • 设置非 200 响应的正文;如果授权者为响应正文提供非 200 的响应,则该正文将返回给 Client 端;最多支持 8192 字节的文本

  • provider-name

    • 这是使用AuthnzFcgiDefineProvider定义的提供程序的名称。
  • None

    • 指定None以在外部范围(例如,父目录)中禁用使用此伪指令启用的提供程序。
  • option

    • 支持以下选项:
  • Authority 性 On | Off(默认为 On)

    • 这控制了当该模块配置了 FastCGI 授权器并且使请求失败时,是否允许其他模块运行。

    • DefaultUser *用户 ID *

      • 当授权者返回成功并且UserExpr被配置并计算为空字符串(例如,授权者未返回变量)时,该值将用作用户 ID。当授权者具有来宾或未经身份验证的概念时,通常使用此方法,并且来宾用户和来宾用户被 Map 到某些特定的用户 ID 以进行日志记录和其他用途。
    • RequireBasicAuth On | Off(默认为 Off)

      • 这控制在将请求传递给授权者之前是否需要基本身份验证。如果需要,将在没有用户 ID 和密码的情况下调用授权者。如果没有该请求,将返回 401.
    • UserExpr * expr *(无默认值)

      • 如果 Client 端不提供基本身份验证,并且授权者确定用户,则在调用授权者后评估的该表达式将确定用户。该表达式位于ap_expr syntax之后,并且必须解析为字符串。典型的用法是使用诸如UserExpr "%{reqenv:XXX}"之类的选项来引用授权者返回的Variable-XXX设置。如果指定了此选项,并且在成功认证之后无法使用表达式检索用户 ID,则该请求将被拒绝,并显示 500 错误。

AuthnzFcgiDefineProvider Directive

Description:将 FastCGI 应用程序定义为身份验证和/或授权的提供者
Syntax:AuthnzFcgiDefineProvider type provider-name backend-address
Default:none
Context:server config
Status:Extension
Module:mod_authnz_fcgi

该指令用于将 FastCGI 应用程序定义为特定阶段的身份验证或授权的提供程序。

  • type

    • 必须将其设置为* authn 进行认证, authz 进行授权,或 authnz *进行两次检查的通用 FastCGI 授权方。
  • provider-name

  • backend-address

    • 它以* fcgi:// hostname:port/*的形式指定应用程序的地址。申请流程必须独立 Management,例如fcgistarter