是否可以只允许 Apache HTTPd 静态资源访问在 Tomcat 中经过身份验证的客户端?

Posted

技术标签:

【中文标题】是否可以只允许 Apache HTTPd 静态资源访问在 Tomcat 中经过身份验证的客户端?【英文标题】:Is it possible to only allow Apache HTTPd static resources access to clients authenticated in Tomcat? 【发布时间】:2012-09-14 09:45:19 【问题描述】:

我有一个 Grails 应用程序,使用 spring-security 插件,部署在 Tomcat 上,前面有 Apache Httpd 服务器。 我想在 httpd 服务器上部署一些执行一些文件操作的 php 脚本。这似乎很容易,但是我想知道是否可以限制对这些脚本的访问,以便只有在我的 Grails 应用程序中经过身份验证的客户端才能执行它们?

我只想限制对脚本的访问,但另一方面,出于性能原因,我不想将它们移至 Groovy/Java [我不想为这些任务浪费 Tomcat 时间]。

编辑: php 脚本会生成一个文件 [最大 1MB],然后将其传输到客户端。 我读过this 并考虑过这个从tomcat 到httpd 的反向代理,但是我担心它会对Tomcat 产生影响。

【问题讨论】:

【参考方案1】:

你可以用一点 mod_perl 做到这一点。下面是一个示例解决方案,需要稍作调整,使其仅捕获您想要保护的 URL,而忽略其他所有内容。

下面的代码假定 Grails 服务器上的某个 URL 由 Spring Security 保护,并且该页面上唯一的内容是“允许”工作。我使用了网址http://mywebapp.com/some-secured-page.jsp。

mod_perl 代码,在一个名为 MyModPerlFilter.pm 的文件中是这样的:

package MyModPerlFilter;

use strict;
use Apache2::RequestRec;
use Apache2::Connection;
use APR::Table;
use LWP::Simple;

use base qw(Apache2::Filter);

use Apache2::Const -compile => qw(REDIRECT DECLINED M_GET);

use constant BUFF_LEN => 1024;

sub handler : FilterRequestHandler 
    my $r = shift;

    # check only GET requests for /*.php, ignore everything else
    if ($r->uri() =~ m|/.*\.php$| && $r->method_number == Apache2::Const::M_GET) 

        # grab Tomcat session ID from request
        my $jsessionid = $r->headers_in->Cookie =~ /JESSIONID=([^;\s]+)/ && $1;

        # fetch secure page with the Tomcat session ID
        my $res = get("http://mywebapp.com/some-secured-page.jsp;jsessionid=$jsessionid");

        # any response other than the word "ALLOWED" redirect to login form
        if ($res ne 'ALLOWED') 
            $r->headers_out->set("Location", "http://mywebapp.com/login.jsp");
            return Apache2::Const::REDIRECT;
        
    

    return Apache2::Const::DECLINED;


1;

如果请求是对匹配“/*.php”的 URL 的 GET,它将直接调用 Grails 服务器上的安全页面并验证它是否返回文本“ALLOWED”。如果对 Grails 页面的调用没有,则表示用户未通过身份验证并将其重定向到 Spring Security 登录页面。

唯一棘手的部分是从请求中获取会话 ID,并在您调用安全检查 URL 时将其包括在内。它假定会话 ID 存储在 cookie JSESSIONID 中,并且您的 Tomcat 设置为允许在 URL 中传递会话 ID。

Apache 设置需要安装 mod_perl,并且配置与此类似。

# location of the mod_perl handler (or use the default locations)
PerlSwitches -I/usr/local/somewhere

<VirtualHost *:80>
    ...

    SetHandler modperl
    PerlMapToStorageHandler MyModPerlFilter

    ...

    # any proxy related stuff here
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

【讨论】:

哇...我印象深刻。这看起来是一个很好的解决方案,并且似乎与它所获得的任何请求相比并不涉及 tomcat。非常感谢!【参考方案2】:

他们必须共享一个会话。这需要相当多的工作,因为它们没有共同点。您必须编写 Java 代码才能与 Apache HTTPD 在其会话中使用的内容兼容。

【讨论】:

以上是关于是否可以只允许 Apache HTTPd 静态资源访问在 Tomcat 中经过身份验证的客户端?的主要内容,如果未能解决你的问题,请参考以下文章

Apache(httpd)配置--日志控制与静态元素过期时间配置

85.Apache(httpd)配置--日志控制与静态元素过期时间配置

centos8设置httpd只允许https访问

各种服务器伪静态配置方法

nginx/httpd + tomcat及负载均衡tomcat

如何验证apache 允许OPTIONS方法