Manual / TLS・認証・セッション2026.10.14 · ユーザーマニュアル
CHAPTER 07 / KOHAKU

TLS・認証・セッション

TLSの構成、認証用のユーザー定義、FORMログインとセッションの既定動作を説明します。

ローカルTLSの構成例

配布ディレクトリで実行します。以下はローカル確認用の自己署名証明書です。公開環境では適切な証明書チェーンを含むJKSを用意します。鍵エントリとkeystoreのパスワードは同じにしてください。

証明書と秘密鍵の作成 — パスワードはプロンプトへ入力
"${KOHAKU_JAVA_HOME:-/opt/java/jdk21}/bin/keytool" -genkeypair \
  -alias server -keyalg RSA -keysize 3072 -validity 365 \
  -storetype JKS -keystore conf/keystore.jks \
  -dname "CN=localhost" -ext "SAN=dns:localhost,ip:127.0.0.1"
conf/server.yaml — TLSのみで起動
http:
  enabled: false
  host: "127.0.0.1"
  canonicalAuthority: "localhost:8443"
https:
  port: 8443
  keyStore: "conf/keystore.jks"
  keyStorePassword: "CHANGE-ME"
  clientAuth: NONE

CHANGE-ME を作成時のパスワードへ置換し、設定ファイルの読取権限を実行ユーザーに限定します。変更後はプロセスを起動し直します。

自己署名証明書を信頼して確認
"${KOHAKU_JAVA_HOME:-/opt/java/jdk21}/bin/keytool" -exportcert -rfc \
  -alias server -keystore conf/keystore.jks -file conf/server-cert.pem
bin/kohaku.sh start
curl --cacert conf/server-cert.pem -i https://localhost:8443/hello/index.html

HTTPSは http.host とHTTPの上限・期限を引き継ぎます。HTTP/2はh2cとTLS+ALPNの経路があります。独立した https.host や一般的な http2.* 調整キーは公開していません。

クライアント証明書

https.clientAuth はNONE(要求しない)、WANT(要求するが必須ではない)、NEED(必須)です。truststoreを指定するにはWANTかNEEDが必要です。

conf/server.yamlのhttps配下 — 既存設定に追記
clientAuth: NEED
trustStore: "conf/truststore.jks"
trustStorePassword: "CHANGE-ME"
trustStoreType: JKS

これはTLSレベルの証明書検証です。webappのCLIENT-CERT認証には、さらにSubject DNとユーザーの対応が必要です。

conf/cert-users.yaml
certuser:
  "alice": "CN=Alice Example,OU=Sales,O=Example Corp,C=JP"

DNはRFC2253正規形で記述し、users.yamlにも同名ユーザーとロールを置きます。

ユーザーとロール

既定のusers.yamlはコメントだけで、利用可能なユーザーを含みません。以下の保存値部分は生成済みのPBKDF2値へ置換してください。CLI生成ツールは未提供で、実装には PasswordStorage.hash(String) があります。

conf/users.yaml — 保存値は実際の生成値へ置換
user:
  "alice":
    password: "{PBKDF2-SHA256}210000$<Base64のsalt>$<Base64の導出鍵>"
    roles:
      - operator
保存形式と対応
形式用途・制限
{PBKDF2-SHA256}反復回数$salt$導出鍵BASIC/FORM等。新規生成は210,000回、salt32バイト、鍵32バイト
{SHA-256}Base64ハッシュ互換用。salt無しのため非推奨。起動時WARN
接頭辞無しの平文DIGESTはこの形式のユーザーだけ利用可能。平文保存のWARNが出る

ユーザー名・保存値は引用し、rolesはブロック列で書きます。空のパスワード、壊れた保存形式、未知の {...} 形式はそのユーザーを無視します。rolesだけのエントリも認証に使えません。

web.xmlで資源を保護する

WEB-INF/web.xmlのweb-app直下 — BASICの例
<security-constraint>
  <web-resource-collection>
    <web-resource-name>private</web-resource-name>
    <url-pattern>/private/*</url-pattern>
  </web-resource-collection>
  <auth-constraint><role-name>operator</role-name></auth-constraint>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>Kohaku</realm-name>
</login-config>
<security-role><role-name>operator</role-name></security-role>

未認証のBASIC/DIGESTは401、権限不足は403です。平文経由のCONFIDENTIAL資源はHTTPSへリダイレクトする経路を持ちます。実際に稼働するTLSと公開URLが合っているか確認します。

FORMログインと正規authority

j_security_check へのPOSTは既定でOriginを検査します。Originが無い場合だけRefererを参照し、ホストとポートを比較します。両方無い、Originがnull、不正または複数の値の場合は403です。比較先はwebappのcanonical-authority、次にserver.yamlのhttp.canonicalAuthority、どちらも無ければ受信Hostです。スキームは比較しません。

TLS終端プロキシの背後では外向きのホスト名を正規authorityとして設定してください。公開標準ポートならポートを省略します。生成URLの正規authorityはHost許可リストや仮想ホスト機能ではなく、受信Hostが異なるだけでは拒否しません。FORM検査のHostへのフォールバックと、生成URLのローカルアドレスへのフォールバックは別の動作です。

セッションの既定

セッション・メソッドの設定
設定既定の動作
session.cookie.httpOnly=trueHttpOnly付き。webappの標準設定で上書き可
session.cookie.sameSite=Laxサーバ固有設定。NoneはSecure付きの場合のみ。平文開始はLax
session.urlTracking.enabled=falseURLのjsessionidを追跡に使わない。URL追跡を宣言したwebappは配備失敗
http.allowTrace=falseTRACEを405で拒否
http.poweredByHeader=trueX-Powered-Byを送出。falseで抑止可能