AuthenticRoast を使用してコンテナー管理セキュリティーをカスタマイズする

JEE セキュリティー・モジュールの開発を単純化するオープンソース・プロジェクト

AuthenticRoast は Java Authentication Service Provider Interface for Containers (JSR 196) を扱うオープンソース・プロジェクトであり、AuthenticRoast を使用することで、コンテナーで管理する宣言型セキュリティー用のカスタム認証モジュールを開発することができます。この記事では、AuthenticRoast を使用することで JEE (Java Enterprise Edition) コンテナーの設定を最小限に抑えることができ、カスタムのセキュリティー要件を満たすためのコーディング作業を大幅に省くことができることを、著者である Joe Sam Shirah が明らかにします。デモ・コードは、この記事からダウンロード可能な WAR から入手することができます。

Joe Sam Shirah, Developer and Principal, conceptGO

Joe Sam ShirahJoe Sam Shirah は、conceptGO の代表兼開発者です。クライアントの要求を満足させるかたわら、developerWorks および Sun 開発者向けサイトに多数のチュートリアルを発表しています。Java Community Award の受賞者である彼は、developerWorks の Java Filter Forum のモデレーターでもあり、jGuru の JDBC、i18n、そして Java400 FAQs を管理しています。



2012年 2月 16日

先日、私の顧客から Web アプリケーションのセキュリティーをカスタマイズしてほしいという要望が 2 件ありました。顧客の一方は、IBM i を扱っている小売店で、ユーザーが各自の IBM i アカウントを使ってアプリケーションにアクセスできるようにしたいと望んでいました。もう一方の顧客は、既存のアプリケーションのセキュリティーを強化することを望んでおり、特定のユーザーについてはセキュアなデータベースで検証する一方、「通常」のユーザーについては既存の LDAP (Lightweight Directory Access Protocol) エントリーを使って検証できるようにしたいと考えていました。

これらのアプリケーションはいずれも、一般公開された Web ページではなく、ローカルで実行されるか、VPN (Virtual Private Network) 経由で実行される、企業の生産性アプリケーションです。一般にこのような環境では、コンテナー管理セキュリティーが有効に機能し、ページごとにクレデンシャルをチェックするためのフィルターなどを作成する負担がアプリケーションから取り除かれるものでした。けれども、これらのアプリケーションの新しい要件には問題がありました。それは、コンテナー管理セキュリティーは、通常は「レルム」つまり Apache Tomcat、IBM WebSphere、GlassFish などのコンテナーが提供するユーザー・データ・ソース・メカニズムによって動作することです。レルムとレルム実装はさまざまに異なり、それぞれのコンテナーに固有なものになりがちです。セキュリティーのカスタマイズを依頼されたアプリケーションは GlassFish の下で実行されますが、GlassFish では IBM i アカウントを利用するためのレルムや、1 つのレルムで複数の認証および承認の方式を実行するためのレルムを定義していません。

私が目標としたのは、最初にカスタムの方法でユーザーに対して認証および承認を行ってから、セキュリティー・チェックのタスクをコンテナー管理セキュリティーに引き渡せるようにすることです。この記事では、JAAS (Java Authentication and Authorization Service) および JSR 196 にソリューションを求め、その後、GNU Lesser General Public License の下でライセンス交付される AuthenticRoast プロジェクトを使用したソリューションに至った過程を紹介します。記事に付属のデモ用 WAR は、GlassFish で動作します (「ダウンロード」を参照)。記事ではまず始めにコンテナー管理セキュリティーについて簡単な概要を説明し、続いてフォーム・ベース認証に焦点を当てます。

コンテナー管理セキュリティーの概念

コンテナー管理セキュリティーとは、Java Servlet 仕様 (「参考文献」を参照) で概説されている宣言型セキュリティー機能を表す一般用語です。コンテナー管理セキュリティー機能がアプリケーションのニーズと合致する場合、プログラマーが行わなければならない面倒でエラーの原因となりがちなコーディング作業は大幅に減ります。また、複数のアプリケーションで一貫性のある認証および承認を行えるようにもなります。

ロール

「ロール」とは、ユーザー、管理者、またはアドミニストレーターなどの定義されたグループのことです。ユーザーは複数のグループのメンバーになることができます。ロールおよびグループは、ユーザーを個々に制御する場合と比べ、セキュリティーの管理およびプログラミングを大幅に単純化します。

コンテナー管理セキュリティーの基本的な考え方は、アプリケーションの外部でユーザーとロールを定義し、標準的な方法でクレデンシャルを取得できるようにするというものです。アクセスを制限する必要がある Web ページも同じく外部で定義し、承認されたユーザーまたはロールだけがアクセスできるようにします。コンテナー管理セキュリティーでは、宣言されたロールをページまたはページのグループにマッピングすることにより、アクセスを自動制御します。

Java Servlet 仕様で定義している認証には、以下の 4 つのタイプがあります。

  • HTTP 基本認証 (HTTP Basic Authentication)
  • HTTP ダイジェスト認証 (HTTP Digest Authentication)
  • HTTPS クライアント認証 (HTTPS Client Authentication)
  • フォーム・ベース認証 (Form Based Authentication)

この仕様では、JSR 196 として登録されている Java Authentication SPI for Containers (「参考文献」を参照) の「Servlet Container Profile」の章に記載されているサーブレット・コンテナー用プロファイルをアプリケーション・サーバーが実装することも強く推奨しています。

ユーザーが認証された後は、以下の HttpServletRequest メソッドを使用して、細かい粒度で特定のページ要素を制御することができます。

  • getRemoteUser()
  • getUserPrincipal()
  • isUserInRole(java.lang.String role)

設定

標準的なコンテナー管理セキュリティーに必要となる設定は、セキュリティー制約、セキュリティー・ロール、ログイン、そしてオプションでロール・マッピングの設定です。ログインに関する設定では、上記 4 つの認証タイプのいずれかを定義し、記述します。この後わかるように、AuthenticRoast はログインに関する設定の手間を省き、代わりに Authenticator として使用されるクラスによって適切な認証タイプを呼び出します。

Java Servlet 仕様の最新バージョンでは、セキュリティー制約を定義する方法として、アノテーションやその他のプログラムによる方法を導入していますが、ここでは web.xml ファイル内で宣言を使用してセキュリティー制約を定義します。その理由は、宣言はアプリケーションのデプロイヤーや管理者にとって馴染み深く、1 ヶ所にまとまっていて利用しやすいからです。この記事で使用されていない要素、サブ要素、および詳細については、「参考文献」を参照してください。

セキュリティー制約

web.xml ファイルの <security-constraint> 要素では、アクセスを制限するページと、これらのページへのアクセスが承認されるロールを宣言します。リスト 1 に一例を記載します。

リスト 1. <security-constraint> 要素
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Protected Pages</web-resource-name>
        <url-pattern>/protected/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>boss</role-name> 
        <role-name>mgr</role-name> 
        <role-name>user</role-name> 
    </auth-constraint>
</security-constraint>

<web-resource-collection> サブ要素は、アクセスを制限するリソースのコレクションに名前を付け、1 つ以上の <url-pattern> 要素をアクセス制限の対象として定義します。リスト 1 の例では、コレクションには「Protected Pages」という名前が付けられています。アクセスを制限するディレクトリー内にあるすべてのページには、<auth-constraint> サブ要素が適用されます。このサブ要素は、アクセスが承認されるロールの名前を示します。デモ・コードでそのロールに該当するのは、bossmgr、および user です。すべてのタイプの HTTP メソッド (GET、POST など) にも、デフォルトでこのセキュリティー制約が適用されることに注意してください。必要な場合には、特定の HTTP メソッドをセキュリティー制約の適用対象として含めることも、除外することもできます。

セキュリティー・ロール

リスト 2 に記載する <security-role> 要素は、リスト 1<auth-constraint> サブ要素に記載された各ロールのロール定義を指定します。

