首页 文章

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

提问于
浏览
7

我试图使用http auth basic保护 ~/public_html/dev 目录,但为了使其安全,我想在ssl上运行它 .

如果请求URI以 /dev 开头并且有效,则以下 .htaccess 文件的中间部分将切换为https .

该文件的最后一部分也可以正常工作,但与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 回答

  • 10

    在进行基本身份验证之前,有一个相对流行的黑客强制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脚本...

  • 4

    我遇到了同样的问题,终于找到了一个丑陋的解决方案,但它确实有效 . 将重写规则放在httpd.conf中的Directory指令或其中一个conf.d文件中(即,在"Main"服务器配置中) . 然后,将Auth *和Require行放在ssl.conf中的 <VirtualHost _default_:443> 容器内的Directory指令中(或者定义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>
    

    ...然后在 </VirtualHost> 标签上方的 /etc/httpd/conf.d/ssl.conf 内添加以下内容:

    <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 VirtualHost中的请求 .

  • 0

    基于siliconrockstar的答案,我正在添加一个php脚本,该脚本适用于你想在文件上强制使用SSL的情况,而不仅仅是sirockstar显示的单文件情况 . 这里它再次与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提供的路径是您网站的根目录),它强制https在您调用的URL上:

    <?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证书,则必须安装一个 . 如果这是您的唯一用途,则可以安装自签名证书 . 在您的网站上使用专用IP的cPanel VPS上,需要花点时间:在WHM中,访问

    一 . 生成SSL证书和签名请求

    然后

    二 . 在域上安装SSL证书

  • 2

    使用基本身份验证保护内容永远不会通过HTTP安全地工作 .

    一旦用户输入了他们的用户名和密码,它就会以未加密的方式发送给该网站的每个页面视图 - 它不仅仅是发送用户被提示的时间 .

    您必须将HTTP上的请求视为未经过身份验证,并通过HTTPS执行所有登录 .

    许多网站都使用HTTPS进行登录 - 使用表单和cookie,而不是基本身份验证 - 之后再转到HTTP . 这意味着他们的“您已登录”cookie将以未加密的方式发送 . 由于这个原因,每个有 Value 的目标都被黑客入侵,而gmail现在正在切换到完整的HTTPS,其他人将会跟进 .

    您没有与其他人一样的扩展问题,这使他们远离计算上更昂贵的HTTPS . 如果您的主页支持HTTPS访问,请在整个过程中使用它 .

  • 0

    如果将重写规则放在主配置中,在任何或类似之外,重写将在验证之前完成 .

    Rewrite Tech

  • 1

    是否可以将您的身份验证部分放在 <Location><LocationMatch> 标记中协议作为术语?

  • 0

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

    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
    
  • 4

    我知道这是一个老问题,但我遇到了一个简单的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是从ssl客户端的mod_ssl设置的 .

    Allow from env=!HTTPS
    
  • 0

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

    要回答这个问题,就好像是2010年被问到的那样:使用两种不同的VirtualHost配置 .

    这个解决方案有点超出了问题的范围,因为暗示是“我只能访问修改 .htaccess !”但在许多情况下,一个可行的解决方案是请管理员简单地设置两个不同的VirtualHost配置 .

    • 非SSL VirtualHost未配置为访问文件系统上的任何内容,仅返回301重定向到所有请求的 https://... 位置 .

    • SSL侦听VirtualHost然后可以自由地实现基本身份验证,而无需担心标准HTTP侦听器将放弃货物 .

    然而,随着我在2018年后的问题,并注意到在Apache 2.4(2012年初?)之前问过这个问题,是时候进行更新了 . Apache 2.4引入了<If condition>检查,这使得这更容易,更直接:

    • 首先,不要IfModule RewriteEngine . 由于Apache正在侦听端口80和443(在标准设置中),并且我们希望强制执行SSL,因此如果Rewrite模块以其他方式脱离,我们希望服务器中断 .
    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>
    

相关问题