英文:
.htaccess condition with environment variables not evaluating
问题
Base setup is as follows:
如果域名以 .staging.com 结尾,那么它是暂存环境
- foobar.com.staging.com --> 暂存环境
- foobar.com --> 正式环境
我有以下的 .htaccess 代码:
- 据我所知,所有必要的 Apache 模块都已启用。
- 环境变量(第 1 到 5 行)似乎已正确设置(至少如果我通过 getenv() 函数在 PHP 脚本中检查它们的话是如此)。
- 基本身份验证本身按预期工作。
- 如果我删除 Allow/Require 块周围的
条件,它们也按预期工作。 - 如果我将
条件保留在下面所写的样子,Allow/Require 根本不会被评估。
你有什么错误的想法吗?
感谢 @covener,我成功让它工作了。我的最终解决方案类似于以下内容:
SetEnvIfNoCase Host ^([a-zA-Z-.]*)\.staging\.com$ environment=staging
SetEnvIfNoCase Host ^([a-zA-Z-.]*)(?<!\.staging\.com)$ environment=production
SetEnvIfNoCase Request_URI "^/export" export_folder=true
SetEnvIf Remote_Addr ^1\.2\.3\.4$ authorized_ip=true
SetEnvIf Remote_Addr "^2\.3\.4\.[0-9]+$" authorized_ip=true
AuthUserFile /home/foobar/public_html/.htpasswd
AuthName "Password Protected"
AuthType Basic
<RequireAny>
<RequireAll>
Require expr %{ENV:export_folder} == 'true'
Require expr %{ENV:authorized_ip} == 'true'
</RequireAll>
<RequireAll>
Require expr %{ENV:export_folder} != 'true'
Require expr %{ENV:environment} == 'production'
</RequireAll>
<RequireAll>
Require expr %{ENV:environment} == 'staging'
<RequireAny>
Require expr %{ENV:authorized_ip} == 'true'
Require expr %{REMOTE_USER} != ''
</RequireAny>
</RequireAll>
</RequireAny>
英文:
Base setup is as follows:
If the domain is ending in .staging.com it is the staging environment
- foobar.com.staging.com --> staging environment
- foobar.com --> live environment
I have the following .htaccess code:
- All the necessary Apache modules are enabled as far I can tell.
- The environment variables (line 1-5) are being set properly (at least if I check them within a PHP script via getenv()).
- The basic auth on itself is working as desired
- If I remove the <If> conditions around the Allow/Require blocks those also work as expected
- If I leave the <If> conditions just as they are written below the Allow/Require are simply not being evaluated.
Any idea what I'm doing wrong?
SetEnvIfNoCase Host ^([a-zA-Z-.]*)\.staging\.com$ staging_env=true
SetEnvIfNoCase Host ^([a-zA-Z-.]*)(?<!\.staging\.com)$ live_env=true
SetEnvIfNoCase Request_URI "^/export" export_folder=true
SetEnvIf Remote_Addr ^1\.2\.3\.4$ authorized_ip=true
SetEnvIf Remote_Addr "^2\.3\.4\.[0-9]+$" authorized_ip=true
AuthUserFile /home/foobar/public_html/.htpasswd
AuthName "Password Protected"
AuthType Basic
Order Deny,Allow
Satisfy any
Deny from all
<If "%{ENV:export_folder} == 'true'">
Allow from env=authorized_ip
</If>
<If "%{ENV:export_folder} != 'true' && %{ENV:live_env} == 'true'">
Allow from env=live_env
</If>
<If "%{ENV:staging_env} == 'true'">
Require valid-user
Allow from env=authorized_ip
</If>
Thanks to @covener i managed to get it working. My final solution was something like this:
SetEnvIfNoCase Host ^([a-zA-Z-.]*)\.staging\.com$ environment=staging
SetEnvIfNoCase Host ^([a-zA-Z-.]*)(?<!\.staging\.com)$ environment=production
SetEnvIfNoCase Request_URI "^/export" export_folder=true
SetEnvIf Remote_Addr ^1\.2\.3\.4$ authorized_ip=true
SetEnvIf Remote_Addr "^2\.3\.4\.[0-9]+$" authorized_ip=true
AuthUserFile /home/foobar/public_html/.htpasswd
AuthName "Password Protected"
AuthType Basic
<RequireAny>
<RequireAll>
Require expr %{ENV:export_folder} == 'true'
Require expr %{ENV:authorized_ip} == 'true'
</RequireAll>
<RequireAll>
Require expr %{ENV:export_folder} != 'true'
Require expr %{ENV:environment} == 'production'
</RequireAll>
<RequireAll>
Require expr %{ENV:environment} == 'staging'
<RequireAny>
Require expr %{ENV:authorized_ip} == 'true'
Require expr %{REMOTE_USER} != ''
</RequireAny>
</RequireAll>
</RequireAny>
答案1
得分: 1
我认为问题出在<if>
部分是一个新的配置部分,所以对于htaccess
中其余部分的mod_authz_compat
的任何使用都会替代而不是合并这个模块的指令,包括satisfy
。
我个人建议清除所有mod_access_compat
指令,并在需要时使用带有表达式的require
,而不使用<if>
部分。<if>
会产生各种令人惊讶的效果,而将表达式作为指令的参数则更加直观。
但是,复制satisfy
可能已经足够了。
英文:
I think the issue here is that the <if>
section is a new config section, so any use of mod_authz_compat replaces, rather than merges, with the directives from this module in the rest of the htaccess, including the satisfy.
I'd personally purge all mod_access_compat directives and use require with expressions where needed, without <if>
sections. <if>
has all kinds of surprising effects whereas expressions as arguments to directives are much more intuitive.
But duplicating the satisfy may be enough.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论