リスト 2. <security-role> 要素
<security-role> 
    <description>boss</description>
    <role-name>boss</role-name>
</security-role> 
<security-role> 
    <description>mgr</description>
    <role-name>mgr</role-name>
</security-role> 
<security-role> 
    <description>user</description>
    <role-name>user</role-name>
</security-role>

フォーム・ベース認証

フォーム・ベース認証では、コンテナー管理セキュリティー用に UI をカスタマイズすることができます。リスト 3 に記載するように、<form /> 要素には POST メソッドと、アクションとして j_security_check を指定する必要があります。また、この要素に j_usernamej_password という 2 つの <input /> 要素を含め、認証するユーザー ID、パスワードをそれぞれ指定する必要もあります。

リスト 3. フォーム・ベース認証を行う Web ページの最小要件
<form method="POST" action="j_security_check"> 
<input type="text" name="j_username"> 
<input type="password" name="j_password"> 
</form>

Web ページが上記の最小要件を満たしていれば、後はアプリケーションの標準に合わせて必要なものを何でも追加することができます。例えば、図 1 に示すデモ・コードのログイン・ページには、画像、ラベル、説明を表示するヘッダーが組み込まれています。

図 1. dwAuthenticRoastDemo ログイン・ページ
AuthenticRoast によるデモのログイン・ページを示すスクリーンショット

ログアウトは通常、セッションを無効化するという方法で実現します。無効化する代わりに、あるいは無効化することに加えて HttpServletRequest logout() メソッドを使用して、呼び出し元の ID をリセットすることもできます。

標準的なコンテナー管理セキュリティーでは、web.xml に <login-config /> エントリーも必要です (リスト 4 を参照)。

リスト 4. web.xml の <login-config /> エントリーの例
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>SomeRealmName</realm-name>
    <form-login-config>
        <form-login-page>/login.jsp</form-login-page>
        <form-error-page>/login-error.jsp</form-error-page>
    </form-login-config>
</login-config>

<login-config /> エントリーで定義するのは、認証方式とレルムです。この例ではフォーム・ベース認証方式を使用するため、このエントリーでは <form-login-config /> 要素を使用してログイン用およびエラー用のページを定義する必要があります。

アプリケーション・サーバーでサポートされているレルムのタイプがニーズを満たす場合、この設定は完璧に機能します。けれどもそうでない場合には、標準的なコンテナー管理セキュリティーは定義されたレルムに依存するという点が、実際的な問題となります。この行き詰まりを発端に、私のソリューション探しが始まりました。


JAAS の問題

Java SE のバージョン 1.4 に統合された JAAS は、認証および承認モジュールを開発するための下位レベルの API です (「参考文献」を参照)。プロジェクトのソリューションとして、私は真っ先に JAAS を思い付きました。JAAS は柔軟で、プラガブル・モジュールを可能にし、Java SE に標準装備されているためです。

残念ながら、JAAS の仕様が完成したのは、JEE セキュリティー・メカニズムが導入される前のことです。JAAS はスタンドアロンのアプリケーションには上手く機能するものの、JAAS にはサーブレットや JEE アプリケーションとの統合あるいはバインディングに関する標準はありません。また、JAAS は権限ロールのベースを複数のプリンシパルが含まれる javax.security.auth.Subject クラスに置いている一方、コンテナー管理セキュリティーは java.security.Principal クラスを使用して動作します。

統合に関する標準がないことから、サーブレットまたは JEE コンテナーのベンダーによる JAAS サポートはいずれも独自仕様です。ある意味、レルムにも同じ問題がありますが、私はより有用でより標準的なソリューションが他にない場合に限って、独自仕様の JAAS、つまり私が独自に改造した JAAS を使用することにしました。


JSR 196 は救いの手となるか

Java Authentication Service Provider Interface for Containers は JASPI や JASPIC と呼ばれることもありますが、それよりも JSR 196 という名前のほうが一般に知られています。JSR 196 の狙いは、カスタム認証メカニズムの設定を可能にする標準を指定し、この標準に準拠するコンテナーがカスタム認証メカニズムを使用して宣言型セキュリティーを実施できるようにすることです。JSR 196 では、サーブレットを含め、さまざまなコンテキストのプロファイルを定義しています。

私が JSR 196 について耳にしたのは 2004年に遡りますが、2007年に最終的なドラフトが公開されるまで、JSR 196 は Java Community Process のまま放置されていました。その一方、JEE リファレンス実装としての GlassFish は、少なくともバージョン 2.1 から JSR 196 の「Servlet Container Profile」の章に記載されているサーブレット・コンテナー用プロファイルをサポートしています。JEE 6 仕様 (「参考文献」を参照) には、JSR 196 が含まれているためです。

JSR 196 では、セキュリティーに関する一般用語や、明らかに関連する「Server Authentication Module (サーバー認証モジュール: SAM)」の概念に加え、「Message Authentication Modules (メッセージ認証モジュール)」や「Message Processing Runtimes (メッセージ処理ランタイム)」、そして「Java Authorization Contract for Containers (JACC または Java ACC)」などといった、ときにはうんざりするほど退屈なフレーズを数多く使用します。それでも私はこのプロセスを踏むことに前向きでしたが、それは、以下の 2 つの大きな問題に直面するまでの話です。

  • 個々の SAM を設定したら、その SAM を単にアプリケーションに統合するのではなく、効果的にコンテナーに統合しなければなりません。
  • JSR 196 を実装する例 (JSR 196 の技術リーダーによる Enterprise Tech Tip 「Adding Authentication Mechanisms to the GlassFish Servlet Container」(「参考文献」を参照) など) に記載されているすべてのステップに従うとなると、大変な作業量になります。

できれば JSR 196 のメソッドを使用したいと思っていましたが、それには SAM の実装に伴う影響と作業を最小限にする手段が必要でした。再び広範に調査した結果、私とまったく同じ目的を持つオープンソースのプロジェクトが見つかりました。


AuthenticRoast

この記事を執筆している時点で、AuthenticRoast プロジェクト (「参考文献」を参照) からリリースされているバージョンは 0.3.3 ですが、このプロジェクトはこれまで 3 年以上、本番環境で使用されてきました。私の 2 つのプロジェクトでは、それぞれ 2 年間、1 年間にわたってこのプロジェクトを使用しています。

AuthenticRoast は、3 つの主要な JAR で構成されています。これらの JAR の役割は、以下の 2 つに分けることができます。

AuthenticRoast で扱えるコンテナー

AuthenticRoast は、GlassFish 2.x/3.x および Tomcat 6 を使用してテストを行っています (Tomcat には JSR 196 のネイティブ・サポートが組み込まれていないため、Tomcat を使用する場合は AuthenticRoast をバルブとして Tomcat に登録し、内部呼び出しを使用します)。GlassFish (つまり JSR 196 に対応したコンテナー) でテストされていることから、AuthenticRoast は WebSphere 8 をはじめとする JEE 6 準拠のあらゆるコンテナーで使用できるはずですが、GlassFish 以外のサーバーで使用しているというレポートがインターネットに公開されているのを見たことはありません。

AuthenticRoast を GlassFish 以外のコンテナーで使用するためには、この記事で説明している内容のうち少なくとも GlassFish の「Message Security Configurations (メッセージセキュリティー設定)」ページでセキュリティー・プロバイダーの基本モジュールを設定する処理と、glassfish-web.xml 内で glassfish-web-app 要素の httpservlet-security-provider 属性にセキュリティー・プロバイダーを指定する部分を、その使用するコンテナーに該当する内容に置き換える必要があります。WebSphere の場合、アプリケーションとセキュリティー・プロバイダーを関連付けるには、WebSphere の管理コンソール上でのデプロイメント・ステップで「Map JASPI Provider (JASPI プロバイダーをマップ)」オプションを使用します (「参考文献」を参照)。

別のコンテナーを使用して AuthenticRoast を統合する場合には、他の開発者の参考となるように、統合プロセスを AuthenticRoast のプロジェクト・リーダーに提供することを検討してください。

  • AuthenticRoast-API-<バージョン番号>.jar および AuthenticRoast-Impl-<バージョン番号>.jar: コンテナーとの統合は避けられない作業ですが、これらの JAR は以下の役割を果たします。
    • コンテナーの設定を 1 回行えば済むようにします。
    • コンテナーと、アプリケーションのセキュリティー・モジュール (認証子) との間で橋渡しをします。
  • AuthenticRoast-Extras-<バージョン番号>.jar: xxxx-Extras という追加ファイルのような名前にも関わらず、(カスタム・コードを作成しない限り) ほとんどのアプリケーションでこの JAR を使用することになります。このファイルには、コンテナー管理セキュリティーで使用できる、各種の認証方式に応じた以下の抽象クラスがあるからです。
    • BasicAuthenticator
    • CompositeAuthenticator
    • FormAuthenticator
    • SSLClientAuthenticator
    • TicketAuthenticator

この記事の残りとデモ・コードでは、FormAuthenticator クラスを GlassFish 3.1.1 で使用する方法を説明します。

AuthenticRoast による認証の開発プロセスには、以下の 4 つの内容が関係します。

  • コンテナーの設定
  • アプリケーションの設定
  • 認証子の登録
  • 認証子のコード

上記の内容について、順に説明します。


コンテナーの設定

幸いなことに、AuthenticRoast におけるコンテナー (この例の場合は GlassFish) の設定は 1 回限りのタスクです。この設定手順については、このプロジェクトのウィキの「InstallationForGlassfish」ページ (「参考文献」を参照) の説明が非常にわかりやすいので (また、設定手順が将来変更される可能性もあることから)、このページに任せることにします。ただし、説明されている手順は GlassFish 2.x を対象としているため、GlassFish 3.1.1 を設定する場合に異なる点を図 2 から図 5 に示しておきます。設定プロセスを開始する前に必ず、AuthenticRoast-API-<バージョン番号>.jar と AuthenticRoast-Impl-<バージョン番号>.jar を GlassFish がインストールされているディレクトリーの lib フォルダーにコピーして、サーバーを再起動してください。

図 2 に示されているように、「Message Security (メッセージセキュリティー)」をクリックすると、すでに「HttpServlet」認証層があることがわかります。「HttpServlet」をクリックしてください。

図 2. GlassFish 3.1.1 の「Message Security Configurations (メッセージセキュリティー設定)」ページ
GlassFish 3.1.1 の「Message Security Configurations (メッセージセキュリティー設定)」ページを示すスクリーンショット

すると、図 3 に示す「Edit Message Security Configuration (メッセージセキュリティー設定の編集)」ページが表示されます。

図 3. GlassFish 3.1.1 の「Edit Message Security Configuration (メッセージセキュリティー設定の編集)」ページ
GlassFish 3.1.1 の「Edit Message Security Configuration (メッセージセキュリティー設定の編集)」ページを示すスクリーンショット

Providers (プロバイダ)」タブをクリックします。

図 4 に、「HttpServlet」認証層がすでに存在している理由が示されています。それは、GlassFish 管理コンソール自体がセキュリティーにプロバイダーを使用しているからです。この画像には、私が作成した「roast」プロバイダーも示されています。「New (新規)」ボタンをクリックして、このプロバイダーを追加してください。

図 4. GlassFish 3.1.1 の「Provider Configurations (プロバイダ設定)」ページ
GlassFish 3.1.1 の「Provider Configurations (プロバイダ設定)」ページを示すスクリーンショット

図 5 に、「roast」プロバイダーのエントリーを示します。これらのエントリーは、AuthenticRoast のウィキの「InstallationForGlassfish」ページに記載されているものと同じです。ページの下のほうにある「Response Policy (応答ポリシー)」フィールド (図 5 には表示されていません) は、何も選択せずに空のままにしておいてください。

