Spring Boot + npm + Geb で入力フォームを作ってテストする ( その77 )( RequestAndResponseLogger クラスの Cookie ログは name, value だけ出力するように変更する+SESSION Cookie の secure 属性を true にするには? )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その76 )( Spring Boot Actuator を導入する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Spring Boot + npm + Geb で入力フォームを作ってテストする ( その75 )( コネクションプーリング用ライブラリを Tomcat connection pool → HikariCP に切り替える ) で RequestAndResponseLogger クラスが出力しているリクエスト、レスポンスのログを見て SESSION Cookie の domain 属性が null、httponly 属性が false と出力されていて、何か問題がありそうだったので調査します。
参照したサイト・書籍
Turn off HttpOnly Spring boot
https://stackoverflow.com/questions/22428233/turn-off-httponly-spring-bootAdd secure flag to JSESSIONID cookie in spring automatically
https://stackoverflow.com/questions/39252924/add-secure-flag-to-jsessionid-cookie-in-spring-automaticallySpring Session
https://docs.spring.io/spring-session/docs/2.0.4.RELEASE/reference/html5/Spring Session - Custom Cookie
https://docs.spring.io/spring-session/docs/2.0.4.RELEASE/reference/html5/guides/java-custom-cookie.html
目次
- 現在の状況を確認する
- サーバから Cookie の domani 属性が未セットの状態で返されると、ブラウザはアクセスした時のドメインをセットする?
- Spring Session では SESSION Cookie の httponly 属性をデフォルトで有効にしている?
- RequestAndResponseLogger クラスの Cookie のログでは name, value しか出力しないように変更する
- SESSION Cookie の secure 属性を true にするには?
手順
現在の状況を確認する
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その75 )( コネクションプーリング用ライブラリを Tomcat connection pool → HikariCP に切り替える ) で、ksbysample.webapp.bootnpmgeb.aspect.logging.RequestAndResponseLogger が出力しているログを見ると SESSION Cookie の domain 属性が null だったり、httponly 属性が false だったりしていたのですが、
[req][cookie] name = SESSION, value = MThlNDQ3NGUtNmQ0Mi00Y2Q2LTlmNTYtMDA4ZDZlYjg3NTQ3, domain = null, path = null, maxage = -1, secure = false, httponly = false
Chrome の Develper Tools で SESSION Cookie を確認すると domain 属性も httponly 属性もセットされていました。
Develper Tools で SESSION Cookie を削除してから再度リクエストを送信し、Fiddler で SESSION Cookie が最初に返される時の HTTP ヘッダを確認したところ以下の文字列が返ってきており、domain 属性はありませんが httponly 属性はセットされていました。
Set-Cookie: SESSION=ZDIyYThlZTctZDg1Yi00MGYyLTgwZmEtNzA4N2U4Y2E1YTY4; Path=/; HttpOnly
今度はリクエストの送信時に Cookie をどのように送信しているかを見てみると以下の文字列が HTTP ヘッダで送信されており、Cookie はキーと値しか送信されていませんでした。
Cookie: SESSION=ZDIyYThlZTctZDg1Yi00MGYyLTgwZmEtNzA4N2U4Y2E1YTY4
ということは、
- サーバから Cookie の domani 属性が未セットの状態で返されると、ブラウザはアクセスした時のドメインをセットする?
- Spring Session では SESSION Cookie の httponly 属性をデフォルトで有効にしている?
- request 時のデータを ksbysample.webapp.bootnpmgeb.aspect.logging.RequestAndResponseLogger で出力しているが、request では Cookie は name と value しか送信されないので、それ以外の属性を出力しても意味がない。
サーバから Cookie の domani 属性が未セットの状態で返されると、ブラウザはアクセスした時のドメインをセットする?
調べたら CookieのDomain属性は 指定しない が一番安全 という記事を見つけました。内容が分かりやすく納得しました。domain 属性はセットしてはいけないんですね。
Spring Session では SESSION Cookie の httponly 属性をデフォルトで有効にしている?
org.springframework.session.web.http.DefaultCookieSerializer を見ると private boolean useHttpOnlyCookie = true;
と実装されていました。デフォルトで httponly 属性を有効にしていました。
RequestAndResponseLogger クラスの Cookie のログでは name, value しか出力しないように変更する
src/main/java/ksbysample/webapp/bootnpmgeb/aspect/logging/RequestAndResponseLogger.java の以下の点を変更します。
private void loggingRequestCookies(HttpServletRequest request) { if (request.getCookies() != null) { Arrays.asList(request.getCookies()).forEach(cookie -> { StringBuilder sb = new StringBuilder(); sb.append("name = ") .append(cookie.getName()) .append(", value = ") .append(cookie.getValue()); logging(LOG_REQUEST_COOKIE, null, sb.toString()); }); } }
- loggingRequestCookies メソッド内の
.append(", domain = ") ... .append(cookie.isHttpOnly());
を削除します。
これで SESSION Cookie をログに出力すると以下のように name, value しか出力されません。
[req][cookie] name = SESSION, value = OTk1MmIzZDktMjQwMi00NDEyLTgwZWItYWQyOTQ5MGYyMmUx
SESSION Cookie の secure 属性を true にするには?
Spring Session - Custom Cookie に記述がありました。
src/main/java/ksbysample/webapp/bootnpmgeb/config/ApplicationConfig.java に cookieSerializer Bean を定義し、その中で cookieSerializer.setUseSecureCookie(true);
を呼び出して secure 属性を有効にします。独自の cookieSerializer Bean を定義すると Spring Session でこちらが使用されるようになります。
@Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); cookieSerializer.setUseSecureCookie(true); return cookieSerializer; }
動作確認してみます。bs-springboot-config.js に https: true,
を追加して Browsersync で https を処理できるようにします。
.......... serveStatic: [], https: true, ghostMode: { ..........
Tomcat を起動した後、npm run springboot
コマンドを実行します。
Chrome の Developer Tools で SESSION Cookie を削除した後、https://localhost:9080/inquiry/input/01/ にアクセスします。
画面が表示された後、Developer Tools で SESSION Cookie を見ると secure 属性が有効になっていることが確認できます。
履歴
2018/08/12
初版発行。