使用Apache反向代理处理plack / PSGI应用程序的身份验证

时间:2013-07-17 08:45:57

标签: perl apache reverse-proxy plack psgi

这是我的情景:

Apache-reverse-proxy-starman

所以,

  1. 通过加密HTTPS的请求转到Apache,如:https://server1/MyPerlApp
  2. 如果用户未登录,则会重定向到某个登录页面(在server1中),而Apache不会将请求代理到Server2
  3. 当用户登录时 - 经过身份验证 - 然后Apache会将所有来到https://server1/MyPerlApp的请求转发到http://server2:5000
  4. 问题1:这可能吗? (问,因为我不太了解Apache,这并不简单:

    ProxyPass /MyPerlApp http://server2:5000/
    

    因为我需要在server1上验证用户身份并设置ProxyPass仅在验证时。 由于Apache非常灵活,我认为上面的答案是肯定的(但确认和细节非常受欢迎) - 所以这是我的主要具体问题:

    • 我的Plack应用程序如何知道在Apache级别验证哪些用户在第一台服务器上)?
    • 某些用户信息传递到服务器2上的perl应用的简单方法是什么? 例如与Apache mod_rewrite为每个查询添加user=username参数,
    • Apache可以设置我的perl应用应该读取的一些HTTP标头吗?
    • 有一种简单而又重新开始的方式吗?

    我正在寻找如何避免我的starman / perl应用程序中的身份验证例程,因为:

    • 用户无论如何都需要登录server1(针对其工作流程中的其他任务)
    • 如果他已经登录,则不需要在我的应用程序中进行身份验证(避免不必要的双重登录)
    • 但我仍然需要知道哪些用户已登录(通过server1上的Apache)

    已经有类似的问题,但是:

2 个答案:

答案 0 :(得分:9)

[我想你在这里问了四个问题。其中一些重叠。我将尝试尽可能多地回答,然后编辑您的问题以使其更清晰一些。发布您当前的Apache httpd.conf可能会有所帮助,这样人们就可以看到您当前如何处理访问和身份验证。这样,您可以获得有关如何将代理应用程序与Apache实例集成的更好建议。]

设置可以处理"网站单点登录的前端"需要一些规划和配置,但值得付出努力。为了使这更容易,您将要使用Apache-2.4。你可能正在使用这个版本,但Apache已成为一种主力,因此有些网站比过去更频繁地更新它。 Apache 2.4包含mod_sessionmod_auth_form,可以设置基于表单的" Web门户单点登录"用于具有多个后端应用程序服务器(通常在不同的机器端口或套接字上运行)的站点的Apache的各种工具组合在一个面向外部的URL / URI集合下。这种使用模式在Apache中非常普遍,2.4版本增加了一些功能,使其更容易实现。

你问过关于"容易推荐的"做你所描述的方式。那么,你走在正确的轨道上。 Apache的httpd对于这种身份验证/授权和用户登录"非常有用。一种应用程序 - 以至于它成为你想要做的事情的主要工具。

您问如何提供用户信息"到后端服务器。您可以像在任何Web应用程序中处理状态一样执行此操作:使用会话和cookie。会话信息包含编码为application/x-www-form-urlencoded字符串的键/值对。您还可以创建后端应用程序可以读取的HTTP_SESSION环境值。如果你想在那里使用它们,你的Plack / Starman应用程序必须能够处理会话和cookie(即它必须是#34;会话感知")。请查看Plack::Middleware::Session有关如何处理此问题的建议。

当然,使用mod_auth_form设置身份验证比Basic身份验证更复杂。但是使用基于表单的登录可以使用javascript(明智地),客户端应用程序可以在本地存储表单信息以便快速登录;同样,表单是灵活的,可以收集更多数据并将更多信息传递给用户,Apache可以处理一些复杂性(身份验证后重定向)。由于它们只是一个HTML <form>,因此您可以简单地开始,并在网站增长时使其更加精细。也就是说,您可以让Apache Reverse Proxy为您的后端提供Basic Auth

