网站安全正则表达式处理程序?(PHP)

Mik*_*der 7 php mod-rewrite session redirect login

我工作的公司要求我带一个他们的网站,并使其成为另一个网站的子域.然后,他们让我将"登录/注销"会话控制从他们的主域扩展到他们的子域.

完成此操作后,我发现存在控制/管理问题.由于它们具有大量的单个页面,并且由于它们具有广泛的目录结构,因此它们太过涉及为每个页面添加PHP片段以根据登录状态重定向.

这是我的解决方案..请告诉我任何有助于我的问题或其他任何问题.

  1. 我将使用Mod_rewrite将subdomin上的每个请求重定向到特定页面(handler.php?requested_url =).
  2. 我将在他们的网站上制作一个"网站允许/禁止规则"部分.此部分将包含一个文本框,其中包含以下规则:

     +/weather/            ---> will allow anyone access to any url that contains "/weather/" somewhere within it, irregardless of logged-in status.
    
     -/weather/premium/    ---> will only allow access to a url that contains /weather/premium to logged-in users. 
    
    Run Code Online (Sandbox Code Playgroud)

    这将输出到存储在rules.php文件中的数组,如下所示:

    $ruleList = array(); 
    $ruleList[] = '+/weather/'; 
    $ruleList[] = '-/weather/premium/';
    
    Run Code Online (Sandbox Code Playgroud)
  3. handler.php中,如果用户已登录,我会将它们转发到requested.url.如果用户未登录,那么我将首先假设每个页面仅限于未登录的用户.handler.php将解析requested_url并根据rules.php进行检查,以查看是否设置了任何显式权限.然后,如果规则允许非登录访问,它会将用户转发到requested_url,否则它会将它们发送到登录页面.

我可以立即看到的一个问题是,如果Mod_rewrite规则将每个请求发送到handler.php,我该如何避免无限循环?

是否应该通过某种方法完成重定向header("Location: ")

编辑:这是我的斗争的更新:

在顶级域名(example.com)的.htaccess文件中,我添加了:

    #Prevent catching requests for the sub1 subdomain
    RewriteCond %{REQUEST_URI} ^sub1\.example\.com
    RewriteRule .* – [L]
Run Code Online (Sandbox Code Playgroud)

然后,在sub1.example.com子域的.htaccess中,我添加了以下内容:

    IndexIgnore *

    RewriteEngine On
    RewriteBase /path/to/base

    #Avoid infinite loop on outgoing requests
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{REQUEST_URI} !^$
    RewriteCond %{HTTP_REFERER} !^/?handler.php?$
    RewriteCond %{REQUEST_URI} !^/?handler.php?$



        #Check for cookie. Redirect to handler if not found.  (not yet implemented)                               
        #RewriteCond %{HTTP_COOKIE} !session_id
    RewriteRule (.*)$ handler.php?requested_url=$1 [NC,L,QSA]
Run Code Online (Sandbox Code Playgroud)

这是handler.php

    <?php

        $url = $_REQUEST['requested_url'];

        //Check list of permissions. For now just assume permitted.
        $permitted = true;
        if ($url == "") $url = "http://sub1.example.com";   
        if ($permitted)
            header("Location: ".$url);
        header("Location: http://sub1.example.com");        

    ?>
Run Code Online (Sandbox Code Playgroud)

我很亲密,我可以品尝它.不幸的是暂时我几乎到处都有"重定向循环".如果有人能给我一个正确方向的推动,我会很感激!

Kev*_*ray 2

我认为你的想法中有一个循环,因此应用程序中有一个循环。像这样:

  1. 用户代理请求子域中的旧资源。

  2. 由于 UA 必须具有有效的凭据,并且旧资源无法验证凭据,因此 UA 被重定向到处理程序。

  3. 处理程序验证凭据,并将 UA 重定向回旧资源。

  4. 转到2。

问题是所请求的资源无法区分步骤 1 和步骤 3 中 UA 的请求,因为这种区别是由 UA 的凭证定义的,而旧资源不会评估该凭证。

这种矛盾从另一个角度也很明显。想象一下,您解决了循环,并且 UA 被重定向到遗留资源——例如http://sub1.example.com/foo.php。对于要返回资源的服务器,这必须意味着未评估凭据(因为它不这样做),因此该资源实际上是公共的。

要解决这个问题,您必须通过更改步骤 2 或 3 的规则来打破僵局:

  • 要更改步骤 2,请将凭证评估添加到旧资源的响应中。前面的答案表明auto_prepend_file()是朝着这个方向发展的,但仅限于 PHP 遗留文件——图像、HTML 等不走运。

  • 要更改步骤 3,找到一种在 UA 不直接请求资源的情况下交付旧资源的方法。一种可能性是让处理程序从文件系统获取资源,并通过readfile()一些 HTTP 标头管理将其放在网络上。

也许这些的组合将为您带来好处:auto_prepend_file()将身份验证处理应用于旧版 PHP 和readfile()非 PHP 内容。