ここのところ
OpenSSO絡みの話が多いので、
もう少し詳しく勉強してみようと
SDCで工藤さんが書いた記事を参考に、OpenSSOのアイデンティティ・サービスを
利用したカスタムのログイン処理を実装してみました。
工藤さんはRuby on Railsでやってましたが、私はJavaer (Javaistではないです...) なのでServletフィルタで
ログイン処理を実装し、NetBeansで作成したVisual Webアプリにセットするという
アプローチです。
で、実装ですが、まずは工藤さんの記事で紹介されている
OpenSSOFilter.javaと
OpenSSOUtil.javaの中身を眺め、今回は超お手軽に実装ということで、
OpenSSOUtil.javaをほぼそのまま使ってフィルタ本体を以下のように簡易実装しました。
private String serviceUrl = "http://sp.example.net:9090/opensso-sp";
public void doFilter(ServletRequest xRequest, ServletResponse xResponse,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) xRequest;
HttpServletResponse response = (HttpServletResponse) xResponse;
if (isAuthenticated(request)) {
try {
chain.doFilter(request, response);
} catch (Throwable t) {
problem = t;
t.printStackTrace();
}
} else {
response.sendRedirect(serviceUrl + "/UI/Login?goto=" +
request.getRequestURL().toString());
}
}
内容は簡単なので特に説明は不要だとは思いますが念のため書いておくと、
isAuthenticated()でクッキーからトークンを取得してバリデーションする
処理が走り、認証されればWebアプリ本体へ処理を渡し、認証されなければ
gotoで戻り先を指定してOpenSSOにリダイレクトします。文章でさらっと書いて
しまいましたが、isAuthenticated()の中身は
OpenSSOUtil.javaを見てください。
NetBeansのVisual Webアプリケーションのプロジェクトでアプリとフィルタを
作っていったのですが本当に簡単ですね。
今回は
OpenSSOUtil.javaからアイデンティティ・サービスをRESTで使ってみた
のですが、NetBeansでアイデンティティ・サービスのWSDLを読み込んでWebサービス
クライアントを自動作成し、さらにソースコードエディタ上で右クリックして
Webサービス呼び出し部分のコードのテンプレートを自動作成してしまえば
SOAP呼び出しも簡単に実装することができます。
後でSAML 2.0のフェデレーションも試してみたかったので、工藤さんの
こちらと
こちらの
記事を参考にOpenSSOの環境を事前にセットアップし、完成したWebアプリをデプロイして動作を確認します。
NetBeansを使えばビルドからデプロイもとても簡単です。
ブラウザでURLを入力すると、OpenSSOのID/パスワード入力画面が表示され、
認証された後にWebアプリにアクセスが可能になります。認証されなければ
Webアプリにアクセスできません。更に、別のWebアプリを作って、こちらにも
フィルタをセットしてデプロイすれば、お手軽シングルサインオン環境が完成です。
あたりまえの動作ですが、こんな簡単でいいの?というのが実感ですね。
通常のWebアプリではOpenSSOが提供するポリシーエージェントを使えば
カスタムな認証部分を作らなくて済むケースがほとんどだと思いますが、
例えば、これまでの社内標準化の取り組みで認証基盤を独自に手作りして使ってきたような
ケースでは、OpenSSOのアイデンティティ・サービスをうまく使って既存の
認証基盤をOpenSSO配下に統合していくようなアプローチは有効だと思います。
一旦、OpenSSO配下に入ってしまえば、OpenSSOが提供する機能を利用して、
他のIDPとのフェデレーションであったり、WindowsログオンでのSSO、
いわゆるWindowsデスクトップ・シングル・サインオンの機能を実現したり、
今後の展開の可能性を大きく広げることができます。
OpenSSOが機能を提供している認証/認可の技術エリアは、アイデンティティ情報を管理する側と、
管理されたアイデンティティ情報をベースにサービスを提供する側の接点となり、
両側の思惑がぶつかる部分ですので、将来的に柔軟な対応が可能な作りにしておくことが
とても重要だと思います。
最近、認証/認可に関するエリアの話が多くなってきているのですが、時々、
OpenID vs OpenSSO (正確にはOpenID vs SAML 2.0だと思いますが...) のような
話され方をしてしまうのは残念に思います。決して相反するものではなく、
互いに補完しあえるものだと思います。RubyとJavaのように。事実、OpenSSOでは
OpenIDのextentionでOpenIDのOPを実現することも可能になっていますからね。
さぁ、次はフェデレーションにチャレンジだ。