図 5. GlassFish 3.1.1 の「Edit Provider Configuration (プロバイダ設定の編集)」ページ
GlassFish 3.1.1 の「Edit Provider Configuration (プロバイダ設定の編集)」ページを示すスクリーンショット

必ず設定を保存して、サーバーを再起動してください。このプロセスが完了すると、アプリケーションで AuthenticRoast を使用できるようになります。


アプリケーションの設定

AuthenticRoast を使用するアプリケーションの web.xml ファイルは、リスト 1リスト 2 に記載したコンテナー管理セキュリティーの標準的な設定内容に従います。ただし、注目すべき唯一の例外として、AuthenticRoast では、リスト 4 に記載した <form-login-config /> は必要もなければ、使用されることもないという点が挙げられます

次のセクションを読むとわかりますが、AuthenticRoast を使用する場合には、認証子をコンテナーに登録しなければなりません。このタスクは通常、アプリケーションのリスナーによって行われます。リスト 5 に、デモ・アプリケーションのリスナーを定義するエントリーを記載します。

リスト 5. web.xml 内でアプリケーションのリスナーを定義するエントリー
<listener>
  <listener-class>com.dw.ARDAppInit</listener-class>
</listener>

この他にアプリケーションの設定に必要な内容として、アプリケーションが httpservlet セキュリティー・プロバイダーを使用することをコンテナーに通知することが最後に挙げられます。このタスクは、コンテナー固有の glassfish-web.xml ファイル (GlassFish 3.x より前では、sun-web.xml という名前になっています) で、<glassfish-web-app /> 要素の httpservlet-security-provider 属性に、定義されているプロバイダー ID と一致するエントリー (roast) を設定することで実現されます。

<glassfish-web-app httpservlet-security-provider="roast" error-url="">

ロール・マッピングはオプションですが、便利な JEE 機能です。デプロイヤーはロール・マッピングによって、アプリケーションで使用されているグループやロールと、デプロイメント・サイトのグループやロールをマッピングすることができます。残念ながら、ロール・マッピングのエントリーとロケーションはコンテナーによって異なります。例えば、WebSphere では ibm-application-bnd.xml を使用する一方、GlassFish ではロール・マッピングにも glassfish-web.xml を使用します。リスト 6 に、アプリケーションで使用する <role-name /> 要素をデプロイメント・サイトに固有の <group-name /> にマッピングするためのエントリーを記載します。

リスト 6. glassfish-web.xml でのロール・マッピング
<security-role-mapping>
    <role-name>boss</role-name>
    <group-name>ARDBoss</group-name>
</security-role-mapping>
<security-role-mapping>
    <role-name>mgr</role-name>
    <group-name>ARDMgr</group-name>
</security-role-mapping>
<security-role-mapping>
    <role-name>user</role-name>
    <group-name>ARDUser</group-name>
</security-role-mapping>

コンテナーはこのエントリーによって、例えばデモ・アプリケーションが boss をチェックするときには、ARDBoss ロールが boss に相当することを保証します。


認証子の登録

ARDAppInit は、リスト 5 で定義したデモ・コードのアプリケーション・リスナーです。リスト 7 を見るとわかるように、このリスナーはアプリケーションの起動時に、contextInitialized() メソッドを使用して認証子クラスのインスタンスを登録します。

リスト 7. デモ・コードの認証子の登録
package com.dw;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import name.aikesommer.authenticator.Registry;
...
public class ARDAppInit implements ServletContextListener
{
  ...
  public void contextInitialized( ServletContextEvent sce )
  {
    ServletContext sc = null;

    sc = sce.getServletContext();
    // register AuthenticRoast authenticator
    Registry.forContext( sc ).register( new ARDFormAuthenticator() );

    System.out.println( "[ARDAppInit Executed]" );

  } // end contextInitialized

} // end class ARDAppInit

