【Apache】【Tomcat】 「A cookie header was received [XXX=YYY] that contained an invalid cookie」が表示される

■ 発生現象

以下の「構成」で、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.html
the 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.html
cookie-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:TomcatCookieのパーサーを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

関連記事

Nginx ~ 入門編 / Linux版 ~

http://blogs.yahoo.co.jp/dk521123/36721709.html

SSLで、Amazon ELB - Nginx - Tomcat を連携する

http://blogs.yahoo.co.jp/dk521123/36729223.html