17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Keycloak by OpenStandiaAdvent Calendar 2017

Day 7

Keycloakでリバプロ型構成を組んでみる(Security Proxy編)

Last updated at Posted at 2017-12-06

今日やること

Keycloakアドベンドカレンダー7日目の今回は、KeycloakのSecurity Proxyを試してみます。

Security Proxyは、Javaで実装されたシンプルなリバースプロキシ(以後、リバプロ)サーバーの一種です。このリバプロサーバー自体がKeycloakのクライアント・アダプターの代わりとなり、プロキシ先のコンテンツの保護や、URLごとのアクセス制御を行うことが可能になります。
アプリケーションサーバーがOpenID ConnectやSAMLに対応していない場合や、クライアント・アダプターの導入が難しい場合、もしくはクライアント・アダプターが対応していない環境の場合の利用に適しています。

主な機能は以下のとおりです。

  • HTTP(S)のリバプロ機能
  • KeycloakサーバーとのOpenID Connect連携
  • 特定パスごとのコンテンツ保護
    • 認証要求によるアクセス制御
    • 特定のHTTPメソッドの許可、拒否
    • 認証済みユーザーのロールによるアクセス制御
    • 特定URLのアクセスを拒否
    • 認証不要でアクセスできるURLの指定
  • HTTPヘッダによる認証済みユーザーの情報連携

今回はTomcat 8の素のサンプルアプリに対して、Security Proxyで保護をかける際の手順を試してみます。

動作確認用のサーバー構成

今回のお試し環境はこのような感じです。
Keycloakサーバーには、demoレルムが作成されており(3日目の記事を参照)、以下のようなロールをもつユーザーが存在していることが前提となります。

FQDN OS JDK 構成 LISTEN ポート
kc-server.example.com CentOS 7.4.1708 OpenJDK 1.8.0.151 ・Keycloakサーバー 3.3.0.CR2 8443
kc-proxy.example.com CentOS 7.4.1708 OpenJDK 1.8.0.151 ・Security Proxy 3.3.0.CR2
・Tomcat 8.5.23
・18443(Security Proxy)
・8080(Tomcat)
ユーザー ロール
user001 user
admin001 user,admin

Tomcatに付属するexapmlesアプリケーションでは、以下のようなアクセス制御をかけることを想定します。

proxy_acl01.jpg

動作確認時の各サーバーへのアクセスポートは以下のとおりです。
proxy_port01.png

Keycloakサーバー側の設定

クライアントの追加・設定

  1. Keycloakの管理コンソールにログインします。
  2. 左メニューバーから、demoレルムを選択します。
  3. 左メニューバーで クライアント をクリックします。クライアント一覧が表示されます。
  4. 右上の 作成 ボタンを押下します。
  5. 以下のようなクライアント設定値を入力し、保存 ボタンを押下します
  1. 引き続き kc-proxy の設定画面が表示されるので以下のような設定を行い、保存 ボタンを押下します。
  • アクセスタイプ: confidential
  • 有効なリダイレクトURI(1つ目): https://kc-proxy.example.com:18443/
  • 有効なリダイレクトURI(2つ目): https://kc-proxy.example.com:18443/examples/websocket/echo.xhtml
    proxy02_opt.png
    :information_source: 有効なリダイレクトURIは、Keycloak上ではワイルドカードによる指定も可能です。ただし、OIDCの仕様上では、redirect_uriと厳密に一致することが必須となっているため、ここではリダイレクト先となりえるURLはすべて指定しています。そのため、ここで指定していないURLへは未ログイン状態から直接遷移できません。
  1. クレデンシャル タブを押下します。
  2. シークレット として表示されている値を控えます。
    proxy03.png

Security Proxy側の設定と起動

サンプルアプリケーションの導入

連携確認用のサンプルアプリケーションとして、Tomcat 8.0を導入して起動しておきます。

cd  /tmp
wget http://ftp.tsukuba.wide.ad.jp/software/apache/tomcat/tomcat-8/v8.5.23/bin/apache-tomcat-8.5.23.tar.gz
tar zxvf apache-tomcat-8.5.23.tar.gz -C /usr/local
cd /usr/local/apache-tomcat-8.5.23/
./bin/startup.sh

Security Proxyのダウンロードと展開

Security Proxyをダウンロードして /usr/local に解凍し、展開したディレクトリに移動しておきます。

cd  /tmp
wget https://downloads.jboss.org/keycloak/3.3.0.CR2/keycloak-proxy-3.3.0.CR2.zip
unzip keycloak-proxy-3.3.0.CR2.zip -d /usr/local
cd /usr/local/keycloak-proxy-3.3.0.CR2/

Security Proxyの設定ファイル作成

Security Proxyを動作させるために、以下のような設定ファイルを作成します。

/usr/local/keycloak-proxy-3.3.0.CR2/proxy.json
{
    "target-url": "http://localhost:8080",
    "send-access-token": true,
    "bind-address": "{バインドするIPアドレス・DNS名}",
    "http-port": "18080",
    "https-port": "18443",
    "applications": [
        {
            "base-path": "/",
            "adapter-config": {
                "realm": "demo",
                "resource": "kc-proxy",
                "auth-server-url": "https://kc-server.example.com:8443/auth",
                "ssl-required" : "external",
                "credentials": {
                    "secret": "{Keycloakサーバー側のシークレットの値}"
                }
            },
            "constraints": [
                {
                    "pattern": "/*",
                    "authenticate": true
                },
                {
                    "pattern": "/examples/jsp/*",
                    "permit": true
                },
                {
                    "pattern": "/examples/websocket/*",
                    "roles-allowed": [
                        "admin"
                    ]
                }
            ]
        }
    ]
}

proxy.json内の設定パラメータの意味ついて、以下に記載します。

基本設定

パラメータ名 必須 説明
target-url リバプロ転送先URLを指定します。
send-access-token KEYCLOAK_ACCESS_TOKENというヘッダ名でアクセストークンをプロキシ先に送信するかどうかを指定します。
bind-address プロキシサーバーのソケットにバインドするためのDNS名もしくはIPアドレスを指定します。外部から接続する場合は、ループバックアドレス以外を指定します。
http-port HTTPとしてLISTENするポート番号を指定します。ただし、HTTPのアクセスが許可されるかどうかは、後述のadapter-configssl-requiredの設定値に依存します。
https-port HTTPSとしてLISTENするポート番号を指定します。
keystore HTTPSを受け付ける場合に利用されるキーストアを指定。キーストアを指定しなかった場合は自動生成された一時的な自己署名サーバー証明書が利用されます。
keystore-password キーストアを指定した場合のキーストアパスワードを指定します。
key-password 利用されるサーバ証明書のキーパスワードを指定します。
buffer-size HTTPサーバーのソケットバッファサイズを指定します。通常デフォルトのままで問題ありません。
buffers-per-region HTTPサーバーのリージョンごとのソケットバッファ数を指定します。通常デフォルトのままで問題ありません。
io-threads IOを処理するスレッド数を指定します。通常デフォルトのままで問題ありません。
worker-threads リクエストを処理するスレッド数を指定します。通常デフォルトのままで問題ありません。

applicationsの設定

パラメータ名 必須 説明
base-path アプリケーションのコンテキストルートを指定します。"/"で始まる必要があります。
error-page エラーが発生した場合(アクセスを拒否した場合も含む)に表示するエラーページを指定します。base-pathからの相対パスを指定します。
adapter-config 後述します。

adapter-configの設定

パラメータ名 必須 説明
realm Keycloak側のレルム名を指定します。
resource Keycloak側のクライアント設定のクライアントID(client-id)を指定します。
auth-server-url Keycloak側のベースURLを指定します。1
credentials Keycloak側のアクセスタイプで"confidential"を指定した場合は必須です。
ssl-required HTTPSでのアクセスを強制するかどうか指定します。"all", "external", "none" のいずれかを指定します。デフォルトは、"external"なので、外部からはHTTPのアクセスは許可されません。

:information_source: adapter-configの設定は非常に多くあるため、動作確認に必要な最低限の項目のみ記載しています。その他のパラメータに関しては、参考資料の"Java Adapter Config"を参照ください。

