HomeDocumentation > 9. サンプル・アプリケーション > 9.j. ウェブ・アプリケーション セキュリティ・サンプル

この文章では、Apache Geronimo サーバーの機能に関連したウェブ・アプリケーションのセキュリティーに注目します。この文章のサンプル・アプリケーションは、サーブレット、JSP や J2EE の宣言的セキュリティーを利用する基本的な Time Reporting システムについて書かれています。上記セキュリティーの機能に加えて、Geronimo に組み込まれている Derby データベースをこのシステムのユーザー情報保存のために利用しています。このアプリケーションはユーザー情報保持のためにデータベースを使いますが、これは単に構成の目的で利用しています。Geronimo での JDBC の利用方法の詳細情報は、 9.b. データベース接続の簡単なサンプル・アプリケーション を参照してください。

この文章を読めば、宣言的セキュリティー機能を利用したウェブ・アプリケーションのための Geronimo アプリケーションサーバーの構成が可能になるでしょう。

この文章は、次のセクションで構成されています。

Geronimo のウェブ・アプリケーション

Apache Geronimo は J2EE ウェブ・アプリケーションをサポートするウェブ・アプリケーションコンテナを持っています。ウェブ・コンテナ自身は、通信ポートや SSL オプションなどの基本構成をサポートしています。ウェブ・アプリケーションは Geronimo 仕様の構成情報も含むことができます。ウェブ・アプリケーションを Geronimo のセキュリティー機構に参加させることができます。ウェブ・アプリケーションを認証することで、セキュアな EJB やコンテナにアクセスすることができます。

Apache Geronimo は現在、次の2つのウェブ・コンテナをサポートしています: Jetty, Tomcat

Jetty

Jetty は 100% Java の HTTP サーバー、サーブレット・コンテナ です。したがって、サーブレットや JSP を利用して動的にコンテンツを生成するために、別のウェブサーバーを設定したり実行する必要はありません。Jetty は静的、動的コンテンツを扱うすべての機能をもったウェブサーバーです。

サーバとコンテナが分離された方法とは違い、Jetty のウェブサーバーとウェブ・アプリケーションは同じプロセス上で実行されるので、内部通信のオーバーヘッドや複雑さがありません。さらに、ピュア Java コンポーネントなので Jetty は簡単に貴方のアプリケーションのデモンストレーションや配布、配備に利用できます。Jetty は Java をサポートするすべてのプラットフォームで利用できます。
http://jetty.mortbay.org/jetty/index.html

Tomcat

Apache Tomcat は Java サーブレット、JavaServer Pages 技術の公式リファレンス実装として利用されているサーブレット・コンテナです。
http://tomcat.apache.org/

アプリケーションの概略

Time Reporting アプリケーションは、各プロジェクトの従事時間の報告をするものです。 大きなアプリケーションではありませんが、Apache Geronimo の持つ表示とセキュリティとの関連機能を含んでいます。

このサンプル・アプリケーションでの時間報告作業には「マネージャー(managers)」「従業員(employees)」の2種類のユーザグループがあります。両方のユーザとも時間報告作業前に自身の証明をする必要があります。マネージャーはこのシステムの特権ユーザですので、従業員を追加することができます。

Time Reporting アプリケーションには以下のページがあります。

  • Welcome
  • Login
  • Time Report
  • Add Employees
  • Logout

次の図はアプリケーションの流れの概略です。

デフォルトのサンプル・アプリケーションは Time Reporting の機能へのリンクを持つ Welcome ページを表示します。利用者は Login ページで有効なユーザー名とパスワードを入力することで Time Report ページを表示できます。このユーザーの認証によりマネージャーの役割が認められると、Time Report ページには Add Employees 機能へのリンクが追加されて表示されます。

アプリケーションの内容

以下に Time Reporting アプリケーションの主要なフォルダーの階層構成を示します。アプリケーションで利用する JSP と構成ファイルがあります。

|- employee
     |- index.jsp
|- login
     |- login.jsp
     |- login_error.jsp
     |- logout.jsp
|- manager
     |- index.jsp
|- WEB_INF
     |- geronimo-web.xml
     |- web.xml
|- index.jsp

上記の JSP と構成ファイルに加えて、このアプリケーション用ビジネス・ロジックをもつ2つのサーブレットが必要です。

  • AddTimeRecordServlet - Read the input data from the Time Report page
  • AddEmployeeServlet - Capture input information from Add Employee page
  • AddTimeRecordServlet - Time Report ページで入力されたデータを読み込む
  • AddEmployeeServlet - Add Employee ページで入力された情報を取得する

