Подтвердить что ты не робот

Кодированная косая черта (% 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

похоже, не помогло.

4b9b3361

Ответ 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, как указано здесь: