这在Apache2.2中完美工作,但不在2.4(现在我需要使用2.4):
<AuthnProviderAlias ldap myldap> AuthLDAPBindDN cn=Manager,dc=example,dc=com AuthLDAPBindPassword xxxx AuthLDAPURL ldap://localhost:9011/dc=example,dc=com?uid?sub?(objectClass=*) </AuthnProviderAlias> Listen 48443 <VirtualHost myserver:48443> <Directory /path/to/a/folder> Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch AllowOverride All order allow,deny Allow from all AuthBasicProvider myldap mySecondLdap myThirdLdap ... AuthType Basic AuthName "LDAP authentication for folder" Require valid-user ... </Directory> </VirtualHost>
直接使用来自Apache 2.4的指令mod_authnz_ldap在<Directory >
部分工作:
AuthLDAPBindDN cn=Manager,dc=example,dc=com AuthLDAPBindPassword xxx AuthLDAPURL ldap://localhost:9011/dc=example,dc=com?uid?sub?(objectClass=*) AuthBasicProvider ldap
但是, 这只允许对一个 LDAP服务器进行身份validation,我必须至less对两个进行身份validation。
因此使用AuthnProviderAlias
,它是现在(2.4) mod_authn_core
核心authentication模块的一部分 ,而不是旧的2.2 LDAPauthentication模块mod_authn_alias
。
我已经在debugging模式下编译了所有2.4.x版本(从2.4.1到2.4.6,甚至是当前版本), APR 1.4.8和APR-util 1.5.2 ( -g -O0
)
我试过的是一个debugging会话( gdb --command=debug
,带有'debug'gdb参数文件如下):
file /home/vonc/usr/local/apps/apache/bin/httpd set logging file /home/vonc/gdb.txt set logging on set args -X show args set breakpoint pending on # authn_alias_check_password b mod_authn_core.c:115 # authaliassection b mod_authn_core.c:203 b mod_authn_core.c:255 run wh fs next where
我所看到的是:
mod_authn_core
的authaliassection
函数被调用两次 ,可能是因为server/main.c
在同一个main()
函数中调用了ap_process_config_tree
两次 ( 一次在这里 , 一次 main()
。 该函数获取authcfg
authn_alias_srv_conf *authcfg = (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config, &authn_core_module);
并设置供应商正确的名称“ ldap
”和右别名“ myldap
”
apr_hash_set(authcfg->alias_rec, provider_alias, APR_HASH_KEY_STRING, prvdraliasrec);
但是:当需要检查密码时(在authn_alias_check_password
,它会再次获取authcfg
,并提取提供者 :
provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec, provider_name, APR_HASH_KEY_STRING);
它使用正确的provider_name
',…并且总是返回null
。
这意味着prvdraliasrec->provider->check_password
永远不会被调用。
在http-dev邮件列表 ( 2013年8月23日的“AuthnProviderAlias在2.4中微妙地被破解了” )中的类似问题是未答复的。
你将如何解决这个错误?
这个错误是由于提供者和他们的使用在不同的服务器上下文中造成的。
解决方法:在VH环境之外定义auth,或者如果可以轻松重建,请尝试使用此修补程序: http : //people.apache.org/~covener/patches/authprovider.diff
Index: modules/aaa/mod_authn_core.c =================================================================== --- modules/aaa/mod_authn_core.c (revision 40703) +++ modules/aaa/mod_authn_core.c (working copy) @@ -179,6 +179,12 @@ return (void *) authcfg; } +/* Only per-server directive we have is GLOBAL_ONLY */ +static void *merge_authn_alias_svr_config(apr_pool_t *p, void *basev, void *overridesv) +{ + return basev; +} + static const authn_provider authn_alias_provider = { &authn_alias_check_password, @@ -373,7 +379,7 @@ create_authn_core_dir_config, /* dir config creater */ merge_authn_core_dir_config, /* dir merger --- default is to override */ create_authn_alias_svr_config, /* server config */ - NULL, /* merge server config */ + merge_authn_alias_svr_config, /* merge server config */ authn_cmds, register_hooks /* register hooks */ };
我发现唯一的工作解决方案是修补mod_authn_core.c
,添加2个全局变量,一个用于我想要使用的每个LDAP别名。
这看起来很丑陋:两个LDAP别名在代码中被硬编码。
见提交2f691a6
provider_alias_rec *prvdraliasrec_myldap; provider_alias_rec *prvdraliasrec_companyldap;
这样, merge_authn_core_dir_config()
专门查找这两个别名来注册它们。
if (!prvdraliasrec && strcmp(provider_name,"myldap")==0) { prvdraliasrec=prvdraliasrec_myldap; } if (!prvdraliasrec && strcmp(provider_name,"companyldap")==0) { prvdraliasrec=prvdraliasrec_companyldap; }
authaliassection()
将这些别名定义返回
if ( strcmp(provider_alias,"myldap") == 0 ) { prvdraliasrec_myldap = prvdraliasrec; } if ( strcmp(provider_alias,"companyldap") == 0 ) { prvdraliasrec_companyldap = prvdraliasrec; }
它有效,但它肯定不是“正确的”解决方案。