Red Hat Single Sign-On を試してみる

今回はRH-SSOを早速試してみようと思います。RH-SSOには様々な機能が含まれていますが、今回は、RH-SSOをSAML IDPとして立てて、簡単なウェブアプリケーション(WAR)をSAML認証対応にしてみようと思います。

まずは、動作をみるための環境を整えておきます。私は以下のような環境を用意しました。

f:id:daijik:20160624144104p:plain

 3つの独立したネットワークを用意しました(もっとシンプルでも良いのですが、デバッグの際にパケットキャプチャなどがしやすいように、たまたま、こうしただけです)。

ポイントは、RH-SSO IdPからは、アプリが動作するWebサーバー#1,2 は見えないというところです。その逆も同じく、Webサーバー#1,2からIdPサーバーは見えません(ネットワーク的に独立しています)。クライアントから見えているのは、Webアプリケーションへの入り口となるロードバランサと、認証サーバー(IdP)だけです。

以下、今回の検証で期待する動作です。

  1. クライアント(ブラウザ)から、ロードバランサのVIP(192.168.150.15:80)に向けてアプリケーションへアクセス
  2. アプリケーションは未ログイン状態のため、認証処理をするために、クライアント(ブラウザ)に対して、リダイレクトするよう応答。リダイレクト先はもちろん、RH-SSO IDP です。
  3. RH-SSOに対してログイン
  4. ログインに成功すると、アプリケーションへ戻るように、リダイレクトで応答。
  5. クライアント(ブラウザ)は、アプリケーションへのリダイレクト要求を受け取り、「1」でアクセスしたアプリケーションへリダイレクト。
  6. 無事、アプリケーションを見ることが出来る。

というわけで、これを実現するために、これから設定をしてみます。

RH-SSO のセットアップ

RH-SSOのインストールはとても簡単です。Red Hatよりバイナリを入手したら、適当な場所に展開してください。これでインストール自体は完了です。JDK8以上の環境があれば、そのまま起動することが出来ます。

このブログエントリでは、RH-SSOを展開した場所を、便宜上、RHSSO_HOMEとしておきます。

adminユーザーを追加する

RH-SSOのサーバーを使うには、あらかじめ、管理者ユーザー(admin)を追加しておく必要があります。管理者ユーザーの追加は以下のようにして行います。

RHSSO_HOME/bin/add-user-keycloak.sh -u admin
RH-SSOサーバーを起動する

管理者ユーザーを作成したら、以下のコマンドにてサーバーを起動します。基本的なお作法はJBoss EAPと同じです。 今回の環境では192.168.122.30でアクセスしたいため、-b / -bmanagement オプションを付けています。

$ RHSSO_HOME/bin/standalone.sh -b 192.168.122.30 -bmanagement 192.168.122.30

サーバーが起動できたら、以下のURLにアクセスすることで、管理コンソールにアクセスすることが出来るようになっているはずです。

http://192.168.122.30:8080/

f:id:daijik:20160627142152p:plain

管理コンソールが表示されたら、先程作成した、adminユーザーでログインをします。

テストに使うためのRoleを作成する

画面左の「Roles」、画面右の「Add Role」をクリックして、適当なロールを作成します。今回は「user」というロールを作成しました。

f:id:daijik:20160627143544p:plain

f:id:daijik:20160627143943p:plain

 
テストに使うためのUserを作成する

続いて、ユーザーを作成します。適当なユーザーを作ってあげます。

f:id:daijik:20160627144114p:plain

今回は「daijik」というユーザーを追加します。

f:id:daijik:20160627144152p:plain

パスワードも設定してやります。

f:id:daijik:20160627144217p:plain

f:id:daijik:20160627144234p:plain

そして、最初に作成したロール(user)とマッピングしてやります。

f:id:daijik:20160627144317p:plain

f:id:daijik:20160627144400p:plain

 これで、RH-SSOのセットアップは完了です。

 

続いて、(SAML的にはクライアントとなる)、Webサーバー側の設定に入ります。今回はアプリケーション・サーバーとして、5月頃に出たばかりのJBoss EAP 7 を使ってみたいと思います。今回はJBoss EAP 7自体のセットアップについては割愛しますが、EAPがインストールされている場所を便宜上、EAP_HOMEとします。

