Hatena::ブログ(Diary)

public static void main

誰かが困って検索したときに助けになる話題を書いていければと思っています。

2009-03-22

[][]Tomcat6のインストールとEclipse3.4のWTPで使用する時に詰まったことメモ

OSはWindows XPTomcatのバージョンは6.0.18です。

追記:

GoogleからTomcat5.5+Eclipse3.4でアクセスしてくる方が多いのですが、おそらくEclipse3.4のWTPで作ったプロジェクトがTomcat5.5にデプロイできない(ターゲットランタイムで選べない)ことについてではないかと思ったので一言。

Tomcat5.5にデプロイできるプロジェクトを作るには、動的Webプロジェクトを作成する際に動的Webモジュールバージョンを2.2に変更すればOKです(デフォルトでは2.5)。


Tomcat5.5とTomcat6の並存

Windows環境でインストール用のexeを使ってTomcat6のインストールを仕様としたら以下のようなエラーが発生。

Failed to install Tomcat6 service.
Check your settings and permissions
Ignore and continue anyway (not recommended)?

別のバージョンのTomcatが入っているときに発生するエラーで、どのTomcatのWindowsサービスの名前も「Apache Tomcat」となっているため、サービスを登録するときにエラーになるようです。

Eclipseからだけ使う分にはサービスとして使う必要はないので無理やりインストールを続行してしまってもよいのですが、並存させたい場合はサービス名を変更してやる必要があります。

Tomcat6をインストールする前にコマンドプロンプトを開いて以下のコマンドを実行します。

sc config tomcat5 DisplayName= "Apache Tomcat 5.5"

これで元の「Apache Tomcat」から「Apache Tomcat 5.5」と言う名前に変更できたので、Tomcat6のインストーラを実行すればエラーなくインストールができます。

名前に統一感を持たせたい人はtomcat6のサービス名のほうもリネームしてください。

ちなみにDisplayName=の後のスペースは必須です。


参考


Eclipseでサーバを定義(あるいは起動)

WTPで開発する際にはサーバ(Servers)を定義するのですが、その際にTomcat6が選択肢に出てくるのですが選択しても「選択されたタイプを使用してサーバーを作成できません」と表示されてウィザードを進めることができませんでした。

普通のTomcatサーバを起動しようとしてもjava.io.UnsupportedEncodingExceptionが発生して動かないようです。

これは、「TOMCAT_HOME\conf」以下のtomcat-users.xmlの一行目が以下のようになっているからです。

<?xml version='1.0' encoding='cp932'?>

このxmlファイルの実際のエンコーディングUTF-8なので、以下のように修正します。

<?xml version='1.0' encoding='utf-8'?>

これで上記のどちらの問題も解決しました。


参考

2007-12-07

[][][]TomcatBasic認証を行う

TomcatでBasic認証を使ってみたので、その設定方法をメモ。

Tomcatでちょっとしたことをやりたいときには、Apacheと連携しないとだめかと思っていたのですが、調べてみると思ってたよりもできることが多いことがわかってきました。

たとえば、mod_rewriteを使ったようにURLを静的に見せるのに、Url Rewrite Filterがあったりとか、ライブラリを使わなくても、jspにヘッダやフッタを自動でくっつけたり、国際化に対応したりといろいろできます。

個人的には、TomcatやApacheの設定ファイルをいじらなくてもwarファイルを配置するだけで他の環境で動くようにできるのが理想だと思っています(DB関連の設定は必要ですが。)。

Jetty+SQLiteで単独で動くアプリケーションになるならもっとよいですね。

今回、Basic認証をTomcatで実現するに当たって、プロジェクトのMETA-INF/context.xmlで設定することで、conf/tomcat-user.xmlやconf/server.xmlを変更しなくてもよい方法を選択しました。

JDBCレルムの設定

レルムとは

レルムとは、ユーザ名とパスワードの組み合わせのように、 Webアプリケーション(複数のWebアプリケーションのまとまりの場合もあります) のユーザを一意に定めるための"データベース"と、認証された各ユーザに付与されているロールの一覧を列挙するものの両方を合わせたものを指します。

404 Not Found

デフォルトではUserDatabaseレルムが設定されていますが、今回は元からMySQLを使っており、動的にユーザを増やすこともありそうなので、JDBCレルムを使うことにしました。



データベースに関する設定

Catalinaホーム/common/lib/に事前にJDBCドライバのjarを置いておきます。

まず、MySQLで以下の2つのテーブルを作ります。

tomcat_userテーブル

uservarchar(45)
passwordvarchar(45)

ユーザ名とパスワードを保持するテーブルです。

tomcat_roleテーブル

uservarchar(45)
rolevarchar(45)

ユーザ名と所属するロールを保持するテーブルです。

それぞれに以下のデータを入れておきます。

INSERT INTO tomcat_user VALUES("user", "password");
INSERT INTO tomcat_role VALUES("user", "basic");

ユーザ名にuser、パスワードにpasswordを使ってログインを行うことが出来るようになります。



context.xml

プロジェクトにMETA-INF/context.xmlを作成し、以下の記述をします。

<?xml version="1.0" encoding="UTF-8"?>
<Context>
	<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99" resourceName="Basic"
		driverName="org.gjt.mm.mysql.Driver"
		connectionURL="jdbc:mysql:///test_db?useUnicode=true&amp;characterEncoding=UTF-8"
		 connectionName="MySQLのユーザ名" connectionPassword="パスワード"
		 userTable="tomcat_user" userNameCol="user" userCredCol="password"
		 userRoleTable="tomcat_role" roleNameCol="role" />               
</Context>

userTable, userNameCol, userCredCol, userRoleTable, roleNameColで先ほど作ったテーブルと対応させています。



Basic認証の設定

プロジェクトのweb.xmlの<web-app>に以下の追記をします。

<security-constraint>
  <web-resource-collection>
    <web-resource-name>
      Authentication of BasicAuth
    </web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>basic</role-name>
  </auth-constraint>
</security-constraint>
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>Basic</realm-name>
</login-config>
<security-role>
  <role-name>basic</role-name>
</security-role>

どのパターンのURLでアクセスしたときに認証をかけるかやどのロールにアクセスを許可するかを設定します。

<role-name>で先ほどtomcat_roleに挿入したbasicロールを指定しています。


Tomcat再起動後にプロジェクトのページにアクセスしようとすると、ユーザ名とパスワードの入力が求められ、Basic認証が実行されていることが確認できると思います。

ちなみにこの方法でログインした場合、HttpServletRequestのgetRemoteUserメソッドを使うことでログインしているユーザ名を取得、getUserPrincipalメソッドを使うことでそのユーザの所属するロールを取得できます。



疑問

今回初めてレルムを使った認証を行ったのですが、Tomcatには今回使ったもの以外にもいくつか認証方式が最初から用意されており、Form認証+JDBCレルムを利用すればログイン制御としては十分です。

そこで気になったのは、JavaでWebアプリケーションを作るときには、一般的にこの認証の仕組みを使うことが多いのかということです。

細かい制御が必要なときはSessionを使ったほうがよさそうですので場合によりけりなのでしょうか。



参考

ユーザー認証 - サーブレット入門