简体   繁体   English

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

[英]Handling authentication with Apache reverse proxy for plack/PSGI app

This is my scenario:这是我的场景:

Apache-反向代理-starman

So,所以,

  1. Requests via encrypted HTTPS go to Apache like: https://server1/MyPerlApp通过加密 HTTPS 的请求转到 Apache,如: https://server1/MyPerlApp
  2. If the user is not logged in, they get a redirect to some login page (in the server1), and Apache doesn't proxy the request to Server2如果用户没有登录,他们会重定向到某个登录页面(在 server1 中),并且 Apache 不会将请求代理到 Server2
  3. When the user logged in - IS authenticated - then Apache forwards all requests that are coming to https://server1/MyPerlApp to http://server2:5000当用户登录 - 经过身份验证 - 然后 Apache 将所有到达https://server1/MyPerlApp请求转发到http://server2:5000

Question1: Is this possible?问题1:这可能吗? (Asking, because I don't know Apache enough deeply, and this is not an simple: (问,因为我对Apache的了解不够深入,这不是一个简单的:

ProxyPass /MyPerlApp http://server2:5000/

because I need need authenticate the user at server1 and set ProxyPass Only if authenticated.因为我需要在 server1 上对用户进行身份验证,并在经过身份验证时设置ProxyPass Only。 Since Apache is quite flexible I assume the answer is yes for the above (but confirmation and details is very welcomed ) - so here are my main specific questions:由于 Apache 非常灵活,我认为上述答案是肯定的(但非常欢迎确认和详细信息) - 所以这里是我的主要具体问题:

  • How will my Plack application know what user is authenticated at the Apache level ( ie on the 1st server)?我的 Plack 应用程序如何知道哪些用户在 Apache 级别(在第一台服务器上)进行了身份验证?
  • what is an easy way to deliver some of the user info to the perl app on the server2?一些用户信息传送到 server2 上的perl应用程序的简单方法是什么? eg with Apache's mod_rewrite what appends an user=username parameter to each query,例如,使用 Apache 的mod_rewriteuser=username参数附加到每个查询中,
  • can Apache can set some HTTP headers that my perl app should read? Apache 可以设置一些我的perl应用程序应该读取的 HTTP 标头吗?
  • is there an easy and recommenced way?有没有简单又推荐的方法?

I'm looking for how to avoid authentication routines in my starman/perl app, maily because:我正在寻找如何在我的 starman/perl 应用程序中避免身份验证例程,因为:

  • the user need to log into server1 anyway (for other tasks in his workflow)用户无论如何都需要登录 server1(对于他的工作流程中的其他任务)
  • if he is already logged in, authentication in my app is not needed (avoid unnecessary double login)如果他已经登录,则不需要在我的应用程序中进行身份验证(避免不必要的双重登录)
  • but I still need to know which users are logged in (via Apache at server1)但我仍然需要知道哪些用户已登录(通过 server1 上的 Apache)

There is already similar questions, but:已经有类似的问题,但是:

[I think you asked four questions here. [我想你在这里问了四个问题。 Some of them overlap.其中一些重叠。 I will try to answer as many as I can, then edit your question to make it a bit clearer.我会尽可能多地回答,然后编辑您的问题以使其更清楚一些。 It might be helpful to post your current Apache httpd.conf so people can see how you are handling access and authentication currently.发布您当前的 Apache httpd.conf可能会有所帮助,以便人们可以了解您当前如何处理访问和身份验证。 That way you might get better suggestions on how to integrate the proxied application(s) with your Apache instance.]这样,您可能会获得关于如何将代理应用程序与您的 Apache 实例集成的更好建议。]

Setting up a front-end that can handle "Web Site Single Sign On" requires some planning and configuration but it is worth the effort .设置可以处理“网站单点登录”的前端需要一些规划和配置,但值得付出努力 To make this easier, you'll want to use Apache-2.4.为了使这更容易,您需要使用 Apache-2.4。 You probably are using this version, but Apache has become something of a workhorse, such that some sites update it much less frequently than in the past.您可能正在使用这个版本,但 Apache 已经成为一种主力,因此某些站点更新它的频率比过去低得多。 Apache 2.4 includes mod_session and mod_auth_form which make it possible to set up form-based "web portal Single Sign On" sorts of tools with Apache for sites with multiple back-end application servers (often running on separate machine ports or sockets) combined under one outward facing set of URL/URIs. Apache 2.4 包括mod_sessionmod_auth_form ,这使得使用 Apache 为具有多个后端应用程序服务器(通常在不同的机器端口或套接字上运行)的站点设置基于表单的“Web 门户单点登录”工具成为可能。外向的一组 URL/URI。 This pattern of use was so widespread with Apache that the 2.4 release added features to make it easier to do.这种使用模式在 Apache 中非常普遍,以至于 2.4 版本添加了一些功能以使其更容易实现。

You asked about an "easy recommended" way to do what you have described.您询问了一种“简单推荐”的方法来执行您所描述的操作。 Well, you are on the right track.好吧,你是在正确的轨道上。 Apache's httpd is really useful for this kind of authentication/authorization and "user login" sort of application - so much so that it's become a staple tool for what you are trying to do. Apache 的httpd对于这种身份验证/授权和“用户登录”类应用程序非常有用 - 以至于它已成为您尝试执行的操作的主要工具。

You asked how to "deliver the user information" to the back-end server.您询问了如何将用户信息“传递给后端服务器”。 You do that in the same way you handle state in any web application: with sessions and cookies.您可以通过与在任何 Web 应用程序中处理状态相同的方式来执行此操作:使用会话和 cookie。 Session information contains key/value pairs encoded as an application/x-www-form-urlencoded string.会话信息包含编码为application/x-www-form-urlencoded字符串的键/值对。 You can also create an HTTP_SESSION environment value that you back-end application can read from.您还可以创建后端应用程序可以读取的HTTP_SESSION环境值。 Your Plack/Starman application has to be able to handle sessions and cookies (ie it has to be "session aware") if you want to use them there of course.如果您想在那里使用它们,您的 Plack/Starman 应用程序必须能够处理会话和 cookie(即它必须是“会话感知”)。 Look at Plack::Middleware::Session for ideas on how to approach this.查看Plack::Middleware::Session以获取有关如何处理此问题的想法。

For sure, setting up authentication with mod_auth_form is more complicated than Basic authentication.当然,使用mod_auth_form设置身份验证比Basic身份验证更复杂。 But with form based logins javascript can be used (judiciously), client applications can store form information locally for quick logins;但是可以使用基于表单的登录 javascript(明智地),客户端应用程序可以在本地存储表单信息以便快速登录; as well, forms are flexible and can gather more data and pass more information to the user and some of the complexity (redirection after authentication) can be handled by Apache.同样,表单很灵活,可以收集更多数据并向用户传递更多信息,并且某些复杂性(身份验证后的重定向)可以由 Apache 处理。 Since they are just an HTML <form> , you can start simply and make them more elaborate as your site grows.由于它们只是一个 HTML <form> ,您可以简单地开始,并随着您的站点的增长而使它们更加精细。 That said you can have an Apache Reverse Proxy simply provide Basic Auth for your back-end.也就是说,您可以拥有一个 Apache 反向代理,只需为您的后端提供Basic Auth身份Basic Auth

Without seeing more details about your installation I can't say how/why you might need mod_rewrite per se , but Rewrite directives can play nicely with ProxyPass .没有看到有关您的安装的更多详细信息,我无法说明您本身如何/为什么需要mod_rewrite ,但是Rewrite指令可以很好地与ProxyPass Of course throughout your site you'd want to check for authentication and session information and redirect users to a login form where/when necessary.当然,您希望在整个站点中检查身份验证和会话信息,并在必要时将用户重定向到登录表单。 Using mod_auth_form makes this easier to implement at the cost of a somewhat more complicated configuration.使用mod_auth_form使这更容易实现,但代价是配置更复杂。 As for the reverse prosy itself, you'd use ProxyPass in the normal way to pass requests to your back end:至于反向prosy本身,您将以正常方式使用ProxyPass将请求传递到您的后端:

ProxyPass /app http://[starmanhost]:3000/

Then you need configure or tweak your current Apache system to have Session On and require authentication for the URLs in question (unless the entire / requires authentication) in the standard Apache way:然后,您需要配置或调整当前的 Apache 系统以启用Session On并要求以标准 Apache 方式对相关 URL 进行身份验证(除非整个/需要身份验证):

<Location /app>
 AuthType Basic
 Session On
 SessionCookieName session path=/
 ...
 require valid-user
</Location>

etc. As the Apache docs point out (and you'll want to read mod_session , mod_proxy among others), you can pass session information around for use by back-end applications.等等。正如 Apache 文档指出的那样(并且您需要阅读mod_sessionmod_proxy等),您可以传递会话信息以供后端应用程序使用。

If the SessionHeader directive is used to define an HTTP request header, the session, encoded as a application/x-www-form-urlencoded string, will be made available to the application.如果SessionHeader指令用于定义 HTTP 请求标头,则编码为 application/x-www-form-urlencoded 字符串的会话将可供应用程序使用。

For privacy/security you'll want to use mod_session_crypto and SSL if that's possible.如果可能,出于隐私/安全考虑,您将希望使用mod_session_crypto和 SSL。 As you note you will not need encryption to be "end to end" (ie HTTPS from client to outward facing front-end and between the reverse proxy and back-end applications) but if outside connections are https:// and you keep session information on the server (usingmod_session_dbd as another response noted) using encrypted storage, you can avoid obvious threats inherent in sharing user session information across servers.正如您所注意到的,您不需要“端到端”加密(即从客户端到向外的前端以及反向代理和后端应用程序之间的 HTTPS),但如果外部连接是https://并且您保持会话服务器上的信息(使用mod_session_dbd作为另一个响应指出)使用加密存储,您可以避免在跨服务器共享用户会话信息时固有的明显威胁。 The best part of this is you can add these layers one by one without having to modify your back-end applications extensively.最好的部分是您可以一层一层地添加这些层,而无需大量修改后端应用程序。 This is the advantage of creating a solid "WebSSO server" front-end to handle logins.这是创建可靠的“WebSSO 服务器”前端来处理登录的优势。

Note that I've been using the term WebSSO here a bit loosely.请注意,我在这里使用了术语 WebSSO 有点松散。 Strictly speaking, WebSSO (and SSO) are much broader and more encompassing concepts with their own standards tracks and technologies (there are a couple Apache projects focused on this).严格来说,WebSSO(和 SSO)是更广泛、更包含自己的标准轨道和技术的概念(有几个 Apache 项目专注于此)。 This is why I tend to call the approach you are trying "Web Site SSO".这就是为什么我倾向于将您正在尝试的方法称为“网站 SSO”。 Support for a wide range of authentication, programming language modules, proxying, and rewriting makes Apache's httpd the "swiss army knife/duct tape" of choice for handling logins and sessions in this way.对广泛的身份验证、编程语言模块、代理和重写的支持使 Apache 的httpd成为以这种方式处理登录和会话的“瑞士军刀/胶带”。

Your rational for doing this is sound, since you can avoid extra logins and confusing users (and their browsers).您这样做的理由是合理的,因为您可以避免额外登录和混淆用户(及其浏览器)。 As well, by decoupling the authentication steps from your application and dedicating that task to Apache, you make it easier for developers to write back-end applications.同样,通过将身份验证步骤与您的应用程序分离并将该任务专用于 Apache,您可以让开发人员更轻松地编写后端应用程序。 Your question is very general though.不过你的问题很笼统。 I think you can start to try out some of the suggestions that begin to appear here and if you run into problems you can follow up with more specific questions focused on your implementation.我认为您可以开始尝试这里开始出现的一些建议,如果您遇到问题,您可以针对您的实施提出更具体的问题。

Get the Apache bits working correctly first ( Session On ; ProxyPass , <Location /app> ) and make sure the right information is getting created, stored and passed on by the front-end.首先让 Apache 位正常工作( Session On ; ProxyPass , <Location /app> )并确保前端创建、存储和传递正确的信息。 This will be very useful for lots of things going forward.这对未来的很多事情都非常有用。 Apache gurus can help here. Apache 大师可以在这里提供帮助。 Once you have the proper session information being passed to your back-end you can ask questions about how to access and use it in in your perl code with starman and plack .将正确的会话信息传递给后端后,您可以询问有关如何使用starmanplack在 perl 代码中访问和使用它的plack There may be missing or rough bits in tools and documentation but lots of sites want to do what you have described so these things will appear and continue to improve.工具和文档中可能存在缺失或粗糙的部分,但许多站点都希望按照您的描述进行操作,以便这些内容会出现并继续改进。 Good luck.祝你好运。

References参考

Apache's mod_session looks to be the component you are missing. Apache 的 mod_session 看起来是您缺少的组件。 Since the proxy is the gateway to the applications in the back-end, it can handle the authentication on the HTTP layer and pass back sessions as needed to the Perl script using the proxy entry.由于代理是后端应用程序的网关,它可以处理 HTTP 层上的身份验证,并根据需要使用代理条目将会话传回 Perl 脚本。
Exposing the user information to the Perl application can happen in a few ways.可以通过几种方式向 Perl 应用程序公开用户信息。

mod_session_dbd - is a module to store session information in a database. mod_session_dbd - 是一个在数据库中存储会话信息的模块。 This could then be shared with the back-end server hosting the Perl application.然后,这可以与托管 Perl 应用程序的后端服务器共享。

mod_session_cookie - is a module to store session information in a cookie on the browser of the client. mod_session_cookie - 是将会话信息存储在客户端浏览器上的 cookie 中的模块。 Session variables would be stored in the cookie and the Perl application would retrieve them.会话变量将存储在 cookie 中,Perl 应用程序将检索它们。

But, cookies or putting session variables in the URL open up security concerns.但是,cookie 或在 URL 中放置会话变量会带来安全问题。 Cookies and headers can be modified.可以修改 Cookie 和标头。

mod_proxy should pass the session variables back to the applications in the form html. mod_proxy 应该以 html 的形式将会话变量传递回应用程序。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM