Chuyển đến nội dung chính

レッスン 11: 多要素認証 - OTP、WebAuthn、およびパスキー

TOTP/HOTP (Google Authenticator、FreeOTP)、OTP ポリシー設定、リカバリ コードを使用した 2 要素認証を構成します。 WebAuthn セットアップ (FIDO2 セキュリティ キー)、WebAuthn パスワードレス ポリシー。パスキーの統合 (条件付きおよびモーダル UI)、AIA を介したパスキーの登録、Kerberos 認証、および X.509 クライアント証明書認証。

🔒 DevSecOps — レッスン 11 レッスン 11: 多要素認証 - OTP、 WebAuthn とパスキー

基本から上級までの Keycloak

パート 3: 認証、MFA、および ID ブローカリング

xdev.asia

1. OTP 認証 — TOTP および HOTP

OTP (ワンタイム パスワード) は、最も一般的な MFA 方式です。 Keycloakは2つのタイプをサポートしています。

タイプ説明するアルゴリズム
TOTP(時間ベース)OTP コードは時間の経過とともに (30 秒ごとに) 変化しますRFC 6238
ホット(HMACベース)OTPコードはカウンタに応じて変化しますRFC 4226

TOTPが推奨されますセキュリティを強化するには、コードは時間の経過とともに期限切れになります。 HOTP は、デバイスが正確なクロックをサポートしていない場合にのみ使用されます。

1.1 OTP ポリシーの設定

OTP ポリシーを次の場所に設定します認証 → ポリシー → OTP ポリシー:

設定説明するデフォルト値推奨
OTPタイプTOTPまたはHOTPトップトップ
OTP ハッシュ アルゴリズムハッシュアルゴリズムSHA1SHA256またはSHA512
桁数OTP 桁数66(最高の互換性)
先読みウィンドウコード番号が受け入れられる前/後11— ユーザーがタイムラグを起こしやすい場合は増加します
OTP トークンの期間コードごとの存続時間 (秒) — TOTP のみ3030
初期カウンター開始カウンター — HOTP のみ00
サポートされているアプリケーションセットアップ手順に表示されるアプリFreeOTP、Google認証システム必要に応じて他のアプリを追加する

1.2 Google Authenticator / FreeOTP を使用した OTP の設定

ステップ 1: 認証フローで OTP をオンにする

デフォルトでは、ブラウザ フローが利用可能ですブラウザ - 条件付き OTPサブフロー。 OTP は、ユーザーが OTP 資格情報を設定した場合にのみ必要です。に義務的なすべてのユーザーは OTP を設定する必要があります。

  1. 入力認証 → 必要なアクション
  2. 探すOTPの構成
  3. オンにするデフォルトのアクション: オン — すべての新規ユーザーは OTP を設定する必要があります
  4. またはオンにします必須既存のユーザーに強制する列「デフォルトのアクションとして設定」

ステップ 2: ユーザーが OTP を登録する

ユーザーが初めてログインしたとき (または管理者が必須アクションをオンにした後):

  1. Keycloakがページを表示します「モバイル認証設定」
  2. ユーザーが Google Authenticator または FreeOTP アプリを開く
  3. QRコードをスキャンするか、手動キーを入力してください
  4. アプリから確認用のOTPコードを入力します
  5. OTP 認証情報がユーザー用に保存されます

ステップ 3: OTP 認証

次回のログインからは、ユーザー名/パスワードを入力した後、アプリから OTP コードを入力する必要があります。

1.3 OTP認証情報の管理

# Admin xem OTP credentials của user
curl -s -X GET \
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/credentials" \
  -H "Authorization: Bearer $ADMIN_TOKEN" | \
  jq '.[] | select(.type=="otp")'

# Admin xóa OTP credential (force user setup lại)
curl -X DELETE \
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/credentials/$CREDENTIAL_ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN"

# Admin trigger Required Action cho user cụ thể
curl -X PUT \
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requiredActions": ["CONFIGURE_TOTP"]
  }'

2. リカバリーコード

リカバリ コードを使用すると、ユーザーは OTP デバイスを紛失した場合にアクセスを復元できます。

2.1 リカバリコードを有効にする

  1. 入力認証 → 必要なアクション
  2. 探す回復認証コード(お持ちでない場合は登録が必要です)
  3. オンにするデフォルトのアクションまたは有効

OTP セットアップ後にリカバリ コードを適用します。

OTP の設定直後にユーザーにリカバリ コードの作成を強制するには、次の順序で必須アクションを構成します。

  1. CONFIGURE_TOTP— 最初に OTP を設定します
  2. CONFIGURE_RECOVERY_AUTHN_CODES— 後でリカバリーコードを生成する

2.2 リカバリコードの使用

ユーザーが OTP デバイスを紛失した場合:

  1. OTP入力画面で、 をクリックします。「別の方法を試してください」
  2. 選択「リカバリーコード」
  3. 保存したリカバリコードのいずれかを入力してください
  4. 各コードのみ使用可能1回
  5. すべてのコードを使用した後、コードを再度生成する必要があります

3. WebAuthn (FIDO2) — セキ​​ュリティ キー

WebAuthn により認証が可能になりますハードウェアセキュリティキー(YubiKey、Google Titan) またはプラットフォーム認証システム(Touch ID、Windows Hello)。

3.1 ブラウザフローでの WebAuthn のセットアップ

ステップ 1: WebAuthn を認証フローに追加する

  1. 複製ブラウザのフロー →WebAuthn を備えたブラウザ
  2. Forms サブフローに、次のように追加します。WebAuthn オーセンティケーター
  3. フロー構造:
    Browser with WebAuthn
    ├── Cookie (Alternative)
    └── Forms (Alternative)
        ├── Username Password Form (Required)
        └── WebAuthn MFA (Conditional)
            ├── Condition - User Configured (Required)
            └── WebAuthn Authenticator (Required)
  4. バインドフロー:認証 → バインディング → ブラウザ フロー = WebAuthn を備えたブラウザ

ステップ 2: 必須アクションをオンにする

  1. 入力認証 → 必要なアクション
  2. 探すWeb認証登録→オンにするデフォルトのアクション
  3. 新規ユーザーはセキュリティキーの登録を求められます

3.2 WebAuthn ポリシーの設定

での構成認証 → ポリシー → WebAuthn ポリシー:

設定説明する価値
証明書利用者エンティティ名ユーザーに表示される名前キークロークまたは会社名
署名アルゴリズム署名アルゴリズムES256(推奨)、RS256
証明書利用者 IDKeycloakのドメインkeycloak.example.com(または空白のまま = 自動)
証明書の伝達の設定キーからの証明書の要求指定されていないまたは直接
認証子の添付ファイル認証子の種類指定されていない(USB キーとプラットフォームの両方を受け入れます)
常駐キーが必要ですキーはデバイスに保存する必要があります指定されていない
ユーザー認証要件デバイスでのユーザー認証が必要です指定されていないまたは必須。必須
タイムアウトの作成キー登録時のタイムアウト(秒)0(タイムアウトなし)
同じ認証子レジスタを避ける同じキーを重複して登録しないでくださいオフ
許容可能な AAGUIDホワイトリスト セキュリティ キー モデル空白のままにする = すべてを受け入れる

3.3 WebAuthn 認証情報の管理

# Xem WebAuthn credentials của user
curl -s -X GET \
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/credentials" \
  -H "Authorization: Bearer $ADMIN_TOKEN" | \
  jq '.[] | select(.type=="webauthn")'

# Response
{
  "id": "credential-uuid",
  "type": "webauthn",
  "userLabel": "YubiKey 5",
  "createdDate": 1711900000000,
  "credentialData": "{\"aaguid\":\"...\",\"credentialPublicKey\":\"...\"}"
}

ユーザーは内部セキュリティ キーを自分で管理することもできますアカウントコンソールで/realms/myrealm/account/#/security/webauthn.

4. パスキー

パスキーは WebAuthn の次の進化版です — 権限パスワードなしでログインする(パスワードレス) 指紋、顔認識、またはデバイスの PIN を使用します。

4.1 パスキーと従来の WebAuthn

特徴ウェブ認証 (MFA)パスキー (パスワードなし)
目的MFA — パスワードの後に​​ステップを追加パスワードを完全に置き換える
認証者WebAuthn オーセンティケーターWebAuthn パスワードレス認証システム
ポリシーWeb認証ポリシーWebAuthn パスワードレス ポリシー
必要なアクションWeb認証登録WebAuthn パスワードレス登録
常駐キーオプション検出可能な資格情報
ユーザー認証オプション必須 (生体認証/PIN)

4.2 パスキーを有効にする

ステップ 1: WebAuthn パスワードレスポリシーを構成する

  1. 入力認証 → ポリシー → WebAuthn パスワードレスポリシー
  2. 構成:
    • 証明書利用者エンティティ名: 私の会社
    • 署名アルゴリズム: ES256
    • ユーザー認証要件: 必須。必須
    • 常駐キーが必要です: はい— パスキーに必要

ステップ 2: パスワードレスのブラウザ フローを作成する

Passwordless Browser Flow
├── Cookie (Alternative)
└── Passwordless Login (Alternative)
    ├── WebAuthn Passwordless Authenticator (Alternative)  → Đăng nhập bằng Passkey
    └── Username Password Fallback (Alternative)           → Sub-flow fallback
        ├── Username Password Form (Required)
        └── Conditional OTP (Conditional)
            ├── Condition - User Configured (Required)
            └── OTP Form (Required)

ステップ 3: 必須アクションをオンにする

  1. 入力認証 → 必要なアクション
  2. オンにするWebAuthn パスワードレス登録→ デフォルトのアクション: オン

4.3 パスキー UI モード — 条件付きおよびモーダル

条件付き UI (自動入力):

パスキーはユーザー名フィールドに自動的に提案されます。ユーザーは選択するだけで生体認証を使用して認証できます。これが最もスムーズな体験です。

条件付き UI を有効にするには、次のように設定します。WebAuthn パスワードレス認証システム要件のあるフローの最初の位置にあります代替.

モーダル UI:

ブラウザに、Passkey による認証を求めるダイアログが表示されます。ユーザーはダイアログを操作する必要があります。明示的な UX が必要な場合に使用されます。

4.4 AIA (アプリケーション開始アクション) 経由でのパスキーの登録

ユーザーは、AIA リンク経由でいつでも Passkey に登録できます。

# AIA URL để trigger Passkey registration
GET /realms/myrealm/protocol/openid-connect/auth?
  client_id=my-app&
  redirect_uri=https://myapp.example.com/callback&
  response_type=code&
  scope=openid&
  kc_action=webauthn-register-passwordless

存在する場合はスキップします:ユーザーがすでにパスキーを持っている場合に登録をスキップしたい場合:

# Thêm parameter skip_if_exists
GET /realms/myrealm/protocol/openid-connect/auth?
  client_id=my-app&
  redirect_uri=https://myapp.example.com/callback&
  response_type=code&
  scope=openid&
  kc_action=webauthn-register-passwordless&
  kc_action_parameter=skip_if_exists

JavaScript の統合:

// Sử dụng keycloak-js adapter
const keycloak = new Keycloak({
  url: 'https://keycloak.example.com',
  realm: 'myrealm',
  clientId: 'my-app'
});

// Trigger Passkey registration
function registerPasskey() {
  keycloak.login({
    action: 'webauthn-register-passwordless'
  });
}

// Button trong UI
document.getElementById('registerPasskeyBtn')
  .addEventListener('click', registerPasskey);

5.ケルベロス認証

ケルベロスが許可されています自動シングルサインオンドメインにログインしているユーザーの場合 (Windows AD、MIT Kerberos)。ユーザーは資格情報を入力する必要はありません。ブラウザーが自動的に Kerberos チケットを送信します。

5.1 Kerberosサーバーのセットアップ

リクエスト:

  • KDC (キー配布センター) の実行 - Active Directory または MIT Kerberos
  • Keycloak サービスの SPN (サービス プリンシパル番号)
  • Keycloak用のKeytabファイル