Time Reporting アプリケーションのセキュリティ構成は geronimo-web.xmlweb.xml ファイルによって扱われています。geronimo-web.xml は TimeReportRealm としてユーザーの役割を定義しています。

geronimo-web.xml の最初の部分はわかりやすいのですが、セキュリティ構成は手が込んでいます。 <security-realm-name> は <security> 要素内の一連の <realms> 要素の定義に利用されています。

web.xml のセキュリティ・ロール(security roles)の記述によって、geronimo-web.xml はユーザーやグループがどの Geronimo セキュリティー・レルムに所属しているかを割り当てます。ログインしていないユーザーには、<default-principal> 要素によって定義された realm が付与されます。

本プロジェクトには マネージャー(manager) と 従業員(employee) という2つの役割があります。マネージャーは会社の従業員でもありますので、employee としても登録され、さらに manager にも登録されています。

geronimo-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
	xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">

	<environment>
		<moduleId>
                        <groupId>${pom.groupId}</groupId>
                        <artifactId>${pom.artifactId}</artifactId>
                        <version>${version}</version>
                        <type>war</type>
		</moduleId>
	</environment>

	<context-root>/timereport</context-root>

	<security-realm-name>TimeReportRealm</security-realm-name>

	<security>
		<default-principal realm-name="TimeReportRealm">
			<principal name="anonymous"
				   class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"
				   />
		</default-principal>
		<role-mappings>
			<role role-name="employee">
				<realm realm-name="TimeReportRealm">
					<principal name="EmployeeGroup"
					   class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"
				   	/>
				</realm>
				<realm realm-name="TimeReportRealm">
					<principal name="ManagerGroup"
					   class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"
					/>
				</realm>
			</role>
			<role role-name="manager">
				<realm realm-name="TimeReportRealm">
					<principal name="ManagerGroup"
					   class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"
					/>
				</realm>
			</role>
		</role-mappings>
    </security>

</web-app>

