TomcatでBasic認証を行う
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アプリケーションのまとまりの場合もあります) のユーザを一意に定めるための"データベース"と、認証された各ユーザに付与されているロールの一覧を列挙するものの両方を合わせたものを指します。
http://www.jajakarta.org/tomcat/tomcat5.0/ja/docs/tomcat-docs/realm-howto.html
デフォルトではUserDatabaseレルムが設定されていますが、今回は元からMySQLを使っており、動的にユーザを増やすこともありそうなので、JDBCレルムを使うことにしました。
データベースに関する設定
Catalinaホーム/common/lib/に事前にJDBCドライバのjarを置いておきます。
まず、MySQLで以下の2つのテーブルを作ります。
tomcat_userテーブル
user | varchar(45) |
---|---|
password | varchar(45) |
ユーザ名とパスワードを保持するテーブルです。
tomcat_roleテーブル
user | varchar(45) |
---|---|
role | varchar(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&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の
<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でアクセスしたときに認証をかけるかやどのロールにアクセスを許可するかを設定します。
Tomcat再起動後にプロジェクトのページにアクセスしようとすると、ユーザ名とパスワードの入力が求められ、Basic認証が実行されていることが確認できると思います。
ちなみにこの方法でログインした場合、HttpServletRequestのgetRemoteUserメソッドを使うことでログインしているユーザ名を取得、getUserPrincipalメソッドを使うことでそのユーザの所属するロールを取得できます。