Кодированная косая черта (% 2F) с Spring Параметр requestMapping path указывает HTTP 400
Это не дублированный вопрос, поскольку это Spring конкретный. Тот, кто добавил, что (через 3 года после факта!) Не удосужился прочитать вопрос или комментарий, чтобы узнать, каков реальный ответ. Принятый ответ - не совсем ответ, но автор ответа так и не вернулся и отредактировал его, как я спросил.
В соответствии с приведенным ниже способом, Spring 3.1 дает ошибку 400 с "Запрос, отправленный клиентом, был синтаксически неправильным()". когда параметр token
содержит кодированную косую черту (% 2F), например " https://somewhere.com/ws/stuff/lookup/resourceId/287559/token/R4o6lI%2FbBx43/userName/jim" Без% 2F все работает нормально. Третья сторона уже звонит в эту службу (конечно!), Поэтому я не могу изменить то, что они отправляют, в краткосрочной перспективе, по крайней мере. Любые идеи о том, как обойти это на стороне сервера?
Эта проблема очень хорошо описана здесь https://jira.springsource.org/browse/SPR-8662, хотя эта проблема связана с UriTemplate, которую я не использую, что я могу сказать.
@RequestMapping("/ws/stuff/**")
@Controller
public class StuffController {
@RequestMapping(value = "/ws/stuff/lookup/resourceId/{resourceId}/token/{token}/userName/{userName}", method = RequestMethod.GET)
public @ResponseBody
String provisionResource(@PathVariable("resourceId") String resourceId, @PathVariable("token") String token, @PathVariable("userName") String userName, ModelMap modelMap,
HttpServletRequest request, HttpServletResponse response) {
return handle(resourceId, userName, request, token, modelMap);
}
}
Примечание. Это на Glassfish 3.1.2, и сначала Grizzly/Glassfish не принимали косую черту, но
-Dcom.sun.grizzly.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
исправлено это.
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.http.encoded-slash-enabled=true
похоже, не помогло.
Ответы
Ответ 1
Это может быть ваш ответ: urlencoded Прямая косая черта ломает URL
Я бы предложил не указывать это в пути, вместо этого переместить его в параметр запроса.
Работа вокруг:
Вы можете изменить RequestMapping на
@RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET)
а затем проанализируйте переменные пути вручную из объекта запроса.
Ответ 2
для spring -boot, трюк
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {
public static void main(String[] args) throws Exception {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run(Application.class, args);
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
Ответ 3
Вот исправление для Spring 3.2.4 (должно работать и для других версий). Нужно перезаписать стандартный UrlPathHelper
public class UrlPathHelperFixed extends UrlPathHelper {
public UrlPathHelperFixed() {
super.setUrlDecode(false);
}
@Override
public void setUrlDecode(boolean urlDecode) {
if (urlDecode) {
throw new IllegalArgumentException("Handler [" + UrlPathHelperFixed.class.getName() + "] does not support URL decoding.");
}
}
@Override
public String getServletPath(HttpServletRequest request) {
String servletPath = getOriginatingServletPath(request);
return servletPath;
}
@Override
public String getOriginatingServletPath(HttpServletRequest request) {
String servletPath = request.getRequestURI().substring(request.getContextPath().length());
return servletPath;
}
}
И добавьте его в обработчик сопоставления:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="order" value="-1"></property>
<property name="urlPathHelper">
<bean class="com.yoochoose.frontend.spring.UrlPathHelperFixed"/>
</property>
</bean>
После дня тяжелых работ он работает сейчас для меня: -)
Было предложено команде Spring как https://jira.springsource.org/browse/SPR-11101
Ответ 4
Для приложения загрузки spring это сработало для меня.
Версия 1
Добавить
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
в файл application.properties
Версия 2
запустите приложение загрузки spring, как это.
static void main(String[] args) {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run this, args
}
Версии 3 или запустите приложение Java с помощью
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = истина
Эта фиксированная переменная с косой чертой% 2F для меня.
Ответ 5
Я нашел это решение, которое работает для меня;
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
непосредственно перед
springApplication.run(арг);
и добавьте ниже код в класс приложения
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
Ответ 6
Мы столкнулись с этой проблемой в моем офисе, мы сделали то, что было предложено выше, из Solubris сказал, где вы поместили его в параметр запроса. Единственным дополнительным требованием является то, что данные могут иметь "&" а также, что испортило бы параметр запроса. Все, что нам нужно было сделать, это кодировать текст до его отправки в URL-адрес и даже "&" были отфильтрованы.
Ответ 7
Другой ответ "/"
дважды закодировать "/"
, что приведет к "%252F"
.
В вашей сопоставленной конечной точке Spring декодирует ее обратно в "%2F"
. Все, что вам нужно, это еще раз декодировать его, используя что-то вроде этого:
URLDecoder.decode(encoded_URL, "UTF-8");
Ответ 8
Обновление 2019 для Spring Boot 2+/Spring (Security) 5+/Java 8+:
Поскольку мое изменение в ответе iamiddy было отклонено, я также хочу предоставить полное решение для Spring Boot 2+ в качестве отдельного ответа.
WebMvcConfigurerAdapter
устарела в Spring5/Java8 и может быть заменена непосредственно интерфейсом WebMvcConfigurer
, заканчивающимся:
@SpringBootApplication
public class Application extends WebMvcConfigurer {
public static void main(String[] args) throws Exception {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run(Application.class, args);
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
Кроме того, вам также необходимо настроить Spring (Strict)HttpFirewall
, чтобы избежать блокировки закодированных слешей с сообщением об ошибке The request was rejected because the URL contained a potentially malicious String "%2F"
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
Spring Boot будет использовать вышеупомянутый компонент HttpFirewall
, когда он доступен - в противном случае может потребоваться настроить WebSecurity
, как указано здесь: