欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Tomcat 8的CookieProcessor默认实现变化导致的cookie处理遇到的问题

程序员文章站 2022-10-03 18:01:59
问题描述:在将Tomcat升级到8.x及更高版本之后,后台报异常: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.tomc...
问题描述:

在将Tomcat升级到8.x及更高版本之后,后台报异常:

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)
 ...
问题原因:

Tomcat 8.x(or later)版本进了很多改进,其中的Cookie处理更换默认的CookieProcessor实现为 Rfc6265CookieProcessor,之前的实现为LegacyCookieProcessor。前者是基于RFC6265,而后者基于 RFC6265、RFC2109、RFC2616。这可能导致在 Tomcat 8以前的版本中运行无问题的Web项目在Tomcat 8中报下面错误:

java.lang.IllegalArgumentException: An invalid character [xx] was present in the Cookie value

上面的[xx]中的xx是指ASCII码(十进制)对应的字符。在不明确知道RFC6265规范中 Cookie值可用的字符时,可能在Cookie值使用其他字符也会出现上面的问题。

validateCookieValue源码:
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 < '!' || c == '"' || c == ',' || c == ';' || c == '\\' || c == 127) {
			throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidCharInValue", new Object[]{Integer.toString(c)}));
		}
	}

}
解决方法:
  1. 独立的Tomcat:修改配置文件context.xml,指定CookieProcessororg.apache.tomcat.util.http.LegacyCookieProcessor,具体配置如下:
<Context>
    <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
</Context>
  1. SpringBoot内嵌Tomcat的解决方式:在springboot启动类中增加内嵌Tomcat的配置Bean,如下代码:
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
	    SpringApplication.run(DemoApplication.class, args);
	}
	
	/**
	 * Tomcat Cookie 处理配置 Bean
	 */
	@Bean
	public WebServerFactoryCustomizer cookieProcessorCustomizer() {
		return factory -> factory.addContextCustomizers( context -> context.setCookieProcessor(new LegacyCookieProcessor()));
	}

}

本文地址:https://blog.csdn.net/weixin_44624841/article/details/107673174

相关标签: tomcat