■ 発生現象
以下の「構成」で、Webサービスを立ち上げたところ、Webサービスでセッションが取得できなくなった。 Tomcatのログを確認したところ、以下「メッセージ内容」のようになっていた。 また、「通信ログ」を確認したところ、カンマ区切りでクッキーが付加されていた。
メッセージ内容
org.apache.tomcat.util.http.parser.Cookie.logInvalidHeader A cookie header was received [AWSALB=YYYYYY] that contained an invalid cookie. That cookie will be ignored.Note: further occurrences of this error will be logged at DEBUG level.
通信ログ
・・・ Cookie: JSESSIONID=XXXXX, AWSALB=YYYYYY
構成
* Client(Java) | HTTPS ↓ * ロードバランサ / Sticky Session | HTTP ↓ * Apache (v2.4.6) ※v2.2.31でも起こる | AJP1.3 ↓ * Tomcat (v8.5.11) ↓ * Webサービス(Java)
■ 原因
* Tomcat8から、Cookie のパースが、RFC6265 準拠するようになった。 * RFC6265 は、以前(RFC2109など)に許容していたカンマ区切りを許容しなくなったため 「Cookie: KEY1=VAL1, KEY2=VAL2」のような形は、不正とみなしてしまっていた
RFC2109
http://pentan.info/doc/rfc/j2109.htmlthe separator in the Cookie header is semi-colon (;) everywhere. # Cookie ヘッダー内の区切り文字は、どこでもセミコロン (;)である A server should also accept comma (,) as the separator between cookie-values for future compatibility. # サーバは、クッキー値との間の後方の互換性のために、カンマも区切り文字でも受け入れるべきだ。 ⇒ つまり、RFC2109では「Cookie: KEY1=VAL1, KEY2=VAL2」でもOKだった
RFC6265
https://triple-underscore.github.io/RFC6265-ja.htmlcookie-header = "Cookie:" OWS cookie-string OWS cookie-string = cookie-pair *( ";" SP cookie-pair ) # 特にカンマを区切り文字にする記述はない
Tomcatのソースより抜粋
org.apache.tomcat.util.http.parser.Cookieクラスpublic static void parseCookie(byte[] bytes, int offset, int len, ServerCookies serverCookies) { // ・・・略・・・ // Using RFC6265 parsing rules, check to see if the header starts with a // version marker. An RFC2109 version marker may be read using RFC6265 // parsing rules. If version 1, use RFC2109. Else use RFC6265. skipLWS(bb); // ・・・略・・・ if (skipResult != SkipResult.FOUND) { // No need to reset position since skipConstant() will have done it parseCookieRfc6265(bb, serverCookies); return; }
■ 解決案
案1:TomcatのCookieのパーサーをLegacyCookieProcessorに切り替える
* server.xml に「<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />」を付加し 古いクッキーパーサーを有効にするserver.xml
<Context> <!-- 略 --> <!-- Add --> <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" /> </Context>公式サイト
https://tomcat.apache.org/tomcat-8.5-doc/config/cookie-processor.html
より抜粋 Legacy Cookie Processor - org.apache.tomcat.util.http.LegacyCookieProcessor This is the legacy cookie parser based on RFC6265, RFC2109 and RFC2616. It implements a strict interpretation of the cookie specifications. Due to various interoperability issues with browsers not all strict behaviours are enabled by default and additional options are available to further relax the behaviour of this cookie processor if required.
案2:Apacheを他のサーバに変更する
* 例えば、Nginxとか。 * 以下の関連記事を参照のこと。SSLで、Amazon ELB - Nginx - Tomcat を連携する
http://blogs.yahoo.co.jp/dk521123/36729223.html