上記のコードは、どのアプリケーションでも基本的に同じです。通常は、認証子インスタンスのパッケージ名とセットアップだけが異なります。


認証子のコード

ここまでの説明、設定、およびセットアップを考えると、通常は以下の点に対処するだけで、独自のカスタム・コードを使ったフォーム・ベース認証を有効にすることができることは、予想外の喜びとなるはずです。

  • SearchComponent クラスの継承
  • FormAuthenticator クラスの最大 4 つ (通常は 2 つだけ) のメソッドのオーバーライド
  • SimplePrincipal クラスに関するわずかな情報の取得

FormAuthenticator クラス (AuthenticRoast-Extras-<バージョン番号>.jar 内) が継承する PluggableAuthenticator は、SimplePrincipal と一緒に AuthenticRoast-API-<バージョン番号>.jar に格納されています。コンテナーは AuthenticRoast を介して、クラス・インスタンスのメソッドを呼び出します。

ログイン・ページには login.jsp という名前を、ログイン・エラー・ページには login-error.jsp という名前をそのまま使用するので構わなければ、FormAuthenticator クラスの 2 つのメソッドに対処すればよくなります。そうでない場合は、String getErrorPage() および String getLoginPage() をオーバーライドして、この 2 つのページの名前としてお望みの名前が返されるようにしてください。

以下の 2 つのメソッドは、必ずオーバーライドする必要があります。

  • boolean checkCredentials(AuthenticationManager manager, AuthenticationRequest request, String username, String password)

    checkCredentials() メソッドは、渡されたクレデンシャル、つまりユーザー名とパスワードを検証します。クレデンシャルに問題がなければ true を返し、そうでない場合は false を返します。

  • SimplePrincipal loadPrincipal(AuthenticationManager manager, AuthenticationRequest request, String username)

    loadPrincipal() メソッドは、有効なユーザーであることを示す truecheckCredentials() メソッドが返した場合にのみ呼び出されます。loadPrincipal() メソッドが返すのは、SimplePrincipal (基本的にユーザー名) とグループ名の Set です。コンストラクターはユーザー名と、そのユーザーに関連付けられたグループまたはロールの名前から成る String 配列を取ります。コンテナーは、web.xml の <auth-constraint> 要素に記載されたロール (リスト 1 を参照)、またはマッピングされたロール (リスト 6 を参照) とマッチするグループ名を検索します。リスト 8 に、SimplePrincipal をロードする例を記載します。

    リスト 8. 静的配列を使用した SimplePrincipal のロード
    String[] asBossGroups = 
              { "ABCBoss", "ARDBoss", "MVBoss", "RSBoss" }; 
    
    SimplePrincipal sp = new SimplePrincipal( "bossLady", asBossGroups );

上記 2 つのメソッドは、初期状態はステートレスであり、関連を持たないことに注意してください。そのため大抵は、ユーザー・データおよびグループ・データへのアクセスがそれぞれのメソッドで繰り返される結果となります。もちろんコードを追加することで、この状況を変えることはできますが、そのまま使用するとステートレスであることは認識しておく必要があります。

認証子コードのフレームワークは、まさにこれだけです。同意してもらえると思いますが、たった 2 つのメソッドで (通常は) 動作するプロジェクトは、これ以上ないほど単純です。


デモ・アプリケーションについて

この記事に付属のデモ・アプリケーション (「ダウンロード」を参照) は、AuthenticRoast を使用する具体的な例となっています。ログイン検証用のページを除き、このアプリケーションにはアクセスが制限されたディレクトリー内に 1 つのページがあるだけです。このページは単に、getRemoteUser()getUserPrincipal()、および isUserInRole(java.lang.String role) の呼び出し結果を表示するだけに過ぎません (図 6 を参照)。

図 6. ログインの結果を示すページ
AuthenticRoast によるデモのログインの結果を示すページのスクリーンショット

