Keycloakを利用したSPNEGO:統合Windows認証によるシングルサインオン
Keycloakを利用したSPNEGO:統合Windows認証によるシングルサインオンの構築方法を説明する。
目次
SPNEGO:統合Windows認証によるシングルサインオンの構築方法
1.概要
Keycloakを用いた統合Windows認証(SPNEGO:Kerberos認証)によるシングルサインオン(SSO)の動作に関する説明である。
KeycloakとはRed Hatが開発したオープンソースソフトウェア(OSS)であり、SSOや認証・認可を行うアイデンティティアクセス管理ソフトウェアである。
◎ KEYCLOAK
SPNEGOを用いることによりユーザID・パスワードを入力することなく、ドメインユーザでログインが完了する。
統合Windows認証とはドメインにログイン済みのクライアント端末からブラウザ経由でKerberos認証(RFC4120)する仕組みである。
また、ブラウザ経由でKerberos認証する仕組みをSPNEGO(The Simple and Protected GSS-API Negotiation Mechanism RFC2478)と言う。
2.前提
◎ Active Directory(AD)は構築されているものとする ※今回はドメイン名:「a-fronter2.local」で構築済み
◎ ADにKerberos認証用ユーザが作成されていること
◎ クライアント端末は上記ドメインに参加しているものとする
◎ クライアント端末のブラウザは統合Windows認証が許可されているものとする
◎ Keycloakはインストール済みとする
◎ Keycloakサーバの正引き、逆引きができるようDNSが設定されているものとする
◎ WebAPサーバとしてkeycloak-spring-security-adapterインストール済みのSpring Securityアプリが構築済みであること
3.認証フロー
以下、Keycloakを用いた統合Windows認証に関する認証フロー図である。
ドメインログイン済みユーザがユーザID・パスワードの入力をせずにWebアプリケーションにログイン可能であることがわかる。

4.環境構築設定手順
1.keytabファイルの作成
AD/KDC内のユーザ情報をkeytabファイルに出力し、Keycloakが読み込める状態にしておく必要がある。
keytabファイルはAD/KDCのコマンドプロンプトに以下のコマンドを実行して生成する。
ktpass
-out [任意のファイル出力先]
-princ [プリンシパル名](HTTP/[KeycloakサーバのFQDN]@[ADのドメイン名(大文字)])
-mapuser [任意のKerberos認証用ユーザ]
-pass [mapuserに設定するパスワード]
-ptype [KRB5_NT_PRINCIPAL]
(使用例)
C:\Users\Administrator>ktpass -out c:\krb2.keytab -princ HTTP/orpiment1.a-fronter2.local@A-FRONTER2.LOCAL
-mapuser administrator@a-fronter2.local -pass XXXXXXXX -ptype KRB5_NT_PRINCIPAL
結果:作成完了状態
Successfully mapped HTTP/orpiment1.a-fronter2.local to Administrator.
Key created.
Output keytab to c:\krb2.keytab:
Keytab version: 0x502
keysize 83 HTTP/orpiment1.a-fronter2.local@A-FRONTER2.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 6 etype
0x17 (RC4-HMAC) keylength 16 (0x4424147a7dcd3c47c4ec3921443023bd)
2.keytabファイル配置
Keycloakサーバの任意のディレクトリに1.で生成したkeytabファイルを配置する。
今回は以下のように配置した。
/opt/keycloak/krb2.keytab
3.Keycloakサーバの設定
Kerberos認証を行うにはLinuxの場合/etc/krb5.confファイルを修正する必要がある。
環境に合わせて以下の様にkdcやadmin_server、domain_realmを設定する。
# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
default_realm = A-FRONTER2.LOCAL
default_ccache_name = KEYRING:persistent:%{uid}
[realms]
A-FRONTER2.LOCAL = {
kdc = WIN-5R16NKGCO0G.a-fronter2.local
admin_server = orpiment1.a-fronter2.local
}
[domain_realm]
.a-fronter2.local = A-FRONTER2.LOCAL
a-fronter2.local = A-FRONTER2.LOCAL
4.Keycloakクライアントの設定
a.任意のレルムで「クライアント」の「作成」押下

b.任意のクライアントIDを入力し「保存」押下

c.クライアントが作成される。有効なリダイレクトURIに認証させるアプリのURIを入力し「保存」を押下

以上でクライアントの設定が完了。
5.Keycloakユーザフェデレーションの設定
a.任意のレルムで「ユーザーフェデレーション」の「プロバイダーの追加」「kerberos」押下

b.以下の様に環境に応じた値を入力し「保存」を押下
コンソール表示名:任意
Kerberosレルム:ドメイン名
サーバープリンシパル:keytabファイル作成時に指定したプリンシパル
KeyTab:Keycloakサーバに配置したkeytabファイルの絶対パス

以上でユーザーフェデレーションの設定が完了。
6.keycloak.jsonのダウンロードと配置
アプリのKeycloakアダプターを作成したクライアントに向けるためにkeycloak.jsonファイルをアプリに読み込ませる必要がある。
a.Keycloakの「クライアント」→作成したクライアント名を押下(今回はclient_spnego)

b.「インストール」押下

c.「フォーマットを選択」→「Keycloak OIDC JSON」押下

d.「ダウンロード」押下

e.ダウンロードしたファイルをWebアプリケーションのWEB-INF直下に配置する

※keycloak.jsonの”auth-server-url”の値がIPアドレスになっているとSPNEGOが動かない。
以下の様にFQDNに修正する。

7.ブラウザの設定
ブラウザからKeycloakに対してNegotiationヘッダを送信するための設定をする必要がある。
a.クライアント端末のインターネットエクスプローラー起動
b.「ツール」→「インターネットオプション」→「セキュリティ」→「ローカルイントラネット」を選択
c.「サイト」→「詳細設定」
d.下の画像のように、KeycloakのFQDNを追加する

5.動作確認
1.クライアント端末がドメインに参加していることを確認
net config workstation
C:\Users\n_asakawa>net config workstation
コンピューター名
フル コンピューター名
ユーザー
アクティブなネットワーク (ワークステーション)
NetBT_Tcpip_{7D32CCF0-5AE7-4CBB-AF59-FCB9B84DF409} (02004C4F4F50)
NetBT_Tcpip_{42A2A4F7-B239-425B-A730-0194720F7361} (52540063B9F1)
ソフトウェア バージョン Windows Server 2012 R2 Standard
ワークステーション ドメイン A-FRONTER2
ワークステーション ドメイン DNS 名 a-fronter2.local
ログオン ドメイン A-FRONTER2
COM デバイス オープン タイムアウト (秒) 0
COM デバイス送信バイト数 (バイト) 16
COM デバイス送信タイムアウト (ミリ秒) 250
コマンドは正常に終了しました。
2.クライアント端末のブラウザで統合Windows認証が許可されていることを確認
今回はブラウザにGoogleChromeを使用するため以下から確認する。
a.インターネットエクスプローラー起動
b.「ツール」→「インターネットオプション」→「詳細設定」を選択
c.「統合Windows認証を使用する」にチェックがついていること
3.クライアント端末のGoogleChromeからWebアプリケーションにアクセスする。(認証フロー②)
WebAPにアクセスすると統合Windows認証が動きアプリのログイン後画面が表示される

認証画面が出力されずにログインが完了する。

6.動作詳細確認
クライアント端末でWiresharkを起動しパケットを見てみる。
左の〇番号が認証フロー図と対応したパケットである。

クライアント端末のチケット情報を確認する
【ADへのログイン直後】(認証フロー①)
以下の様に3つのチケットが確認できる。

Webアプリケーションログイン直後】(認証フロー㉒)
以下の様にチケットが4つに増えている。
増えたものがKerberos認証で要求、取得したHTTPサービスチケットだとわかる。
