Пожалуйста, не закрывайте этот вопрос как ответ, потому что все ссылки, которые я нашел, например 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
В результате этого явно невозможно использовать динамическую фильтрацию. Единственная возможность, которую я сейчас вижу, это пользовательский фильтр или вложенные фильтры.