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"http:
enabled: false
host: "127.0.0.1"
canonicalAuthority: "localhost:8443"
https:
port: 8443
keyStore: "conf/keystore.jks"
keyStorePassword: "CHANGE-ME"
clientAuth: NONECHANGE-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.htmlHTTPSは http.host とHTTPの上限・期限を引き継ぎます。HTTP/2はh2cとTLS+ALPNの経路があります。独立した https.host や一般的な http2.* 調整キーは公開していません。
クライアント証明書
https.clientAuth はNONE(要求しない)、WANT(要求するが必須ではない)、NEED(必須)です。truststoreを指定するにはWANTかNEEDが必要です。
clientAuth: NEED
trustStore: "conf/truststore.jks"
trustStorePassword: "CHANGE-ME"
trustStoreType: JKSこれはTLSレベルの証明書検証です。webappのCLIENT-CERT認証には、さらにSubject DNとユーザーの対応が必要です。
certuser:
"alice": "CN=Alice Example,OU=Sales,O=Example Corp,C=JP"DNはRFC2253正規形で記述し、users.yamlにも同名ユーザーとロールを置きます。
ユーザーとロール
既定のusers.yamlはコメントだけで、利用可能なユーザーを含みません。以下の保存値部分は生成済みのPBKDF2値へ置換してください。CLI生成ツールは未提供で、実装には PasswordStorage.hash(String) があります。
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で資源を保護する
<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=true | HttpOnly付き。webappの標準設定で上書き可 |
| session.cookie.sameSite=Lax | サーバ固有設定。NoneはSecure付きの場合のみ。平文開始はLax |
| session.urlTracking.enabled=false | URLのjsessionidを追跡に使わない。URL追跡を宣言したwebappは配備失敗 |
| http.allowTrace=false | TRACEを405で拒否 |
| http.poweredByHeader=true | X-Powered-Byを送出。falseで抑止可能 |