.htaccess条件中的环境变量未评估。

huangapple go评论69阅读模式
英文:

.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 --&gt; staging environment
  • foobar.com --&gt; 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 &lt;If&gt; conditions around the Allow/Require blocks those also work as expected
  • If I leave the &lt;If&gt; 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-.]*)(?&lt;!\.staging\.com)$ live_env=true
SetEnvIfNoCase Request_URI &quot;^/export&quot; export_folder=true
SetEnvIf Remote_Addr ^1\.2\.3\.4$ authorized_ip=true
SetEnvIf Remote_Addr &quot;^2\.3\.4\.[0-9]+$&quot; authorized_ip=true

AuthUserFile /home/foobar/public_html/.htpasswd
AuthName &quot;Password Protected&quot;
AuthType Basic

Order Deny,Allow
Satisfy any
Deny from all

&lt;If &quot;%{ENV:export_folder} == &#39;true&#39;&quot;&gt;
    Allow from env=authorized_ip
&lt;/If&gt;
&lt;If &quot;%{ENV:export_folder} != &#39;true&#39; &amp;&amp; %{ENV:live_env} == &#39;true&#39;&quot;&gt;
    Allow from env=live_env
&lt;/If&gt;
&lt;If &quot;%{ENV:staging_env} == &#39;true&#39;&quot;&gt;
    Require valid-user
    Allow from env=authorized_ip
&lt;/If&gt;

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-.]*)(?&lt;!\.staging\.com)$ environment=production
SetEnvIfNoCase Request_URI &quot;^/export&quot; export_folder=true
SetEnvIf Remote_Addr ^1\.2\.3\.4$ authorized_ip=true
SetEnvIf Remote_Addr &quot;^2\.3\.4\.[0-9]+$&quot; authorized_ip=true

AuthUserFile /home/foobar/public_html/.htpasswd
AuthName &quot;Password Protected&quot;
AuthType Basic

&lt;RequireAny&gt;
    &lt;RequireAll&gt;
        Require expr %{ENV:export_folder} == &#39;true&#39;
        Require expr %{ENV:authorized_ip} == &#39;true&#39;
    &lt;/RequireAll&gt;
    &lt;RequireAll&gt;
        Require expr %{ENV:export_folder} != &#39;true&#39;
        Require expr %{ENV:environment} == &#39;production&#39;
    &lt;/RequireAll&gt;
    &lt;RequireAll&gt;
        Require expr %{ENV:environment} == &#39;staging&#39;
        &lt;RequireAny&gt;
            Require expr %{ENV:authorized_ip} == &#39;true&#39;
            Require expr %{REMOTE_USER} != &#39;&#39;
        &lt;/RequireAny&gt;
    &lt;/RequireAll&gt;
&lt;/RequireAny&gt;

答案1

得分: 1

我认为问题出在&lt;if&gt;部分是一个新的配置部分,所以对于htaccess中其余部分的mod_authz_compat的任何使用都会替代而不是合并这个模块的指令,包括satisfy

我个人建议清除所有mod_access_compat指令,并在需要时使用带有表达式的require,而不使用&lt;if&gt;部分。&lt;if&gt;会产生各种令人惊讶的效果,而将表达式作为指令的参数则更加直观。

但是,复制satisfy可能已经足够了。

英文:

I think the issue here is that the &lt;if&gt; 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 &lt;if&gt; sections. &lt;if&gt; has all kinds of surprising effects whereas expressions as arguments to directives are much more intuitive.

But duplicating the satisfy may be enough.

huangapple
  • 本文由 发表于 2023年6月9日 03:00:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定