# Tạo SPN và keytab cho Keycloak (MIT Kerberos)
kadmin -q "addprinc -randkey HTTP/[email protected]"
kadmin -q "ktadd -k /etc/keycloak/keycloak.keytab HTTP/[email protected]"

# Đặt permission
chmod 600 /etc/keycloak/keycloak.keytab
chown keycloak:keycloak /etc/keycloak/keycloak.keytab

5.2 Kerberos 用の Keycloak の構成

オプション 1: Kerberos ユーザー ストレージ プロバイダー

  1. 入力ユーザーフェデレーション → プロバイダーの追加 → Kerberos
  2. 構成:
    • ケルベロスレルム: 例.com
    • サーバープリンシパル: HTTP/[email protected]
    • キータブ: /etc/keycloak/keycloak.keytab
    • Kerberos認証を許可する:の上
    • パスワード認証に Kerberos を使用する:の上
    • 初回ログインの更新:の上

オプション 2: LDAP + Kerberos (Active Directory)

  1. 入力ユーザーフェデレーション → プロバイダーの追加 → LDAP
  2. AD の LDAP 接続を構成する
  3. 項目を有効にするKerberos認証を許可する
  4. Kerberos レルム、サーバー プリンシパル、キー タブを入力します。

5.3 ブラウザフローで Kerberos を有効にする

  1. 入力認証 → フロー → ブラウザ(またはカスタムフロー)
  2. 探すケルベロス実行。実行
  3. 要件の変更無効豪華な代替
Browser Flow (Kerberos enabled)
├── Cookie (Alternative)
├── Kerberos (Alternative)                    ← BẬT lên
├── Identity Provider Redirector (Alternative)
└── Forms (Alternative)
    ├── Username Password Form (Required)
    └── Browser - Conditional OTP (Conditional)
        ├── Condition - User Configured (Required)
        └── OTP Form (Required)

5.4 レルム間の信頼

ある Kerberos レルムのユーザーが別のレルムを信頼できるようにします。

# /etc/krb5.conf trên Keycloak server
[libdefaults]
    default_realm = CORP.EXAMPLE.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false

[realms]
    CORP.EXAMPLE.COM = {
        kdc = dc1.corp.example.com
        admin_server = dc1.corp.example.com
    }
    PARTNER.EXAMPLE.COM = {
        kdc = kdc.partner.example.com
    }

[capaths]
    PARTNER.EXAMPLE.COM = {
        CORP.EXAMPLE.COM = .
    }

6. X.509 クライアント証明書認証

X.509 では、次を使用した認証が可能です。クライアント証明書— 企業、政府、または mTLS 環境で一般的です。

6.1 ブラウザフローへの X.509 の追加

  1. 複製ブラウザのフロー →X.509を搭載したブラウザ
  2. もっとX509/ユーザー名検証フォーム流れの中へ
Browser with X.509
├── Cookie (Alternative)
├── X509/Validate Username Form (Alternative)  ← Thêm mới
├── Identity Provider Redirector (Alternative)
└── Forms (Alternative)
    ├── Username Password Form (Required)
    └── Browser - Conditional OTP (Conditional)
        ├── Condition - User Configured (Required)
        └── OTP Form (Required)

6.2 X.509 オーセンティケータの構成

横にある⚙️をクリックしてくださいX509/ユーザー名検証フォーム:

設定説明する例えば
ユーザー ID ソースユーザーを識別するための証明書のフィールド被験者の通称, 件名の電子メール
ソースとユーザー属性のマッピングID ソースをユーザー属性にマップするユーザー名またはメールアドレス
正規表現正規表現は証明書フィールドから ID を抽出しますCN=(.*?)(?:,\|$)
CRL チェックが有効になっています証明書失効リストを確認するの上
CRL配布ポイントCRL への URL またはパスldap://ca.example.com/CN=...
OCSPチェックが有効ですオンライン証明書ステータスの確認プロトコルの上
OCSP レスポンダー URIOCSP レスポンダ URLhttp://ocsp.example.com
証明書キーの使用法キーの使用法が必要ですデジタル署名
証明書の拡張キーの使用法拡張キーの使用法クライアント認証
証明書ポリシー検証モード証明書ポリシーを検証する指定されていない

