복붙노트

[SPRING] Spring RequestMapping 경로 매개 변수가있는 인코딩 된 슬래시 (% 2F)는 HTTP 400을 제공합니다.

SPRING

Spring RequestMapping 경로 매개 변수가있는 인코딩 된 슬래시 (% 2F)는 HTTP 400을 제공합니다.

이것은 스프링과 관련되어 중복 된 참조 질문이 아닙니다. 누구든지 그 사실을 추가 한 사람 (3 년 후 사실!)은 진짜 대답이 무엇인지 알아보기 위해 질문이나 댓글 스레드를 읽지 않아도됩니다. 받아 들여진 대답은 꽤 답이 아니지만 대답의 저자는 내가 물어 본 것처럼 되돌아 와서 편집하지 않았다.

아래의 적절한 방법을 감안할 때 Spring 3.1은 "클라이언트가 보낸 요청은 구문 적으로 올바르지 않습니다 ()."라는 400 개의 오류를 제공합니다. 토큰 매개 변수에 URL 인코딩 된 슬래시 (% 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. ==============================

    1.이것은 귀하의 답변 일 수 있습니다 : urlencoded 전달 슬래시가 URL을 깨는 것입니다.

    이것은 귀하의 답변 일 수 있습니다 : urlencoded 전달 슬래시가 URL을 깨는 것입니다.

    나는 그것을 경로에 두지 말고 요청 매개 변수로 옮겨 놓으십시오.

    해결 방법 :

    RequestMapping을 다음으로 변경할 수 있습니다.

    @RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET) 
    

    요청 오브젝트에서 수동으로 경로 변수를 구문 분석하십시오.

  2. ==============================

    2.스프링 부트의 경우 다음과 같은 트릭을 수행했습니다.

    스프링 부트의 경우 다음과 같은 트릭을 수행했습니다.

    @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. ==============================

    3.다음은 Spring 3.2.4의 수정 사항입니다 (다른 버전에서도 잘 동작 할 것입니다). 하나는 기본 UrlPathHelper을 덮어 써야합니다.

    다음은 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. ==============================

    4.봄 부팅 응용 프로그램이 나를 위해 일했다 ..

    봄 부팅 응용 프로그램이 나를 위해 일했다 ..

    버전 1 더하다

    org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
    

    application.properties 파일

    버전 2 이렇게 봄 부팅 응용 프로그램을 실행하십시오.

    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 = true

    나에게 고정 된 % 2F로 인코딩 된 슬래시 경로 변수.

  5. ==============================

    5.나는 나를 위해 일하는이 해결책을 발견했다.

    나는 나를 위해 일하는이 해결책을 발견했다.

    System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
    

    직전 springApplication.run (args);

    응용 프로그램 클래스에 아래 코드를 추가하십시오.

     @Override
        public void configurePathMatch(PathMatchConfigurer configurer) {
            UrlPathHelper urlPathHelper = new UrlPathHelper();
            urlPathHelper.setUrlDecode(false);
            configurer.setUrlPathHelper(urlPathHelper);
        }
    
  6. ==============================

    6.우리 사무실 사무실에서이 문제를 만났습니다. Solubris가 쿼리 매개 변수에 넣은 위치에 대한 제안에서 위의 제안을했습니다. 유일한 추가 요구 사항은 데이터에 '&'가있을 수 있으며 이는 쿼리 매개 변수를 엉망으로 만듭니다. URL에서 전송되기 전에 텍스트를 인코딩해야하고 '&'까지도 필터링되었습니다.

    우리 사무실 사무실에서이 문제를 만났습니다. Solubris가 쿼리 매개 변수에 넣은 위치에 대한 제안에서 위의 제안을했습니다. 유일한 추가 요구 사항은 데이터에 '&'가있을 수 있으며 이는 쿼리 매개 변수를 엉망으로 만듭니다. URL에서 전송되기 전에 텍스트를 인코딩해야하고 '&'까지도 필터링되었습니다.

  7. from https://stackoverflow.com/questions/13482020/encoded-slash-2f-with-spring-requestmapping-path-param-gives-http-400 by cc-by-sa and MIT license