今回の環境では、上図でいうところの、Webサーバー#1/#2 のそれぞれに、EAPがインストールしてあるとイメージしてください。

それでは、早速、EAP7に対してRH-SSOを使うための設定を入れていきます。RH-SSOにはクライアント・アダプタという形で、EAPのモジュールが提供されています。rh-sso-7.0.0-eap7-adapter.zip、rh-sso-7.0.0-saml-eap7-adapter.zip というファイルで提供されています。まずは、これらのファイルを2台のEAPサーバーに設定していきます。

クライアント・アダプタのインストール

クライアント・アダプタをEAP_HOMEに展開する

cd EAP_HOME
unzip /path-to/RH-SSO-7.0.0.GA-eap7-adapter.zip

 

SAMLアダプタをEAP_HOMEに展開する

cd EAP_HOME
unzip /path-to/RH-SSO-7.0.0.GA-saml-eap7-adapter.zip

さらにCLIのコマンドを使って、設定をしていきます。今回のCLIの操作では動作中のEAPサーバーに接続をしますので、あらかじめEAPを起動しておきます。

EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml

今回の環境では2台のEAPサーバーを用意していて、アプリのセッション・クラスタリングも試したいので、--server-config=standalone-ha.xml として、HA用のプロファイルを使ってEAPを起動します。

サーバーが起動出来たら、以下のCLIコマンドを実行して、クライアント・アダプタに関する情報をサーバー設定(standalone-ha.xml)へ反映させます。

EAP_HOME/bin/jboss-cli.sh -c --file=EAP_HOME/bin/adapter-install.cli
EAP_HOME/bin/jboss-cli.sh -c --command=:reload
EAP_HOME/bin/jboss-cli.sh -c --file=EAP_HOME/bin/adapter-install-saml.cli
EAP_HOME/bin/jboss-cli.sh -c --command=:reload

同じ作業を、2台のEAPに対して実行します。これで、EAPへの設定は完了です。ここまで出来たら、2台のEAPを起動しておきます。今回の環境ではEAP2台でクラスタ構成にしていますので、--server-config でHA用のプロファイルを指定し、さらに、-b / -bmanagement でIPアドレスを明示して、余計なIPでLISTENさせないようにします。

Webサーバー#1
EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -b 192.168.200.10 -bmanagement 192.168.122.10

Webサーバー#2
EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -b 192.168.200.20 -bmanagement 192.168.122.20

 

ここまで出来たら、後は、RH-SSOサーバー上でアプリケーション(SAML的にはクライアント)に関する設定を行って、実際のアプリケーション(WAR)にKeyCloak関連の設定をいれれば全て完了です。

RH-SSOサーバー上にて「Client」の作成

これからRH-SSO上に、SAML連携させるためのClient(つまりSP側、つまりアプリ側)に関する設定をします。

改めて、RH-SSOの管理コンソールにadminでログインを行って、画面左の「Clients」をクリックし、画面右の「Create」へと進みます。

f:id:daijik:20160627172850p:plain

すると、いくつか入力フォームが出てきますので、まずは、Client ID とClient Protocolを入れておきます。Client IDは任意です。Client Protocolは saml を選択します。

f:id:daijik:20160627173130p:plain

 セーブすると、さらに、設定項目が現れます。

f:id:daijik:20160627173646p:plain

沢山あるようですが、今回はポイントとなるところだけを設定します。

  1. Valid Redirect URIs: `http://192.168.150.15/app-profile-saml/*`
  2. Base URL: `http://http://192.168.150.15//app-profile-saml/`
  3. Master SAML Processing URL: `http://http://192.168.150.15//app-profile-saml/saml`
  4. Force Name ID Format: `ON`

 今回の環境では、ロードバランサ経由で実際のアプリケーションにアクセスしますので、その場合のアプリのURLを設定してやることが大切です。192.168.150.15というアドレスでロードバランサが受け付けてくれるように設定してあるので、それを意識した設定を入れておきます。

これでRH-SSO上へのClientの設定は完了です。

アプリケーション(WAR)への設定

