46

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

以下のRESTfulメソッドを考えると、Spring 3.1は「クライアントから送信されたリクエストが構文的に正しくありませんでした()」という400エラーを出します。パラメータにURLエンコードされたスラッシュ(%2F)が含まれている場合、tokenたとえば「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

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

4

10 に答える 10

24

スプリングブートの場合、次のトリックが行われました

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

}
于 2016-06-02T20:03:20.803 に答える
14

これはあなたの答えかもしれません:urlencodedスラッシュはURLを壊しています

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

回避策:

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

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

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

于 2012-11-21T07:33:38.187 に答える
10

Spring Boot 2+ / Spring(Security)5+ / Java 8+の2019アップデート:

iamiddyの回答に対する私の編集が拒否されたため、別の回答としてSpring Boot2+の完全なソリューションも提供したいと思います。

WebMvcConfigurerAdapterSpring5/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);
    }
}

(Strict)HttpFirewallさらに、エラーメッセージでエンコードされたスラッシュがブロックされないようにSpringを構成する必要もあります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は、利用可能な場合は上記のBeanを使用します。それ以外の場合は、ここで説明するようHttpFirewallに構成する必要がある場合があります。WebSecurity

于 2019-10-09T12:06:50.483 に答える
7

これがSpring3.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) {
            return getOriginatingServletPath(request);
        }

        @Override
        public String getOriginatingServletPath(HttpServletRequest request) {
            return request.getRequestURI().substring(request.getContextPath().length());
        }
    }

そして、それをマッピングハンドラーに注入します。

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

于 2013-11-20T11:07:17.130 に答える
7

スプリングブートアプリケーションの場合、これは私にとってはうまくいきました。

バージョン1 追加

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

application.propertiesファイルに

バージョン2 は、このようにSpringBootアプリケーションを実行します。

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でエンコードされたスラッシュパス変数。

于 2016-02-25T19:12:40.423 に答える
6

私は私のために働いているこの解決策を見つけました。

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);
    }
于 2016-06-07T10:27:23.783 に答える
1

変数を手動で解析することを避けるために、私は次のことを行いました。

  1. 他のコードを実行する前に、以下を追加してください。
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
  1. そして、コントローラーで、1つではなく2つの変数を追加します。次に例を示します。
    @RequestMapping(value = "/api/devices-by-name/device={deviceId}/restconf/data/ietf-interfaces:interfaces-state/interface={dpuIdPrefix}/{dpuIdSuffix}",
            method = RequestMethod.GET,
            produces = "application/json")
    public ResponseEntity<String> getInterfaceState(@PathVariable(value = "deviceId") String deviceId,
                                                    @PathVariable(value = "dpuIdPrefix") String dpuIdPrefix,
                                                    @PathVariable(value = "dpuIdSuffix") String dpuIdSuffix) {
        String dpuId = dpuIdPrefix + "/" + dpuIdSuffix;

そしてそれで私は以下を検索することができます:

curl -s -X GET http://localhost:9090/api/devices-by-name/device=ZNSDX16DPU03/restconf/data/ietf-interfaces:interfaces-state/interface=gfast%200%2F14

スラッシュがオプションの場合、2つの異なる要求マッピングを構成する必要がある場合があります。

于 2021-05-20T15:44:18.760 に答える
0

私たちはちょうど私のオフィスでこの問題に遭遇しました、私たちはあなたがそれをクエリパラメータに入れたところにソルブリスが言ったことから上記の提案であったことをしました。唯一の追加要件は、データに「&」も含めることができることです。これにより、クエリパラメータが台無しになります。URLで送信される前にテキストをエンコードするだけで、「&」も除外されます。

于 2014-04-10T19:57:59.040 に答える
0

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

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

于 2019-05-23T08:24:00.083 に答える
0

以下は、BACK_SLASHの問題を解決しました。

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

ただし、application.ymlを介して同じ機能を実行できます。

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

この設定は機能しません。私はその方法を見つけられず、それでもそれを見ています。

于 2020-07-22T08:31:25.723 に答える