【问题标题】:Apache .htaccess redirect to HTTPS before asking for user authenticationApache .htaccess 在请求用户身份验证之前重定向到 HTTPS
【发布时间】:2012-05-03 06:30:28
【问题描述】:

这是我的 .htaccess:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

AuthUserFile /etc/hi
AuthName "hi"
AuthType Basic
require valid-user

它要求使用 http 进行用户身份验证,这意味着密码将以纯文本形式发送。它将重定向到 https 版本并再次询问密码。

我该如何解决?

【问题讨论】:

  • 您需要在单独的虚拟主机条目中声明 HTTP 和 HTTPS 站点,因此一个配置不会干扰另一个。完成后,重写规则应该在 http 1 中,auth 在 https 1 中(这一切都假设您仅通过 HTTPS 访问站点)。

标签: apache .htaccess


【解决方案1】:

如果您运行的是 Apache 2.4,则可以使用 configuration sections 轻松解决此问题。

例如...

# Redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

# Authenticate users only when using HTTPS
# Enable for <v2.4
 # SSLRequireSSL
 # ErrorDocument 403 /secure-folder/
# Enable for >v2.4
<If "%{HTTPS} == 'on'">
    AuthType Basic
    AuthName "Special things"
    AuthUserFile /etc/blah.htpasswd
    # Prevent this 'Require' directive from overriding any merged previously
   <IfVersion >= 2.4>
      AuthMerging And
   </IfVersion>
    Require valid-user
# Enable for >v2.4
</If>

【讨论】:

  • 绝对不要这样做。 由于指令合并顺序(&lt;If&gt; 最后合并),经过身份验证的用户将可以访问以前被阻止的任何文件或目录&lt;Directory&gt;&lt;File&gt;!例如,在普通服务器设置中,.htaccess 文件将被授予有效用户访问权限。
  • @Alek,我添加了一个“AuthMerging”指令,我相信它可以解决您提出的问题。因此,所有访问者仍被重定向到 HTTPS,但任何 HTTPS 请求都需要对访问者进行身份验证除了之前合并的 指令添加的现有限制。你怎么看?
  • 我没有测试这个设置,但从文档中看它似乎没问题,所以我不会相信你的话。
  • 可以有 = 2.4> 吗?我猜 SSLRequireSSL 也可以使用
【解决方案2】:

我是这样解决的。只允许非 SSL,因为它将被重定向,然后在 SSL 上要求身份验证一次...

SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

AuthUserFile /etc/hi
AuthName "hi"
AuthType Basic
require valid-user
Allow from env=IS_NON_SSL

【讨论】:

  • 优雅解决一个不完全明显的问题。我最终使用了Allow from env=!HTTPS,其中在 SSL 请求上设置了 HTTPS,但同样的概念也适用。谢谢。
  • 根据httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif的文档,SERVER_PORT 不是 SetEnvIf 指令中可用的选项
  • 另外,至少在我的情况下,它仍然要求身份验证两次。
  • @ChrisHeald 您可以发布您的解决方案作为答案吗?因为这里的这个对我不起作用。
【解决方案3】:

非常感谢您,Istador!

我的 Apache 是 2.2 版(Synology NAS DSM 5.1),所以这两个不能用:

RewriteOptions Inherit
IfVersion

取出它们(以及版本 >= 2.4 的部分)后。整个事情开始为我工作。

关于这个话题有很多建议,我花了两天时间尝试。

但只有这个对我有用。

这就是我所做的:

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

AuthType Basic
AuthName "private area"
AuthUserFile /path/to/file/.htdigest

Order Deny,Allow
Deny from all
Satisfy Any
Allow from env=!HTTPS
Require valid-user

因此它已被验证可在 Apache 2.2、Synology DSM 5.1 上运行。

【讨论】:

  • 请不要添加“谢谢”作为答案。一旦你有足够的reputation,你就可以vote up questions and answers你觉得有帮助。
  • 这很奇怪。根据 Apache 2.2 for mod_rewrite(适用于 Apache 1.3 及更高版本)和 mod_version(适用于 Apache 2.0.56 及更高版本)的文档,假设两个模块都已安装,则这两个指令都应该是有效的。
  • @Ilya。 “谢谢”很有帮助,因为帖子与他们的特定帖子相关,这有助于为像我这样的读者提供上下文。没有它,读者可能会认为它只是直接针对 OP 的帖子。当然,他们本可以更简洁地写一个“@Istador”!
  • 这似乎不适用于我拥有的基于 Debian 的 2.2 版本 - Allow from env=!HTTPS 似乎没有效果,导致所有页面都绕过身份验证步骤。
【解决方案4】:

检查的解决方案https://stackoverflow.com/a/15940387/2311074 确实适用于 Ubuntu 16.04 上的 Firefox,但它不适用于 Win 7 上的 Firefox。

如果你想保护你的文件夹https://yourdomain.com/securefolder 那么您需要在该文件夹中创建一个.htaccess,其内容如下:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

SSLRequireSSL
ErrorDocument 403 https://yourdomain.com/securefolder
AuthType Basic
AuthName "Admin"
AuthUserFile /outside/your/www/folder/.htpasswd
Require user admin Admin

它的工作方式是,当您通过http:// 而不是https:// 调用网站时,它会将您重定向到错误页面。诀窍是使用带有https:// 的正确链接作为默认错误页面。

【讨论】:

  • 这是唯一对我有用的,我用SSLRequireSSL ErrorDocument 403 https://%{HTTP_HOST} 但我有点担心。这是重定向的正确方法吗?我的意思是 403 不会以某种讨厌的方式影响谷歌吗?
【解决方案5】:

我正在运行 Apache 2.2,但上述解决方案均不适合我。我为我找到了解决方法here。基本上,您需要设置 SSLRequireSSL 并在 ErrorDocument 中使用一些脚本语言将用户转发到 HTTPS。不幸的是,在我的情况下,这仅在访问服务器上的特定文件时有效,如果仅提供域,则它不起作用。这是我所做的:

AuthType Basic
AuthName "Password Protected Area"
AuthUserFile /my/path/to/.htpasswd
#Require valid-user

<FilesMatch "(^(?!ssl.php).*)">
        SSLRequireSSL
        ErrorDocument 403 /ssl.php
        Require valid-user
</FilesMatch>

FileMatch 中的正则表达式告诉 apache 对除 ssl.php 之外的所有文件使用 SSLRequireSSL - 如果用户尝试在没有 SSL 的情况下访问,则将用户转发到 ssl.php。

我的 ssl.php 看起来像这样:

if(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == "" || $_SERVER['HTTPS'] == "off")
{
        $redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        header("HTTP/1.1 301 Moved Permanently");
        header("Location: $redirect");
        exit;
}

现在发生了什么:

最后一点是我不满意的,如果有人对此有解决方案,我会很高兴听到。我试图解决这个问题的事情:

  • 将正则表达式更改为 (^$)|(^(?!ssl.php).*) 以显式匹配空字符串。没用
  • 添加了重写规则以将空字符串重写到 index.php。也不行。