WEBアプリケーションのSAML化まであと少しです。この後は、RH-SSOから、SAML認証に必要となる設定ファイルを生成し、それをWARファイル内に組み入れて全て完了となります。

keycloak-saml.xmlの生成

keycloak-saml.xmlというファイルがWEBアプリをSAML化する上で必要なのですが、これはRH-SSOを使って、生成します。

さきほど「Client」の作成をしましたが、作成したクライアントの設定画面を開いて、一番右側の「Installation」タブへ進みます。

f:id:daijik:20160627174452p:plain

フォーマット・オプションが選択出来るようになっているので、「KeyCloak SAML Adapter keycloak-saml.xml」を選択します。

すると、なにやら設定らしきものが自動生成されるので、それを保存します。このファイルをWARに組み入れてやればいいわけです。

keycloak-saml.xmlのWARファイルへの組み込み

細かい話をすると、ちょっと書き換えたりすることも必要なのですが、今回はあくまで実験なので、簡単にいきます。

keycloak-saml.xmlファイルはWEB-INFの直下に置いてください。それだけです。

web.xmlの編集

web.xmlでは、どのようなURLに対してどのような認証を行うか、という設定をします。今回は実験なので、全てのURLに対して、KEYCLOAK-SAMLで認証しますよ、という設定にします。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<security-constraint>
<web-resource-collection>
<web-resource-name>app</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>KEYCLOAK-SAML</auth-method>
</login-config>

<security-role>
<role-name>user</role-name>
</security-role>
<distributable/>
</web-app>

これで、必要な準備は全て完了!WARファイルが出来たら、起動してある2台のEAPサーバーにデプロイしましょう。

実際にアクセスしてみる 

では、実際にアクセスして動きをみてみます。その前に、どのように動いてくれたら嬉しいのかをイメージしておきます。

  • ロードバランサが待ち受けているIPめがけて、ブラウザでURLにアクセスする
  • 当然、未ログイン状態なので、RH-SSOサーバーにリダイレクトされる
  • RH-SSOサーバでログイン成功したら、再度アプリにリダイレクトされる
  • アプリにアクセス出来る。

 こうなってほしいわけです。

さっそくやってみます。ちなみに、私のアプリケーションは超〜シンプルなものでして、conter.jspというJSPファイルが一つ置いてあるだけです。というわけで、

http://192.168.150.15/app-profile-saml/counter.jsp というURLにアクセスしてみます。

f:id:daijik:20160627180126p:plain

すると、、、。

f:id:daijik:20160627180219p:plain

RH-SSOサーバーのログイン画面が出てきます。

ここで、先程作成したユーザーでログインします。すると、、、。

f:id:daijik:20160627180350p:plain

ログイン後、目的のJSPにアクセスすることが出来ました。期待どおりの動作です。ちなみに、このJSPは繰り返しアクセスをすると Counterの数字が一つ増えていくという単純なものです。

クラスタ環境ではどう動く?

これは興味本位でやってみたのですが、たとえば、今回の環境ではEAPクラスタ化されていますから、アクティブセッションを持っているEAPを止めてやっても、HTTPセッションは当然ながら引き継がれるはずです。では、SAMLによる認証関連の情報は引き継がれるのか?というのが、今回の関心事項です。

というわけで、上記JSPに何度かアクセス(ブラウザのリロード)し、counterを6まで増やしました。

f:id:daijik:20160627180817p:plain

そして、アクティブセッションを持っているEAPを停止します(Ctrl-Cなどで)。

で改めて、ブラウザをリロードします。

f:id:daijik:20160627180928p:plain

すると、Counterの値はHttpSessionのレプリケーションによって引き継がれますし、リロードした際に、再度、ログインを要求されることもありませんでした。念のため、RH-SSOサーバー(SAML IDP)のところでパケットキャプチャしながら動きを見てみたのですが、IDPへリダイレクトされる様子もみられませんでした。

ということは、EAPとKeyCloakのクライアントアダプタがうまいこと認証情報もクラスタ内で保持してくれている、ということだと思います。

 

というわけで、今回は、自分の勉強もかねて、KeyCloakによるSAML SSOを試してみました。ちょっと使うくらいであれば、特にハマったところも無いし、思ったより、簡単だったなという印象です。