簡體   English   中英

spring啟動時如何處理RequestParam中的大括號

[英]How to handle curly braces in RequestParam in spring boot

我有一個帶有 GET 服務的 spring 啟動應用程序。

@RequestMapping(value = "/abc/track/{type}", method = RequestMethod.GET)

    public void DummFunc(                            
          @RequestParam(value="subs", required = false) String sub,
,  HttpServletResponse response) {}

subs的值是一個編碼值。

如果我將以下作為值傳遞給參數 subs

{%22endpoint%22:%22https://def.abc.com/tyu/send/eD3vpGNQW28:APA91bHOo8rYrV0xccdQz3okjZJG-QGrJX8LG6ahJnEUpMNfGedqi3hJxQsJx_8BMbH6oDjaSPPEXqzNWchWrGSkhuTkSdemikkys1U22Ipd7MsRw0owWbw89V2fslIVAJ6G5lkyvYuQ%22,%22expirationTime%22:null,%22keys%22:{%22p256dh%22:%22BK0pktn50CMsTQtqwdPlKlJtdFs0LFeXX14T1zgoz6QWnvSTp5dxtChnUP5P1JX0TsjcopbdPKyN31HfABMUyic%22,%22auth%22:%22qbO_z0vGao9wD-E5g8VU-A%22}}

它無法捕獲請求,並且控制不會進入 function 內部。

如果我們改為將值傳遞給參數 subs:

%7B%22endpoint%22:%22https://def.abc.com/tyu/send/dX5q5eV7hFQ:APA91bHib-0QXrMzjatcvTR_uaIeeJK8lf6GmXUC9Jxv0Oxth-BzD4GmWnd4-YpDZv8qSFZ0eSg9mB2YkRvkc5ezdXW5KeaHjuQZfdyDxyBXjJgE-25Xbtlk37pdm8vfLk20k0k_VxW9%22,%22expirationTime%22:null,%22keys%22:%7B%22p256dh%22:%22BCCvcBLpRqp4u0auP688_MUJLsAiwWlQSn5kpyl8YVsEo_J-KpSdnhCmVIE_BhDXBcFYflPK52hqhYf3EaOCyuY%22,%22auth%22:%22iKuW_ESkCZnubWcQu_JK8w%22%7D%7D

它工作正常。

  1. 為什么會這樣? 第一次編碼有什么問題?

  2. 由於服務器無法處理請求,它返回 400。我需要捕獲此類請求,然后通過正確編碼來處理它們。 什么可以前進?

我是 Spring boot/Spring 和 Java 本身的新手。 如果我能獲得一些見解,那就太好了。

另外,我可以在這里在線解碼它們,沒有任何問題- https://www.urldecoder.org/

編輯:基本上,通過問題的請求有{}而不是%7B%7D

我的問題不是應用程序因 400 個錯誤請求而失敗,而是如何在我的應用程序中捕獲此類請求,正確編碼然后處理它們。

這與 Java 或 Spring 本身無關,而是與 HTML URL 編碼參考相關。 URL 只能使用 ASCII 字符集通過 Internet 發送。

不安全字符在RFC-1738的開頭定義,這里是列表:

" < > # % { } | \\ ^ ~ [ ] ` 包括空格。

除此之外,還有屬於以下的保留字符,用於區分參數、鍵值表示、端口等。

; / ? :@ = &

您使用的不安全字符是{} ,它們等於%7B%7D


本質上,您應該擔心客戶端以您描述的方式發送給您的數據。 服務器必須要求傳遞正確的表單和 URL。 盡管瀏覽器和 REST 客戶端會自動對這些字符進行編碼,但以編程方式發送它們可能會導致錯誤。 我所知道的 Spring 中僅有的兩個可用解決方案是通過注冊CharacterEncodingFilter bean(已回答)或 Spring-Boot 配置:

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

您需要先啟用編碼並強制執行 HTTP 請求和響應。

spring-boot 非常關注安全性。 我猜添加雙引號/單引號或轉義都行不通。

請通過: https : //tools.ietf.org/html/rfc1738

我認為您應該嘗試手動編碼{%7B}%7D

不安全:

出於多種原因,字符可能不安全。 空間
字符是不安全的,因為重要的空格可能會消失並且
轉錄 URL 時可能會引入無關緊要的空格或
排版或經受文字處理程序的處理。
字符“<”和“>”是不安全的,因為它們被用作
自由文本中 URL 周圍的分隔符; 引號 (""") 用於
在某些系統中分隔 URL。 字符“#”是不安全的,應該始終進行編碼,因為它用於萬維網和其他
系統將 URL 與可能跟隨它的片段/錨標識符分隔開。 字符“%”是不安全的,因為它用於
其他字符的編碼。 其他字符是不安全的,因為
網關和其他傳輸代理有時會修改
這樣的字符。 這些字符是“{”、“}”、“|”、“\\”、“^”、“~”、
“[”、“]”和“`”。

所有不安全的字符必須始終在 URL 中編碼。 為了
例如,字符“#”必須在 URL 中編碼,即使是
通常不處理片段或錨點的系統
標識符,以便如果 URL 被復制到另一個系統中
如果使用它們,則無需更改 URL 編碼。

通常,當托管您的 Springboot 應用程序的 APP 服務器(如 Undertow、tomcat、Jboss)不允許某些特殊字符時,會出現此問題,這些字符在服務器之間可能很不一致。 這樣做是為了保護 URL,沒有人可以向服務器發送一些特殊字符以損害其功能。

如果在Springboot應用中還想允許特殊字符到達controller,需要在APP服務器中允許這個配置。 例如,這是 Undertow 服務器中要求的配置,以允許 URL 中的特殊字符:

@Configuration
public class HttpConfig {
    @Bean
    public UndertowServletWebServerFactory servletWebServerFactory() {
        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
        factory.addBuilderCustomizers((UndertowBuilderCustomizer) builder ->
                builder.setServerOption(UndertowOptions.ALLOW_UNESCAPED_CHARACTERS_IN_URL, Boolean.TRUE));
        return factory;
    }
}

為了使springboot能夠很好的對rest url進行UTF-8編碼/解碼,在application.properties文件中添加如下配置,對於springboot 2.6版本:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.force-request=true
server.servlet.encoding.force-response=true

最好的方法是在調用此 rest URL 的客戶端應用程序中對特殊字符進行編碼以符合安全原則

由於 Tomcat 升級了他們在 URL 參數中的安全性。 請找到可能的解決方案https://github.com/bohnman/squiggly/issues/42#issuecomment-386658525

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM