具有身份验证的反向代理,具有http_auth_request_module与Apache

时间:2020-05-11 23:03:21

标签: php apache nginx reverse-proxy

我一直在研究服务器设置,当一起使用NGINX和Apache时,我发现似乎有些工作,但是我想知道是否可以仅使用Apache来完成相同的工作。我正在测试的基本设置如下图所示。可能有更好的方法,但这似乎在我的开发设置中有效。

Server Setup

有一个Apache服务器,该服务器运行具有用户帐户和登录方式的Web应用程序的前端。理想情况下,NGINX服务器后面的两个服务器将在本地主机上运行,​​这是我正在测试的两个独立端口,而NGINX服务器是这两个服务器的反向代理。

有一些URL提供给用户以获取受保护服务器上的资源。 Apache服务器应用程序创建了这些内容,但是内容由充当反向代理的NGINX服务器提供。我不想允许未登录的用户和未获得“授权”的用户利用该链接在NGINX服务器后面的两台服务器中的任何一台上获取内容。用户数据库位于MySQL / MariaDB中,当前由Apache服务器上的应用程序使用。

一种验证方式是将登录用户的session_id和某种类型的令牌附加到为用户创建的URL上。我的用户登录时,session_id已存储在数据库中,并且可以即时创建令牌。该URL还具有NGINX服务器后面两个服务器上资源的ID,并且有一种方法可以验证用户是否有权查看该资源,因此示例URL类似于:

https://www.example.org:3000/resourceid=xxx.xxx/token=xxxx/session=? (不确定是否都需要。

NGINX和OpenResty具有一个http_auth_request_module,它可以执行类似的操作,尽管它必须查询Apache服务器,或者至少查询数据库以检查是否应提供URL。因此,有两件事要检查:1)请求资源的用户必须通过传递的令牌来识别,并且必须登录。2)一旦确定了用户,就很容易检查如果他们有权通过对数据库执行查询来查看所请求的资源。因此,将令牌存储在数据库中以标识已登录的用户和/或令牌就足够了,并且还有另一个查询可以检查该特定用户是否有权查看该资源。

NGINX服务器的配置文件有点像这样。我是新手,因此可能会出现一些错误,但它适用于server1。现在,我还在NGINX服务器上的/之外提供内容,但是我也想为此设置反向代理。它既可以在Apache服务器上运行,也可以在NGINX服务器上运行,但是不必直接从Internet访问。现在的实际示例如下:

前端创建这样的链接,该链接实际上到达NGINX服务器,然后该链接查询Apache服务器以确定它是否有效(即,令牌以某种方式对应于已登录的用户,并且该用户已被授权查看该资源。

Auth脚本中有很多代码,但是基本上可以使用:

    error_log("proxy test");
    $headers = getallheaders();
    //DatabaseFactory::logVariable($headers);
    isset($headers['Referer'])?$referer = $headers['Referer']:$referer = false;
    $orig_uri = $headers['X-Original-Uri'];
    DatabaseFactory::logVariable($referer);
    DatabaseFactory::logVariable($orig_uri);
    . . . 
    ....

    returns a 200 status code if passed, error codes otherwise, e.g. 401;
    header("HTTP/1.1 200 OK");

这是一个示例链接,因此如果存在令牌,则auth脚本可以使用该令牌。

因此,如果某个随机访问者(例如黑客)试图获得访问权限,则auth机制会将其锁定的原因有两个,即使具有帐户和有效资源ID的用户试图使用该链接,只要令牌得到管理(例如,在用户登录时生成令牌,并在登录时销毁它们

),也会失败

http://localhost:3000/viewer/2.16.840.1.114151.3053898321150690137331984793170198063350200423?token=og46c1r9t6u7hfgec19n4536hu

server {
    root   html;
    listen      127.0.0.1:3000;  #(would be a different IP in production, on the internet)
    server_name  localhost;      #e.g. server1.example.org

    #charset koi8-r;

    #access_log  logs/host.access.log  main;
    location / {

        try_files $uri $uri/ /index.html?$args;
    }

    location  /server1/  {

        auth_request /auth;
        auth_request_set $auth_status $upstream_status;
        proxy_pass http://127.0.0.1:8042;  # 1 of the servers behind the NGINX server
        proxy_set_header HOST $host;
        proxy_set_header X-Real-IP $remote_addr;
        rewrite /server1/(.*) /$1 break;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Origin' '*';

    }


    location = /auth {  # authorization returned from the apache server

        internal;
        proxy_pass https://www.example.org/Proxy/auth;  #port 443
        proxy_pass_request_body on;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
    }


    # redirect server error pages to the static page /50x.html
    #

    error_page   401  /401.html;
    location = /401.html {
        root   html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

一个问题可能是,如果用户恰巧关闭浏览器而不注销,则该用户的令牌将过期。这里有一些建议:(关于SO,SO不允许问题中的.com链接?即使是SO?/ questions / 887919 / how-to-detect-if-a-user-has-logged-out -in-php

只是想知道:

  1. 上面说的有意义吗?
  2. 是否可以仅使用Apache服务器而不必使用NGINX来完成类似的事情? Apache可以用作反向代理,它具有auth模块,但我认为它们不像NGINX auth模块,主要是Basic Auth。

0 个答案:

没有答案