升级到 Tomcat 8 后 Cookie 可能出现的问题
From: http://www.lichenliang.top/tomcat-8-invalid-character-cookie-value.html
問題場景
之前運行在 Tomcat 7 中的 Web 項目,當把 Tomcat 從 7 升級到 8.x 及更高版本后,用戶登錄失敗,后臺報異常:
| java.lang.IllegalArgumentException: An invalid character [xx] was present in the Cookie valueat org.apache.tomcat.util.http.Rfc6265CookieProcessor.validateCookieValue(Rfc6265CookieProcessor.java:162)at org.apache.tomcat.util.http.Rfc6265CookieProcessor.generateHeader(Rfc6265CookieProcessor.java:111)... |
規(guī)范變化
Tomcat 8.x( or later)版本進了很多改進,其中的 Cookie 處理也升級到 RFC6265 規(guī)范,這可能導致在 Tomcat 8 以前版本中運行無問題的Web項目在 Tomcat 8 中報下面錯誤:
java.lang.IllegalArgumentException: An invalid character [34] was present in the Cookie value
上面的 [34] 中的 34 是指 ASCII 碼(十進制)對應的字符 “(雙引號)。那么在不明確知道 RFC6265 規(guī)范中 Cookie 值可用的字符時,可能在 Cookie 值使用其他字符也會出現(xiàn)上面的問題。
那么下面就來看看到底哪些字符時不可用的。
查看源碼
| private void validateCookieValue(String value) {int start = 0;int end = value.length();if (end > 1 && value.charAt(0) == '"' && value.charAt(end - 1) == '"') {start = 1;end--;}char[] chars = value.toCharArray();for (int i = start; i < end; i++) {char c = chars[i];if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) {throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidCharInValue", Integer.toString(c)));}} } |
Rfc6265CookieProcessor.validateCookieValue 源碼地址
通過上面這段源碼分析出 RFC6265 規(guī)范中 Cookie 值不可用的字符串,見下表:
| 34 | 0x22 | “ | 雙引號 |
| 44 | 0x2C | , | 逗號 |
| 59 | 0x3B | ; | 分號 |
| 92 | 0x5C | \ | 反斜杠 |
| 127 | 0x7f | DEL (delete) | 刪除(控制字符) |
| < 33 | < 0x21 | 略 | 控制字符/通信專用字符/空格 |
問題原因
Tomcat 8 更換默認的 CookieProcessor 實現(xiàn)為 Rfc6265CookieProcessor ,之前的實現(xiàn)為 LegacyCookieProcessor 。前者是基于 RFC6265 ,而后者基于 RFC6265、RFC2109、RFC2616 。
解決方式
獨立的 Tomcat
修改配置文件 context.xml ,指定 CookieProcessor 為 org.apache.tomcat.util.http.LegacyCookieProcessor,具體配置如下:
| <Context><CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" /> </Context> |
SpringBoot 內嵌 Tomcat 的解決方式
在 springboot 啟動類中增加內嵌 Tomcat 的配置 Bean,如下代碼:
| @SpringBootApplication public class Application extends SpringBootServletInitializer {public static void main(String[] args) {SpringApplication.run(Application.class, args);}// Tomcat Cookie 處理配置 Bean@Beanpublic WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {return (factory) -> factory.addContextCustomizers((context) -> context.setCookieProcessor(new LegacyCookieProcessor()));} } |
參考資料:
Tomcat 8 CookieProcessor 實現(xiàn)變化
百度百科 ASCII
總結
以上是生活随笔為你收集整理的升级到 Tomcat 8 后 Cookie 可能出现的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ionic Mac 环境配置
- 下一篇: 泰拉瑞亚tModLoader 模组浏览器