在请求用户身份验证之前,Apache .htaccess重定向到HTTPS

时间:2012-04-22 10:16:09

标签: apache .htaccess

这是我的.htaccess:

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

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

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

我该如何解决?

9 个答案:

答案 0 :(得分:15)

如果你正在运行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>

答案 1 :(得分:14)

我这样绕过它。只允许非SSL,因为它将被重定向,然后在SSL上需要auth一次...

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

答案 2 :(得分:9)

非常感谢,Istador!

我的Apache版本为2.2(Synology NAS DSM 5.1),所以这两个版本不适用于它:

RewriteOptions Inherit
IfVersion

将它们(以及版本&gt; = 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。

答案 3 :(得分: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://作为默认错误页面的正确链接。

答案 4 :(得分:2)

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

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

这是.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

答案 5 :(得分:1)

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

Ben的/ Chris Heald的解决方案在2.2.22中也没有为我工作,但这是由于不同的顺序/满足配置。这些设置已随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

答案 6 :(得分:1)

我正在运行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到SSLRequireSSL以获取除ssl.php之外的所有文件 - 并且如果用户尝试在没有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。也不起作用。

答案 7 :(得分:0)

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

此代码使用.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>

答案 8 :(得分:0)

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

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内部服务器错误。


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