web-dev-qa-db-ja.com

Apache 2プロキシ(mod_proxy)の背後にあるTomcat Webアプリケーションでリダイレクトを送信する

TomcatにWebアプリケーションがありますhttp://localhost:8080/WebApp/

私はApache 2(mod_proy)を構成して、ポートと名前を指定せずにlocalhostからWebアプリケーションに直接アクセスできるようにしました。例:http://localhost

<VirtualHost localhost:80>
    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/WebApp/
    ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>

Index.htmlはhttp://localhostで正しく表示されます。しかし、サーブレットがリダイレクトする場合:

@WebServlet(description = "...", urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet
{    
    @Override
    protected void doGet(HttpServletRequest request,
                     HttpServletResponse response) throws IOException
    {
        response.sendRedirect("a.html");
    }
 }

uRL http://localhost/loginを使用しています-http://localhost/WebApp/a.htmlにリダイレクトされます

http://localhost/a.htmlへの正しいリダイレクトを取得するにはどうすればよいですか?

15
Mahe

スチュアートとこのブログへのリンクのおかげで、解決策を見つけました: Apacheの背後にあるTomcat Webアプリケーションのリバースプロキシ

解決策:ProxyPreserveHostをオフにする必要があります!

理由:スイッチがオンになっている場合、プロキシバックエンドによって返される応答ヘッダーには、「localhost」またはポート番号(または80)のない実際のドメインが含まれます。そのため、ProxyPassReverseパターンは一致しません(ポートが異なるため、別のドメイン名が使用されている場合、ドメイン名も一致しません)。

構成:

<VirtualHost localhost:80>

   ProxyPreserveHost Off
   ProxyPass /  http://localhost:8080/WebApp/
   ProxyPassReverse / http://localhost:8080/WebApp/

</VirtualHost>

しかし、これはhttp経由でのみ機能し、ajp経由では機能しません(理由はわかりません)。それでもajpを使用したい場合は、次の回避策を使用できます-間違ったリダイレクトの後にApacheに別のリダイレクトを実行させます。

<VirtualHost localhost:80>

   ProxyPass /WebApp !
   ProxyPass /  ajp://localhost:8009/WebApp/
   ProxyPassReverse / ajp://localhost:8009/WebApp/

   RedirectMatch 301 ^/WebApp/(.*)$ /$1
   RedirectMatch 301 ^/WebApp$ /

</VirtualHost>

ProxyPass /WebApp !ディレクティブは、mod_proxyでの以降の処理からパスを除外するために必要です(リダイレクトディレクティブの前にプロキシディレクティブが評価されるため)

次に、RedirectMatchディレクティブは、/WebApp/...で始まるすべてのものを/WebAppで先頭に/WebAppのないURLにリダイレクトします。

唯一の欠点は、WebアプリケーションにWebAppという名前のサブフォルダーを含めてはならないことです

14
Mahe

私もこの問題を抱えていて、それに少し時間を費やしました。 Apache httpd構成を次のように変更すると、リダイレクトが機能すると信じています。

<VirtualHost localhost:80>
    ProxyPreserveHost On

    ProxyPass / http://localhost:8080/WebApp/
    ProxyPassReverse / http://localhost/WebApp/

    ProxyPassReverseCookiePath /WebApp /
</VirtualHost>

これは、Tomcat応答ヘッダーにプロキシヘッダーが含まれるためです(つまり、Locationヘッダーはhttp://localhost/WebApp のではなく http://localhost:8080/WebApp)ProxyPreserveHostがオンになっているためです。

脚注として:これは、webappsコンテキストを変更したい場合にも機能します。公開されているコンテキストを次のものを使用できるコンテキストに変更したいとします。

<VirtualHost localhost:80>
    ProxyPreserveHost On

    ProxyPass /context/ http://localhost:8080/WebApp/
    ProxyPassReverse /context/ http://localhost/WebApp/

    ProxyPassReverseCookiePath /WebApp /context
</VirtualHost>

参考までに、このブログ投稿が非常に役立つことがわかりました: Apacheの背後にあるTomcat Webアプリケーションの逆プロキシ

3
Stuart

リダイレクトの代わりに転送を使用

あなたの問題はsendRedirectの使用だと思います。 sendRedirectの呼び出しは、実際には、URLがリダイレクトされたことをブラウザーに示すことを前提としています。非表示にするには、転送を使用する必要があります。サーブレットでは、sendRedirectの代わりにこれを試してください。

String servletPath = request.getServletPath();
if(servletPath.equals("/app1")){
     ServletContext ctx = request.getServletContext().getContext("/app1");
     RequestDispatcher dispatcher=ctx.getServletContext().getRequestDispatcher( "/app1/app1.html" ); // or wherever you actually keep app1.html
     dispatcher.forward( request, response );
} 

Context.xml内でcrossContext = "true"を設定して、リクエストを他のWebアプリケーションに転送できるようにします。

<Context crossContext="true" ....../>
0
Usman Mutawakil

Apache2(ポート80で実行)要求をTomcat(ポート8080で実行されているアプリケーションサーバー)にリダイレクトしようとしたときに、同じ問題が発生しました。

これは完全に機能している設定です。

/etc/Apache2/sites-available/000-default.confに移動し、次の構成を追加します。

<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual Host. For the default virtual Host (this file) this
    # value is not decisive as it is used as a last resort Host regardless.
    # However, you must set it for any further virtual Host explicitly.
    #ServerName www.example.com

    # for redirecting the websocket requests
    ProxyPass /ws ws://localhost:7681/ 
    #ProxyPass  /ws ws://localhost:7681/

    ProxyPassReverse   /ws ws://localhost:7681/

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${Apache_LOG_DIR}/error.log
    CustomLog ${Apache_LOG_DIR}/access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual Host. For example the
    # following line enables the CGI configuration for this Host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf


# for redirecting the http request 
   ProxyPass /applicationContextUrl                         '  http://localhost:8080/applicationContextUrl

   ProxyPassReverse /applicationContextUrl         http://localhost:8080/applicationContextUrl

   ProxyPassReverseCookiePath /applicationContextUrl / 
   ProxyPassReverseCookieDomain localhost applicationContextUrl
   ProxyRequests off
   ProxyTimeout 15


   ErrorLog ${Apache_LOG_DIR}/nirad_error.log
   LogLevel debug
CustomLog ${Apache_LOG_DIR}/nirad_access.log combined
<Proxy *>
       AddDefaultCharset off
       Order deny,allow
       Allow from all
       #Require all denied
       Require all granted
       Require local

</Proxy>
</VirtualHost>

できました。端末に移動して、次のコマンドを実行します。

  1. Sudo a2enmod proxy_http(httpリダイレクト用)。
  2. Sudo a2enmod proxy_wstunnel(WebSocketリダイレクト用)
  3. およびSudo service Apache2 restart
  4. アプリケーションサーバーをポート8080で実行する
0
Manik Maurya

apache2とTomcatを接続するためにAJPコネクターを使用する必要があります。これは、このための完璧なソリューションになります。

これを構成する方法が必要な場合は、この詳細を説明します

0
Ramnath