web.xml はユーザーの役割をウェブ・アプリケーションのリソースに割り当てます。また、アプリケーションのログイン構成も定義しています。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	 version="2.4">

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
  	</welcome-file-list>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>employee</web-resource-name>
			<url-pattern>/employee/*</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<role-name>employee</role-name>
		</auth-constraint>
	</security-constraint>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>manager</web-resource-name>
			<url-pattern>/manager/*</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<role-name>manager</role-name>
		</auth-constraint>
	</security-constraint>

	<login-config>
		<auth-method>FORM</auth-method>
		<realm-name>TimeReportRealm</realm-name>
		<form-login-config>
			<form-login-page>/login/login.jsp</form-login-page>
			<form-error-page>/login/login_error.jsp</form-error-page>
		</form-login-config>
	</login-config>

	<security-role>
		<role-name>employee</role-name>
    	</security-role>
	<security-role>
		<role-name>manager</role-name>
    </security-role>

    <servlet>
	    <display-name>AddTimeRecordServlet</display-name>
	    <servlet-name>AddTimeRecordServlet</servlet-name>
	    <servlet-class>org.apache.geronimo.samples.timereport.web.AddTimeRecordServlet</servlet-class>
  	</servlet>
  	<servlet>
	    <display-name>AddEmployeeServlet</display-name>
	    <servlet-name>AddEmployeeServlet</servlet-name>
	    <servlet-class>org.apache.geronimo.samples.timereport.web.AddEmployeeServlet</servlet-class>
  	</servlet>

  	<servlet-mapping>
	    <servlet-name>AddTimeRecordServlet</servlet-name>
	    <url-pattern>/employee/add_timerecord</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
	    <servlet-name>AddEmployeeServlet</servlet-name>
	    <url-pattern>/manager/add_employee</url-pattern>
    </servlet-mapping>

</web-app>

Time Report ページから Add Employee 機能への遷移を規制するために、以下のようなプログラムによる認証を利用しています。

employee/index.jsp
...
<BR>
<%if(request.isUserInRole("manager")){%>
<A href="../manager/">Add Employees</A>
<BR>
...

geronimo-application.xml はデプロイする必要のあるデータベース・プールをアプリケーションに通知します。セキュリティー・レルム構成はデータベース・プールと一緒に含まれています。データベース・プールは TimeReportPool.xml に定義されています。また、ドライバーとして tranql-connector-ra-1.3.rar ファイルをデプロイする必要があることが記述されています。これら2つのファイルは生成された EAR ファイル内の最上位階層に置きます。

geronimo-application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.2">

    <environment xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
        <moduleId>
            <groupId>${pom.groupId}</groupId>
            <artifactId>${pom.artifactId}</artifactId>
            <version>${version}</version>
            <type>ear</type>
        </moduleId>
    </environment>

    <module>
        <connector>tranql-connector-ra-1.3.rar</connector>
        <alt-dd>TimeReportPool.xml</alt-dd>
    </module>
</application>

TimeReportPool.xml には2つの内容が定義されています。 データベース・プールとセキュリティー・レルムです。以下に示すように、最初の部分は他のデータベース・プールと似ています。次の部分には、必須のセキュリティー・レルム計画があります。この2つの内容をひとつの独立したファイルに入れることによって、アプリケーションにデータベース・プールとセキュリティー・レルムを入れて出荷でき、インストール時の作業を軽減するでしょう。

TimeReportPool.xml
<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2">
    <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
        <dep:moduleId>
            <dep:groupId>console.dbpool</dep:groupId>
            <dep:artifactId>TimeReportPool</dep:artifactId>
            <dep:version>1.0</dep:version>
            <dep:type>rar</dep:type>
        </dep:moduleId>
        <dep:dependencies>
            <dep:dependency>
                <dep:groupId>org.apache.geronimo.configs</dep:groupId>
                <dep:artifactId>j2ee-security</dep:artifactId>
                <dep:type>car</dep:type>
            </dep:dependency>
            <dep:dependency>
                <dep:groupId>org.apache.geronimo.configs</dep:groupId>
                <dep:artifactId>system-database</dep:artifactId>
                <dep:type>car</dep:type>
            </dep:dependency>
        </dep:dependencies>
    </dep:environment>
	<!--db pool fragment-->
    <resourceadapter>
        <outbound-resourceadapter>
            <connection-definition>
                <connectionfactory-interface>javax.sql.DataSource</connectionfactory-interface>
                <connectiondefinition-instance>
                    <name>TimeReportPool</name>
                    <config-property-setting name="Driver">org.apache.derby.jdbc.EmbeddedDriver</config-property-setting>
                    <config-property-setting name="UserName">app</config-property-setting>
                    <config-property-setting name="ConnectionURL">jdbc:derby:TimeReportDB</config-property-setting>
                    <connectionmanager>
                        <local-transaction/>
                        <single-pool>
                            <max-size>10</max-size>
                            <min-size>0</min-size>
                            <match-one/>
                        </single-pool>
                    </connectionmanager>
                </connectiondefinition-instance>
            </connection-definition>
        </outbound-resourceadapter>
    </resourceadapter>
	<!--security realm fragment-->
	<gbean name="TimeReportRealm" class="org.apache.geronimo.security.realm.GenericSecurityRealm">
		<attribute name="realmName">TimeReportRealm</attribute>
		<reference name="ServerInfo">
			<name>ServerInfo</name>
		</reference>
		<xml-reference name="LoginModuleConfiguration">
			<log:login-config xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-1.1">
				<log:login-module control-flag="REQUIRED" wrap-principals="false">
					<log:login-domain-name>TimeReportRealm</log:login-domain-name>
					<log:login-module-class>org.apache.geronimo.security.realm.providers.SQLLoginModule</log:login-module-class>
					<log:option name="jdbcDriver">org.apache.derby.jdbc.EmbeddedDriver</log:option>
					<log:option name="jdbcUser">app</log:option>
					<log:option name="userSelect">select userid, password from users where userid=?</log:option>
					<log:option name="groupSelect">select userid, groupname from usergroups where userid=?</log:option>
					<log:option name="jdbcURL">jdbc:derby:TimeReportDB</log:option>
				</log:login-module>
			</log:login-config>
		</xml-reference>
	</gbean>
</connector>

ツールの利用

Time Reporting サンプル・アプリケーションの開発、構築に利用したツールは以下のとおりです。

Apache Maven 2

Maven はエンタープライズ Java プロジェクト向けの有名なオープンソースのビルドツールです。 ビルド作業の負荷を軽減できるように設計されました。Maven では Ant や他の伝統的な make ファイルなどで利用されるタスク・ベースの手法ではなく、宣言的手法を利用して、プロジェクトの構成や内容が定義されます。このことにより、企業全体で開発標準を適用することや、ビルド用スクリプトの記述やメンテナンスに必要な時間を削ることの助けとなります。宣言的で、ライフサイクルに基づく手法を使っていた Maven 1 は、伝統的なビルド方法よりも、多くの人にとって、根本的な発展となり、さらに Maven 2 はこの点を高めました。Maven 2 は次の URL からダウンロードできます。
http://maven.apache.org

サンプル・アプリケーションの構成、ビルド、デプロイ

以下のリンクから Time Reporting アプリケーションをダウンロードしてください。
Time Report

zip ファイルを展開すると、time_report ディレクトリーが作られます。

ソースコード

SVN からサンプル・アプリケーションのソースコードをチェックアウトすることができます。

svn checkout http://svn.apache.org/repos/asf/geronimo/samples/trunk/samples/timereport

構成

Time Reporting アプリケーションは J2EE の宣言的セキュリティを利用して実行するので、情報を保存するためにデータベースを作り、セキュリティー・レルムをデプロイする必要があります。

ユーザ情報保存用データベースの作成

Apache Geronimo サーバーを始動した後、 Geronimo コンソール へログインし、以下の手順によりユーザー情報保存用の TimeReportDB を作成してください。

TimeReportDB.sql
CREATE TABLE users(
	userid VARCHAR(15) PRIMARY KEY,
	password VARCHAR(15),
	name VARCHAR(40)
);

CREATE TABLE usergroups(
	userid VARCHAR(15),
	groupname VARCHAR(20),
	PRIMARY KEY (userid, groupname)
);

INSERT INTO users VALUES('emp1', 'pass1', 'Employee 1');
INSERT INTO users VALUES('emp2', 'pass2', 'Employee 2');
INSERT INTO users VALUES('mgm1', 'pass3', 'Manager 1');
INSERT INTO users VALUES('mgm2', 'pass4', 'Manager 2');

INSERT INTO usergroups VALUES('emp1', 'EmployeeGroup');
INSERT INTO usergroups VALUES('emp2', 'EmployeeGroup');
INSERT INTO usergroups VALUES('mgm1', 'ManagerGroup');
INSERT INTO usergroups VALUES('mgm2', 'ManagerGroup');
  1. 左側の Console Navigation から DB Manager リンクを選択してください。
  2. Create DB 欄にデータベース名として TimeReportDB を入力し、Create ボタンをクリックしてください。
  3. Use DB 欄で TimeReportDB を選択してください。
  4. time_report/config ディレクトリーから、TimeReportDB.sql を開いてください。
  5. SQL Commands のテキストエリアに TimeReportDB.sql の内容を貼りつけ、Run SQL ボタンを押してください。

ビルド

Time Report アプリケーションは pom.xml によってソースコードからのビルドされます。コマンド・プロンプト・ウィンドウを開き、timereport ディレクトリーへ移動し、mvn install site とコマンドを入力するとビルドされ、timereport フォルダーの下に timereport-ear-2.0-SNAPSHOT.ear が作られます。これで Geronimo アプリケーション・サーバーに Time Report アプリケーションをデプロイする準備ができました。

デプロイ

Geronimo コンソール の利用によって、サンプルアプリケーションのデプロイはかなり簡単です。

  1. Console Navigation パネルから Deploy New を選択してください。
  2. Archive 入力欄に time_report フォルダーの timereport-ear-2.0-SNAPSHOT.ear を読み込んでください。
  3. Install ボタンを押してアプリケーションをサーバへデプロイしてください。
    Back to Top

サンプル・アプリケーションのテスト

サンプル・アプリケーションのテストは、ブラウザを開き、http://localhost:8080/timereport を入力してください。 アプリケーションの Welcome ページへ遷移します。

Time Report ページへは、ユーザー名を emp1 、パスワードを pass1 で接続できます。マネージャーとしてアプリケーションにログインするには、mgm1 と pass3 を利用してください。

まとめ

この文章では、J2EE の宣言的セキュリティー機能を持つ Geronimo アプリケーション・サーバーにウェブ・アプリケーションをデプロイする方法を示しました。順に説明にしたがって、サンプル・アプリケーションをビルド、デプロイ、テストをしました。

この文章のハイライトは、次のとおりです。

  • Apache Geronimo は Jetty と Tomcat という2つのウェブ・コンテナを持っています
  • 組み込みの Derby を利用してセキュリティーのデータを持つデータベースを作れます
  • Geronimo ウェブ・アプリケーション内にセキュリティー・ロールを定義できます
  • Geronimo コンソール を利用してデプロイメント・プランとウェブ・アーカイブをデプロイします