【讨论】:

    【解决方案6】:

    我们客户的 webapp 安装在他的 webuser 目录中。授权是在 mod_rewrite 规则 (https://serverfault.com/a/443185/253111) 之前处理的,我们无法得到接受的答案来工作,所以 mod_rewrite 似乎不是一个选项。

    最终我们明确要求使用 SSL,并通过 HTTPS 使用 webapp 的根作为 403 和 404 错误文档。因此,当一个人通过 HTTP(未经授权,因此是 403)或不存在的页面(404)访问任何页面时,他将被重定向到 ie。 https://DOMAIN.TLD/~WEBUSER/admin.

    这是在 cmets 中包含一些额外信息的 .htaccess 文件。

    ### INFO: Rewrites and redirects are handled after authorisation
    ### @link https://serverfault.com/a/443185/253111
    
    ### INFO: Log out of a HTPASSWD session
    ### This was not always possible, but Firefox and Chrome seem to end sessions
    ### when a new one is trying to be using ie.:
    ### https://logout:logout@DOMAIN.TLD/~WEBUSER/
    ### @link http://stackoverflow.com/a/1163884/328272
    
    ### FORCE SSL: Explicitly require the SSL certificate of a certain domain to
    ### disallow unsigned certificates, etc. ErrorDocument commands are used to
    ### redirect the user to an HTTPS URL.
    ### @link http://forum.powweb.com/showthread.php?t=61566
    SSLOptions +StrictRequire
    SSLRequireSSL
    SSLRequire  %{HTTP_HOST} eq "DOMAIN.TLD"
    
    ### HTPASSWD AUTHENTICATION
    AuthUserFile /var/www/vhosts/DOMAIN.TLD/web_users/WEBUSER/.htpasswd
    AuthType Basic
    AuthName "Hello"
    Require valid-user
    
    ### ERROR DOCUMENTS: Redirect user in case of a 403 / 404.
    ErrorDocument 403 https://DOMAIN.TLD/~WEBUSER/admin
    ErrorDocument 404 https://DOMAIN.TLD/~WEBUSER/admin
    

    【讨论】:

    【解决方案7】:

    这是在我的一种配置中起作用的唯一解决方案:

    RewriteEngine On
    RewriteCond %{SERVER_PORT} 80
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    <If "%{SERVER_PORT} != '80'">
        AuthUserFile /etc/hi
        AuthName "hi"
        AuthType Basic
        require valid-user
    </If>
    

    值得注意的是,这是针对我无法控制的 Apache 2.4(共享主机)。似乎%{HTTPS} 变量未在此配置中定义,任何基于SSLRequireSSL 的解决方案都会产生500 Internal Server Error。


    (旁注:如果您在处理 HTTP 请求时更喜欢 403 Forbidden 而不是 301 Permanent Redirect,请改用 RewriteRule ^(.*)$ - [F,L]

    【讨论】:

      【解决方案8】:

      Molumby 的解决方案适用于 2.4 及更高版本,但不适用于当前的 Debian 版本 2.2.22。

      Ben's / Chris Heald 的解决方案在 2.2.22 中也不适用于我,但这是由于不同的 order/satisfy 配置。这些设置在 2.4 中已更改,并且该解决方案似乎与 2.4 及更高版本不兼容(重定向有效,但浏览器只是显示未经授权的错误而无需提供凭据)。

      以下是适用于 2.4 以下和以上版本的两种解决方案的组合:

      RewriteEngine on
      RewriteOptions Inherit # rewrite rules from parent directories
      RewriteCond %{HTTPS} off
      RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
      
      AuthType Digest
      AuthName "private area"
      AuthDigestProvider file
      AuthUserFile /path/to/file/.htdigest
      
      <IfVersion < 2.4>
          Order Deny,Allow
          Deny from all
          Satisfy Any # reset this to 'All' in custom <Files> and <Directory> directives that block access
          Allow from env=!HTTPS
          Require valid-user
      </IfVersion>
      <IfVersion >= 2.4>
          <If "%{HTTPS} == 'on'">
              AuthMerging And
              Require valid-user
          </If>
      </IfVersion>
      

      要求:mod_rewrite、mod_auth、mod_digest、mod_version

      【讨论】:

      • 好主意,但它失败了(500 错误),因为即使使用
      • @LWC 1.) 编程语言不适合您的观点。反例:如果预处理器删除了无效部分,则可以编译无效的 C 代码。作为用户,我希望 IfVersion 在不评估其内容的情况下也能正常工作。 2.) 我在 2014 年 2 月至 2014 年 9 月期间使用 Apache 2.2.22 使用此配置。它可能无效并且可能导致错误日志条目(我没有检查),但它按预期工作并且没有响应 5xx 错误。 (也许它只是因为 Debian 版本才有效,有时与上游版本有所不同。)
      • 我猜不是全部,只是其中很多。感谢您的澄清!
      【解决方案9】:

      以上都不适合我,但确实如此。我唯一担心的是,如果在某些情况下不会触发身份验证,则允许某人在没有凭据的情况下访问。我不确定是否有,但也许你们聪明的人可能会说别的。

      此代码使用 .htaccess 文件夹身份验证将非 www 重定向到 www 并将 http 重定向到 https。

      这是您要保护的目录中的 htaccess 文件的内容:

      RewriteEngine on
      # ensure www.
      RewriteCond %{HTTP_HOST} !^www\. [NC]
      RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/foldername/$1 [L,R=301]
      # ensure https
      RewriteCond %{HTTP:X-Forwarded-Proto} !https
      RewriteCond %{HTTPS} !=on [NC]
      RewriteRule ^(.*)$ https://%{HTTP_HOST}/foldername/$1 [L,R=301]
      
      # Apache 2.4 If
      <If "%{HTTPS} == 'on' && %{HTTP_HOST} =~ /www/">
      AuthType Basic
      AuthName "Protected folder"
      AuthUserFile "/home/etc/.htpasswds/public_html/foldername/passwd"
      require valid-user
      </If>
      

      【讨论】:

      • 是的,只有一个对我有用,在需要有效用户之前,您需要检查 https 和 www 是否都打开。
      猜你喜欢
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多