checkCredentials() メソッドが受け入れるユーザー/パスワードのセットには、以下の 3 つがあります。

  • ユーザー stevie、パスワード user1
  • ユーザー ray、パスワード mgr1
  • ユーザー vaughan、パスワード boss1

渡されたクレデンシャルの有効性が確認されると、ユーザー名とそのユーザー名に関連付けられた以下のグループ名の配列が、SimplePrincipal オブジェクトの loadPrincipal() メソッドから返されます。

  • ユーザー stevie の場合は asUserGroups
  • ユーザー ray の場合は asMgrGroups
  • ユーザー vaughan の場合は asBossGroups

リスト 9 に、配列の内容を記載します。

リスト 9. ARDFormAuthenticator が使用するグループ配列
  private static String[] asBossGroups = 
          { "ABCBoss", "ARDBoss", "MVBoss", "RSBoss" }; 
  private static String[] asMgrGroups = 
          { "ABCMgr", "ARDMgr", "MVMgr", "RSMgr" }; 
  private static String[] asUserGroups = 
          { "ABCUser", "ARDUser", "MVUser", "RSUser" };

ロール・マッピングを含め、残りのコードと設定のほとんどは、リスト 1 からリスト 7 に記載されているとおりです。ただし例外として、上記で説明したようにリスト 4 に記載した <login-config /> 要素は、AuthenticRoast では不要であり、使用されることもありません。


まとめ

コンテナー管理セキュリティーのためのカスタム・モジュールは頻繁には必要になりませんが、必要となった場合、カスタム・モジュールは非常に重要な意味を持つはずです。JSR 196 は、カスタマイズされた宣言型セキュリティーを統合するという目的を果たしたものの、それに伴う犠牲として、非常に面倒で複雑なプロセスになることがあります。そのプロセスを単純化するのが、AuthenticRoast プロジェクトです。

AuthenticRoast の主要な利点である「完全に制御できる」という側面は、同時に最大の欠点でもあることを覚えておいてください。それは、何もかも自分でやらなければならないからです。例えば、私は以前、パスワードとグループ・データに関しては、GlassFish の LDAP レルムを使って Microsoft Active Directory にアクセスしていましたが、それには、ストリングを検索するための定型のコードを作り上げる必要がありました。また、AuthenticRoast を使用して、LDAP のクレデンシャルが認証に失敗した場合の検証プロセスを追加する際には、自分で LDAP アクセス・コードを調べて作成しなければなりませんでした。

けれどもこのような欠点は、JSR 196 を直接扱う場合や、カスタム・セキュリティー・モジュールを作成するどんな場合にも当てはまります。突き詰めるところ、AuthenticRoast は、JEE コンテナーの設定を最小限に抑えることと、カスタム・セキュリティー要件を満たすためのコーディング作業を大幅に減らすことに成功したオープンソース・ソリューションということになります。


ダウンロード

内容ファイル名サイズ
Demonstration WAR for this article1j-authenticroast.zip86KB

  1. The Java sources are included in the WAR file. For instruction on using the WAR file, see the readme.txt file included with the download.

参考文献

学ぶために

製品や技術を入手するために

  • AuthenticRoast: AuthenticRoast をダウンロードしてください。
  • GlassFish: GlassFish アプリケーション・サーバーの情報およびダウンロードを調べてください。
  • WebSphere Application Server for Developers: 無料の WebSphere オファリングをダウンロードしてください。これは、最終的にアプリケーションを実行するランタイム実稼動環境とまったく同じです。
  • ご自分に最適な方法で IBM 製品を評価してください。評価の方法としては、製品の試用版をダウンロードすることも、オンラインで製品を試してみることも、クラウド環境で製品を使用することもできます。また、SOA Sandbox では、数時間でサービス指向アーキテクチャーの実装方法を効率的に学ぶことができます。

議論するために

  • developerWorks コミュニティーに参加してください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者が主導するブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology, Open source
ArticleID=792436
ArticleTitle=AuthenticRoast を使用してコンテナー管理セキュリティーをカスタマイズする
publish-date=02162012