Possible issues with cookies after upgrading to Tomcat 8
From: http://www.lichenliang.top/tomcat-8-invalid-character-cookie-value.html
problem scenario
For the web project running in Tomcat 7 before, when Tomcat is upgraded from 7 to 8.x and later, the user login fails and an exception is reported in the background:
java.lang.IllegalArgumentException: An invalid character [xx] was present in the Cookie value at org.apache.tomcat.util.http.Rfc6265CookieProcessor.validateCookieValue(Rfc6265CookieProcessor.java:162) at org.apache.tomcat.util.http.Rfc6265CookieProcessor.generateHeader(Rfc6265CookieProcessor.java:111) ... |
norm change
Tomcat 8.x (or later) has made many improvements, and the cookie handling has also been upgraded to the RFC6265 specification, which may cause web projects that run without problems in Tomcat 8 to report the following error in Tomcat 8:
java.lang.IllegalArgumentException: An invalid character [34] was present in the Cookie value
The 34 in [34] above refers to the character " (double quotation marks) corresponding to the ASCII code (decimal). Then when the characters available for the cookie value in the RFC6265 specification are not clearly known, other characters may also appear in the cookie value. The problem.
So let's take a look at which characters are not available.
View source code
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))); } } } |
Through the above source code analysis, the strings that are not available for cookie values in the RFC6265 specification are analyzed, as shown in the following table:
decimal | hex | Abbreviation/Character | explain |
---|---|---|---|
34 | 0x22 | “ | Double quotes |
44 | 0x2C | , | comma |
59 | 0x3B | ; | semicolon |
92 | 0x5C | \ | backslash |
127 | 0x7f | DEL (delete) | delete (control character) |
< 33 | < 0x21 | slightly | Control characters/communication special characters/space |
problem causes
Tomcat 8 replaces the default CookieProcessor implementation with Rfc6265CookieProcessor, and the previous implementation is LegacyCookieProcessor. The former is based on RFC6265, while the latter is based on RFC6265, RFC2109, and RFC2616.
Solution
Standalone Tomcat
Modify the configuration file context.xml and specify the CookieProcessor as org.apache.tomcat.util.http.LegacyCookieProcessor. The specific configuration is as follows:
<Context> <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" /> </Context> |
SpringBoot embedded Tomcat solution
Add the configuration bean embedded with Tomcat in the springboot startup class, as follows:
@SpringBootApplication public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); } // Tomcat cookie handling configuration bean @Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() { return (factory) -> factory.addContextCustomizers( (context) -> context.setCookieProcessor(new LegacyCookieProcessor())); } } |
References:
Tomcat 8 CookieProcessor implementation changes
Baidu Encyclopedia ASCII