Как ограничить доступ по IP к определенным динамическим URL-адресам (всего 1-2 страницы) в формате tomcat или url-pattern - PullRequest
0 голосов
/ 12 ноября 2018

Пожалуйста, не закрывайте этот вопрос как ответ, потому что все ссылки, которые я нашел, например this , и они о том, как заблокировать один статический URL, но не динамический.

У меня есть Tomcat 7, и у меня есть приложение, похожее на http://server/myapp/. Мне нужно ограничить некоторые страницы внутри этого приложения для некоторых IP-адресов. например, все должно работать нормально для всех IP-адресов, кроме этих 2 страниц

http://server/myapp/admin/appversion/index.jsp http://server/myapp/admin/appversion/app_parameters.jsp

для статических URL работает отлично, если я добавляю фильтр в файл web.xml сервера (... \ apache-tomcat-7 \ conf \ web.xml) следующим образом

<filter>
    <filter-name>IPFilter</filter-name>
    <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class>
    <init-param>
        <param-name>allow</param-name>
        <param-value>127\.\d+\.\d+\.\d+</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>IPFilter</filter-name>
    <url-pattern>/admin/appversion/index.jsp</url-pattern>
    <url-pattern>/admin/appversion/app_parameters.jsp</url-pattern>
</filter-mapping>

Проблема возникает, когда мне нужно выполнить динамическую (или регулярную выражение) фильтрацию. Например, каждый раз, когда у меня появляется новая версия приложения, эта часть URL (appversion) изменяется.

/ админ / AppVersion / app_parameters.jsp

реальный URL сегодня выглядит следующим образом /admin/1.0/app_parameters.jsp через 1 месяц, это будет /admin/1.1/app_parameters.jsp и т. Д., И я не хочу менять его каждый раз, когда у меня есть обновление. Кроме того, он может отличаться для среды разработки, тестирования и производства, и я не хочу поддерживать 3 разные конфигурации и менять их для каждого обновления.

Если я попытаюсь сделать это так

<url-pattern>/admin/*/app_parameters.jsp</url-pattern>

тогда это не работает. и если я читаю официальную документацию tomcat , то нет объяснения, как это работает. Есть несколько примеров, таких как / *, но он работает только для каждой страницы.

Мой вопрос: Есть ли способ, как настроить Tomcat стандартным способом и динамически ограничить некоторые страницы? Одним из решений может быть нахождение полного синтаксиса url-pattern и проверка, поддерживается ли правильное регулярное выражение. Может быть, с использованием подфильтров / вложенных фильтров и т. Д. Или есть только одно решение для создания моего пользовательского фильтра Java на основе org.apache.catalina.filters.RemoteAddrFilter, где я могу применить правильное регулярное выражение к URL-адресу?

P.S. Кто-то может подумать, почему у меня есть страницы администратора внутри основного приложения, и я просто должен изменить свое приложение и переместить его в другое приложение, но проблема в том, что это стандартное приложение от какого-то поставщика. Я не создал это приложение самостоятельно. Если я сам изменю это приложение, я потеряю его поддержку и уже проверил, что эти 2 страницы не легко переместить. Эти 2 страницы имеют много зависимостей от других частей приложения. Конечно, я создам заявку для этого поставщика отдельно, но было бы хорошо получить независимое решение (План Б), если поставщик не может предоставить что-либо.

ОБНОВЛЕНИЕ 1

Я проверил исходные коды tomcat и похоже, что в элементе поддерживаются только 4 шаблона. Это код из org.apache.catalina.core.ApplicationFilterFactory

private boolean matchFiltersURL(String testPath, String requestPath) {
    if (testPath == null) {
        return false;
    }
    if (testPath.equals(requestPath)) {
        return true;
    }

    if (testPath.equals("/*"))
        return true;
    if (testPath.endsWith("/*")) {
        if (testPath.regionMatches(0, requestPath, 0, testPath.length() - 2)) {
            if (requestPath.length() == testPath.length() - 2)
                return true;
            if ('/' == requestPath.charAt(testPath.length() - 2)) {
                return true;
            }
        }
        return false;
    }

    if (testPath.startsWith("*.")) {
        int slash = requestPath.lastIndexOf('/');
        int period = requestPath.lastIndexOf('.');
        if ((slash >= 0) && (period > slash) && (period != requestPath.length() - 1) && (requestPath.length() - period == testPath.length() - 1)) {

            return testPath.regionMatches(2, requestPath, period + 1, testPath.length() - 2);
        }
    }

    return false;
}

кратко что поддерживается

  1. exact URL match
  2. <url-pattern>/*</url-pattern> means match for all URLs.
  3. <url-pattern>/some/path/*</url-pattern> means match for all URLs starting with  "/some/path". It support /* only at the end of the URL.
  4. <url-pattern>*.ext</url-pattern> means match for any path but with specific extension.
  5. All others are not supported (examples what is not supported: /fld1/*/fld2, /fld1/*.jsp, etc

некоторые примеры, которые могут помочь понять это

matchFiltersURL("", "/fld1/fld2/mypage.jsp")
     (boolean) false

matchFiltersURL("*", "/fld1/fld2/mypage.jsp")
     (boolean) false

matchFiltersURL("/*", "/fld1/fld2/mypage.jsp")
     (boolean) true

matchFiltersURL("/fld1/*", "/fld1/fld2/mypage.jsp")
     (boolean) true

matchFiltersURL("/fld1*", "/fld1/fld2/mypage.jsp")
     (boolean) false

matchFiltersURL("/fld1/fld2/*", "/fld1/fld2/mypage.jsp")
     (boolean) true

matchFiltersURL("/fld1/*/mypage.jsp", "/fld1/fld2/mypage.jsp")
     (boolean) false

matchFiltersURL("*./fld1/fld2/mypage.jsp", "/fld1/fld2/mypage.jsp")
     (boolean) false

matchFiltersURL("*./fld1/fld2/mypagejs", "./fld1/fld2/mypagejsp")

matchFiltersURL("*.jsp", "/.jsp");
     (boolean) true

matchFiltersURL("*.xxxx", "/.xxxx");
     (boolean) true

matchFiltersURL("*./fld1/xxxx", "/fld1/.xxxx");
     (boolean) false

matchFiltersURL("*./fld1/.xxxx", "/fld1/.xxxx");
     (boolean) false

matchFiltersURL("/fld1/fld2/*.jsp", "/fld1/fld2/mypage.jsp")
     (boolean) false

matchFiltersURL("*./fld1/fld2/*", "/fld1/fld2/mypage.jsp")
     (boolean) false

В результате этого явно невозможно использовать динамическую фильтрацию. Единственная возможность, которую я сейчас вижу, это пользовательский фильтр или вложенные фильтры.

...