代码之家  ›  专栏  ›  技术社区  ›  Matt

使用URL重写通过HTTPS进行HTTP身份验证

  •  7
  • Matt  · 技术社区  · 15 年前

    我正在努力保护 ~/public_html/dev 目录使用HTTPAUTHBASIC,但为了确保安全,我想通过SSL运行它。

    下面的中间部分 .htaccess 如果请求uri以 /dev 工作。

    文件的最后一部分也可以工作,但不能与HTTPS重定向一起正常工作。

    我基本上想打字 http://www.example.com/dev/some_sub_dir/ 并被重定向到 https://www.example.com/dev/some_sub_dir/ 并提示输入http-auth用户名和密码。

    现在发生的是如果我去 http://www.example.com/dev/some_sub_dir/ 我在端口80上得到了用户名和密码提示,然后在端口443上立即再次得到提示。所以我的凭证被发送了两次,一次是透明的,一次是加密的。使整个https URL重写有点毫无意义。

    这样做的原因是,我不会意外地通过HTTP提交我的用户/传递;HTTPS将始终用于访问 /DEV 目录。

    这个 HTAccess 是在 ~/public_html/dev 目录。

    # Rewrite Rules for example.com
    RewriteEngine On
    RewriteBase /
    
    # force /dev over https
    RewriteCond %{HTTPS} !on
    RewriteCond %{REQUEST_URI} ^/dev
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    
    # do auth
    AuthType Basic
    AuthName "dev"
    AuthUserFile /home/matt/public_html/dev/.htpasswd
    Require valid-user
    9 回复  |  直到 7 年前
        1
  •  10
  •   siliconrockstar    12 年前

    在进行基本身份验证之前,有一个相对流行的黑客强制使用HTTPS。我第一次在这里看到它:

    http://blog.jozjan.net/2008/02/htaccess-redirect-to-ssl-https-before.html

    它涉及使用自定义错误文档来处理HTTPS检查失败后发生的任何情况。

    例如,我有一个页面需要强制打开HTTPS,所以我在.htaccess文件中这样做:

    <FilesMatch "secure-page.php">
        SSLRequireSSL
        ErrorDocument 403 https://www.example.com/secure-page.php
        AuthType Basic
        AuthName "Secure Page"
        AuthUserFile /var/www/whatever/.htpasswdFile
        Require valid-user
    </FilesMatch>
    

    也就是说:

    如果请求的页面是“secure page.php”-如果不是https,则重定向到自定义的“错误页面”-“错误页面”实际上只是页面的https版本-在第二个请求中,由于https检查现在通过,请执行基本身份验证:)

    您可以将这个概念扩展到一个目录或其他用例-您的自定义“错误页”可以是一个重定向到正确的https URL的php页面,或者像上面链接中那样的cgi脚本…

        2
  •  4
  •   Jeff Davis    15 年前

    我遇到了同样的问题,最终找到了一个难看的解决方案,但它奏效了。将rewrite规则放入httpd.conf中的目录指令或conf.d文件之一(即“主”服务器配置中)。然后,将auth*和require行放入目录指令中 里面 这个 <VirtualHost _default_:443> ssl.conf中的容器(或定义ssl virtualhost的任何位置)。

    对我来说,这意味着创建一个文件 /etc/httpd/conf.d/test.conf 用:

    <Directory "/var/www/html/test">
            #
            # force HTTPS
            #
            RewriteEngine On
            RewriteCond %{HTTPS} off
            RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    </Directory>
    

    …然后在内部添加以下内容 /etc/httpd/conf.d/ssl.conf 就在上面 </VirtualHost> 标签:

    <Directory "/var/www/html/test">
            #
            # require authentication
            #
            AuthType Basic
            AuthName "Please Log In"
            AuthUserFile /var/www/auth/passwords
            Require valid-user
    </Directory>
    

    这样做使得Apache将rewriterule应用于所有请求,而auth要求仅适用于443虚拟主机中的请求。

        3
  •  4
  •   zx81    12 年前

    基于SiliconRockstar的答案,我添加了一个PHP脚本,它可以在您希望强制使用SSL的情况下工作。 全部的 这些文件,不仅仅是SiliconRockstar显示的一个文件案例。这里,它与htaccess文件一起工作。

    保护整个目录的htaccess:

        SSLRequireSSL
        ErrorDocument 403 /yourphp.php
        AuthType Basic
        AuthName "Secure Page"
        AuthUserFile /some_path_above_the_html_root/.htpasswdFile
        Require valid-user
    

    由htaccess调用的php(此示例htaccess中为php给定的路径是站点的根目录),这将强制在您调用的URL上使用https:

    <?php
    $path = "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    if ( $_SERVER['SERVER_PORT'] == 80) {
        header("Status: 302 Moved\n");
        header("Location: ".$path."\n\n");
    }
    else {
        header( "Content-type: text/html\n\n");
        echo "How did you get here???";
    }
    ?>
    

    如果您的站点没有SSL证书,则必须安装一个。如果这是您唯一的用途,您可以安装自签名证书。在CPanel VPS上,您的站点位于专用IP上,这需要一些时间:在WHM中,访问

    一个。生成SSL证书和签名请求

    然后

    二。在域上安装SSL证书

        4
  •  2
  •   Will    15 年前

    使用基本身份验证保护内容永远不会在HTTP上安全工作。

    一旦用户输入了他们的用户名和密码,它将不加密地发送给该站点的每个页面视图,而不仅仅是发送给用户提示的时间。

    您必须将HTTP上的请求视为未经身份验证,然后 全部的 通过https登录资料。

    很多网站使用https登录-使用表单和cookie,而不是基本身份验证-然后转到http。这意味着他们的“您已登录”cookie将以未加密的方式发送。每一个有价值的目标都因为这个被黑客攻击了,Gmail现在正在切换到完整的HTTPS,其他人也将跟随。

    您不具备与其他人相同的缩放问题,这些问题使它们远离计算成本更高的HTTPS。如果您的主页支持HTTPS访问,请在整个过程中使用它。

        5
  •  1
  •   Michael Schmidt Kishore    12 年前

    如果您将重写规则放在主配置中的任何或类似配置之外,那么将在身份验证之前完成重写。

    参见 Rewrite Tech

        6
  •  0
  •   Will    15 年前

    把您的身份验证部分放在 <Location> <LocationMatch> 使用协议作为术语标记?

        7
  •  0
  •   Ben    12 年前

    我是这样绕过它的。只允许非SSL,因为它将被重定向,然后需要在SSL上进行一次身份验证…

    SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL
    
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    
    AuthUserFile /.htpasswd
    AuthName "Enter your Username and Password:"
    AuthType Basic
    require valid-user
    Allow from env=IS_NON_SSL
    
        8
  •  0
  •   Craig Smith    11 年前

    我知道这是一个古老的问题,但是我在一个简单的ht.access重定向上遇到了困难。在其他许多问题和答案之后,我最终把这个htaccess组合在一起,它按预期工作。

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    
    AuthName "Private Server"
    AuthUserFile /var/www/.htpassword
    AuthType Basic
    require valid-user
    Order allow,deny
    Allow from env=!HTTPS
    Satisfy Any
    

    注意

    Order allow,deny
    

    这正是我所看到的许多其他答案所缺少的,因为它允许人们在使用HTTPS时直接进入。我的测试中缺少的另一部分是:

    Satisfy Any
    

    下面的代码片段允许非SSL客户端使用进行重定向。https env var是从mod_ssl为ssl客户机设置的。

    Allow from env=!HTTPS
    
        9
  •  0
  •   hunteke    7 年前

    我有两个问题的答案,一个是2010年的心态,另一个是2012年后的心态。

    要回答这个问题,就好像是2010年被问到的一样:使用两种不同的虚拟主机配置。

    这个解决方案有点超出了问题的范围,因为这意味着“我只能修改 .htaccess “但在许多情况下,一个可行的解决方案是请求管理员du jour简单地设置两个不同的虚拟主机配置。

    • 非ssl虚拟主机没有配置为访问文件系统上的任何内容,只返回301重定向到 https://... 所有请求的位置。

    • 然后,SSL侦听虚拟主机可以自由地实现基本身份验证,而无需担心标准HTTP侦听器会泄露产品。

    然而,我戴着2018年后的帽子,注意到这个问题是在Apache2.4(2012年初?)之前提出的。是时候更新了。引入Apache 2.4 <If condition> 检查,使这更容易和更直接:

    • 首先,不要对重写引擎进行模块化。由于Apache正在监听端口80和443(在标准设置中),并且我们希望强制使用SSL,因此如果重写模块以其他方式断开,我们希望服务器断开。

      RewriteEngine On 
      
    • 第二,简单地说,如果请求不安全,执行即时和永久的(301)重定向。注意r(edirect)和l(ast),它们共同工作以确保非加密请求被重定向,并且不能用于获得非认证访问。(对于OCD,非复制粘贴,请注意 缺乏 之间的间距 != on . 这是故意的。)

      RewriteCond %{HTTPS} !=on 
      RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,QSA,L,NC]
      
    • 最后,使用同一个变量 <If-condition> 检查以确保我们只需要TLS请求的密码。

      <If "%{HTTPS} == 'on'">
              AuthName "Password please!" 
              AuthType Basic 
              AuthUserFile /path/to/htpasswdfile
              AuthGroupFile /dev/null 
              require valid-user
      </If>
      

    总之:

    # .htaccess
    
    RewriteEngine On
    
    RewriteCond %{HTTPS} !=on
    RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,QSA,L,NC]
    
    <If "%{HTTPS} == 'on'">
            AuthName "Password please!"
            AuthType Basic
            AuthUserFile /path/to/htpasswdfile
            AuthGroupFile /dev/null
            require valid-user
    </If>