web-dev-qa-db-ja.com

Spring RequestMappingパスパラメーターを使用したエンコードされたスラッシュ(%2F)はHTTP 400を提供します

これは重複していません 参照された質問 、これはSpring特有です。それを追加した人(事実の3年後!)は、本当の答えが何であるかを見るために質問やコメントスレッドを読むことを気にしませんでした。受け入れられた答えは完全な答えではありませんが、答えの作者は戻って来て、私が尋ねたようにそれを編集しませんでした。

以下の安らかな方法を考えると、Spring 3.1は「クライアントから送信されたリクエストは構文的に正しくありませんでした」というエラー400を返します()。 tokenパラメータに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

役に立たなかったようです。

32
Jim

これはあなたの答えかもしれません: エンコードされたスラッシュはURLを壊しています

それをパスに入れずに、代わりにリクエストパラメータに移動することをお勧めします。

回避策:

RequestMappingを次のように変更できます

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

次に、リクエストオブジェクトからパス変数を手動で解析します。

12
Solubris

スプリングブートの場合、次のトリックを行いました

@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);
    }

}
16
iamiddy

これは、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 として提案されました

7
30thh

私はこの解決策を見つけました。

System.setProperty("org.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");

springApplication.run(args)の直前;

applicationクラスに以下のコードを追加します

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

春のブートアプリケーションの場合、これは私のために働いた..

バージョン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または-Dorg.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = trueを使用してJavaアプリケーションを実行します

これにより、%2Fエンコードされたスラッシュパス変数が修正されました。

6
manukyanv07

私のオフィスでこの問題に出くわしました。上記で提案したことを Solubrisが言った クエリパラメーターに入れたところから行いました。唯一の追加要件は、データに ''も含めることができることです。これにより、クエリパラメーターが台無しになります。私たちがしなければならなかったのは、URLで送信される前にテキストをエンコードし、さらに ''を除外することだけでした。

0
rsteier

別の答えは_"/"_を2回エンコードすることで、これは_"%252F"_を生成します。
マップされたエンドポイントで、Springはそれを_"%2F"_にデコードします。さらに必要なのは、次のようなものを使用してもう一度デコードすることです:

URLDecoder.decode(encoded_URL, "UTF-8");

0
M. Sokólski