constraintの設定

パラメータ名 必須 説明
pattern URLパターンを指定。"/"で始まる必要があり、ワイルドカード(*)は最後でのみ指定が可能です。
有効なパターン: /foo/bar/* および /foo/*.txt
無効なパターン: /*/foo/*
roles-allowed 特定のロールをもつユーザーのみアクセスを許可する設定です。配列で複数の指定可能です。
methods 許可するHTTPメソッド名を配列で指定します。
excluded-methods 拒否するHTTPメソッド名を配列で指定します。
deny アクセスを拒否する場合にはtrueを設定します(Keycoak Security Proxy経由ではアクセスさせたくないURLなど)。
permit 認証不要でアクセス可能にする場合にはtrueを設定します。
permit-and-inject 認証不要でアクセス可能にする場合にはtrueを設定します。ただし、認証済みでアクセスされた場合はヘッダにユーザー情報を付加します。
authenticate ロールに関係なく、認証のみでアクセス可能にする場合にはtrueを設定します。

proxy.jsonを作成したら、以下のコマンドからSecurity Proxyが起動できます。

cd /usr/local/keycloak-proxy-3.3.0.CR2/
java -jar bin/launcher.jar proxy.json

設定ファイルに問題がなければ、以下のような起動メッセージが表示されます。

Home directory: /usr/local/keycloak-proxy-3.3.0.CR2
11 24, 2017 6:44:37 午後 org.keycloak.proxy.ProxyServerBuilder initConnections
WARN: Generating temporary SSL cert
11 24, 2017 6:44:45 午後 org.xnio.Xnio <clinit>
INFO: XNIO version 3.3.6.Final
11 24, 2017 6:44:45 午後 org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.3.6.Final

動作確認

認証が必要なURL

  1. 認証が必要な https://kc-proxy.example.com:18443/ にアクセスします。
  2. Keycloakに未ログインであるため、ログイン画面にリダイレクトが発生します。
  3. ID/PWでログインします。
  4. Tomcatのトップ画面が表示されます。
  5. https://kc-proxy.example.com:18443/examples/servlets/servlet/RequestHeaderExample にアクセスします。
  6. HTTPヘッダにKeycloakのユーザー情報が連携されているのが分かります。
    proxy04.png

認証が不要なURL

  1. 認証が不要な https://kc-proxy.example.com:18443/examples/jsp/ にアクセスします。
  2. 認証していなくてもページを参照できるのが分かります。
    proxy05.png

admin ロールが必要なURL

  1. adminロールが必要な https://kc-proxy.example.com:18443/examples/websocket/echo.xhtml にアクセスします。
  2. adminロールを持つユーザーのID/PWでログインします。
  3. https://kc-proxy.example.com:18443/examples/websocket/echo.xhtml が表示される。(admin ロールを持たないユーザーでログインした場合は403エラーとなります)
    proxy07.png

まとめ

今回はKeycloakとSecurity ProxyをID連携させる方法を確認しました。
基本的に設定用のjsonファイルを1つ配置するだけで、KeycloakとのID連携を確認できるため、リバプロ型の簡易的な動作確認としては有用かと思います。

ですが、Security Proxyを本格的にシステムに組み込む場合は、リバプロとして機能的に不足している点がいくつかあります。

  • プロキシ転送先が1サーバーしか指定できない
  • アクセスログがない
  • Apacheのような細かな制御(URL置換やヘッダ置換、ロードバランシングなどなど)ができない
  • HTTPヘッダとして連携できる項目が限られている

そのためリバプロ型構成を利用する場合は、8日目の記事で私が解説する「Keycloakでリバプロ型構成を組んでみる(mod_auth_openidc編)」を使用することにより、上記の不足点を補いつつ、リバプロとして柔軟な設定が利用可能となります。

参考資料

脚注

  1. Keycloakサーバーとのssl接続で自己署名サーバー証明書を利用する場合にはSecurity Proxy側のJavaのtruststoreにサーバー証明書の取り込みが必要です。(Security Proxyが、Keycloakサーバーと直接SSL通信するため)

17
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?