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

时间:2012-09-21 23:49:26

标签: apache tomcat grails spring-security apache2

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

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

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

2 个答案:

答案 0 :(得分:2)

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

下面的代码假设Grails服务器上有一些由Spring Security保护的URL,该页面上唯一的内容是“允许”工作。我使用了网址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。它假定会话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>

答案 1 :(得分:0)

他们必须分享一个会话。这需要相当多的时间,因为它们没有任何共同之处。您必须编写Java代码以与Apache HTTPD在其会话中使用的内容兼容。