如果没有看到有关您的安装的更多详细信息,我无法说明您可能需要mod_rewrite 本身的方式/原因,但Rewrite指令可以很好地与{ {1}}。当然,在您的网站中,您需要检查身份验证和会话信息,并在必要时将用户重定向到登录表单。使用ProxyPass使得更容易实现,但代价是更复杂的配置。至于反向搜索本身,您可以通过正常方式使用mod_auth_form将请求传递到后端:

ProxyPass

然后,您需要配置或调整当前的Apache系统以获得ProxyPass /app http://[starmanhost]:3000/ 并要求以标准Apache方式对相关URL进行身份验证(除非整个Session On需要身份验证):

/

等。正如Apache文档指出的那样(并且您希望阅读mod_sessionmod_proxy等),您可以传递会话信息以供后端应用程序使用。

  

如果<Location /app> AuthType Basic Session On SessionCookieName session path=/ ... require valid-user </Location> 指令用于定义HTTP请求   标题,会话,编码为application / x-www-form-urlencoded   字符串,将提供给应用程序。

     

对于隐私/安全,您可以使用mod_session和SSL(如果可能)。正如您所注意到的那样,您不需要加密就可以“#end; end to end&#34; (即,从客户端到反向代理和后端应用程序之间的面向外部的前端的HTTPS)但是如果外部连接是mod_session_crypto并且您在服务器上保留会话信息(使用{ {3}}作为另一个响应,使用加密存储,您可以避免在服务器之间共享用户会话信息时固有的明显威胁。最好的部分是您可以逐个添加这些层,而无需广泛修改后端应用程序。这是创建一个坚实的WebSSO服务器&#34;前端处理登录。

请注意,我在这里使用过WebSSO一词有点松散。严格地说,WebSSO(和SSO)具有更广泛和更具包容性的概念,具有自己的标准轨道和技术(有一些Apache项目专注于此)。这就是为什么我倾向于称你正在尝试的方法&#34;网站SSO&#34;。支持广泛的身份验证,编程语言模块,代理和重写使Apache的https://瑞士军刀/胶带&#34;瑞士军刀/胶带&#34;以这种方式处理登录和会话的选择。

这样做的理由是合理的,因为您可以避免额外的登录和混淆用户(及其浏览器)。同样,通过将身份验证步骤与应用程序分离并将该任务专用于Apache,您可以使开发人员更轻松地编写后端应用程序。你的问题很普遍。我认为您可以开始尝试一些开始出现在这里的建议,如果遇到问题,您可以跟进针对您的实施的更具体的问题。

首先使Apache位正常工作(httpd; Session OnProxyPass)并确保正确的信息由前端创建,存储和传递。这对于未来的许多事情都非常有用。 Apache大师可以在这里提供帮助。将正确的会话信息传递到后端后,您可以使用<Location /app>starman在perl代码中提出有关如何访问和使用它的问题。工具和文档中可能存在缺失或粗略的位,但许多网站希望执行您所描述的内容,因此这些内容将会出现并继续改进。祝你好运。

<强>参考

答案 1 :(得分:2)

Apache的mod_session看起来是你缺少的组件。由于代理是后端应用程序的网关,因此它可以处理HTTP层上的身份验证,并根据需要使用代理条目将会话传回Perl脚本。
将用户信息公开给Perl应用程序可以通过几种方式实现。

mod_session_dbd - 是一个在数据库中存储会话信息的模块。然后可以与托管Perl应用程序的后端服务器共享。

mod_session_cookie - 是一个将会话信息存储在客户端浏览器中的cookie的模块。会话变量将存储在cookie中,Perl应用程序将检索它们。

但是,cookie或在URL中放置会话变量会引发安全问题。 Cookie和标题可以修改。

mod_proxy应该以html格式将会话变量传递回应用程序。

http://httpd.apache.org/docs/trunk/mod/mod_session.html