6.3 証明書マッピング戦略

証明書を Keycloak ユーザーにマッピングするには、さまざまな方法があります。

# 1. Subject's Common Name → Username
# Certificate: CN=john.doe, OU=Engineering, O=Example Corp
# → username: john.doe

# 2. Subject's e-mail → Email
# Certificate: [email protected]
# → email: [email protected]

# 3. Serial Number → User Attribute
# Certificate: Serial=1A2B3C4D
# → user attribute "x509_serial" = "1A2B3C4D"

# 4. SHA-256 Certificate Thumbprint → User Attribute
# Certificate SHA-256: ab:cd:ef:12:34:...
# → user attribute "x509_thumbprint" = "ab:cd:ef:12:34:..."

# 5. Subject's DN với regex
# Certificate: CN=john.doe, OU=Engineering, O=Example Corp, C=VN
# Regex: CN=(.*?)(?:,|$)
# → Extracted: john.doe

6.4 CRL と OCSP のチェック

証明書が失効していないことを確認するには:

CRL (証明書失効リスト):

  • Keycloakは設定されたURIからCRLをダウンロードしてキャッシュします
  • クライアント証明書のシリアル番号が CRL にあるかどうかを確認します
  • CRL が利用できない場合、およびCRLチェック有効=オン→認証に失敗しました

OCSP (オンライン証明書ステータス プロトコル):

  • 証明書のステータスをリアルタイムで確認
  • KeycloakはOCSPレスポンダーにリクエストを送信します
  • 個別のチェックでは CRL よりも高速
  • 短所: OCSP サーバーの可用性によって異なります。
# Test OCSP check
openssl ocsp \
  -issuer ca.pem \
  -cert client.pem \
  -url http://ocsp.example.com \
  -resp_text

# Test certificate info
openssl x509 -in client.pem -noout -subject -serial -fingerprint -sha256

6.5 Keycloak mTLS セットアップ

Keycloakがクライアント証明書を受信できるようにするには、リバースプロキシまたはKeycloakを直接構成する必要があります。

# Docker Compose — Keycloak với mTLS qua nginx
services:
  nginx:
    image: nginx:latest
    ports:
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./certs/server.crt:/etc/nginx/certs/server.crt
      - ./certs/server.key:/etc/nginx/certs/server.key
      - ./certs/ca.crt:/etc/nginx/certs/ca.crt
    depends_on:
      - keycloak

  keycloak:
    image: quay.io/keycloak/keycloak:26.0
    command: start --proxy-headers xforwarded
    environment:
      KC_HOSTNAME: keycloak.example.com
      KC_HTTP_ENABLED: "true"
      KC_PROXY_HEADERS: xforwarded
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
# nginx.conf — Forward client certificate
server {
    listen 443 ssl;
    server_name keycloak.example.com;

    ssl_certificate /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;
    ssl_client_certificate /etc/nginx/certs/ca.crt;
    ssl_verify_client optional;

    location / {
        proxy_pass http://keycloak:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port 443;
        
        # Forward client certificate
        proxy_set_header ssl-client-cert $ssl_client_escaped_cert;
    }
}

7. MFA メソッドの比較

方法安全UXフィッシング耐性ユースケース
TOTP/HOTP中くらい良いそうではない人気があり、導入が簡単
ウェブ認証 (MFA)高い良い持っているエンタープライズ、コンプライアンス
パスキー非常に高い素晴らしい持っている消費者 + 企業
ケルベロス高い透明はい (ドメイン)エンタープライズ、Windows ドメイン
X.509証明書非常に高い透明持っている政府、軍、銀行

8. まとめ

コンセプト説明する
OTP ポリシーTOTP/HOTP 構成 — アルゴリズム、数字、ピリオド、先読み
リカバリーコードOTPデバイス紛失時のバックアップコード
ウェブ認証FIDO2 セキュリティ キー — フィッシング耐性のある MFA
パスキーパスワードレス認証 — 検出可能な資格情報 + 生体認証
ケルベロスドメイン ユーザー向けの透過的 SSO
X.509クライアント証明書認証 - mTLS
CRL/OCSP証明書失効チェック