<目次>
(1) Tomcatを使ったフォーム認証でユーザ情報をデータベース管理する方法
(1-1) 前提条件
(1-2) STEP1:context.xmlにコネクションプールを設定
(1-3) STEP2:context.xmlにDB認証の設定を追記
(1-4) STEP3:ユーザ管理用のテーブル作成
(1-5) STEP4:web.xmlの設定
(1-6) STEP5:ログイン/ログインエラーページの作成
(1-7) STEP6:疎通確認
(1) Tomcatを使ったフォーム認証でユーザ情報をデータベース管理する方法
今回はJSP/ServeltにてTomcatを使ったフォーム認証をする際に、ユーザー情報(ID、パスワードなど)を「tomcat-users.xml」に保持するのではなく、DB内(のテーブル)にて保持したい場合の設定方法をご紹介します。
(1-1) 前提条件
●アプリケーションサーバの準備
・JDK、Eclipseのインストールが済んでいる
⇒(手順)EclipseをCentOS7にインストールする手順
・Tomcatのインストールが済んでいる
⇒(手順)TomcatをCentOS7にインストールする手順
●データベースサーバの準備
(1-2) STEP1:context.xmlにコネクションプールを設定
まず最初に、Tomcatのcontext.xmlにコネクションプールの設定を追記して、コネクションプールにプールされた接続からDBへのアクセスを可能にします。手順については下記の記事をご参照ください。
(1-3) STEP2:context.xmlにDB認証の設定を追記
Tomcatにおいては認証におけるユーザ情報をどこで管理するか?を下表のいくつかのパターンから選択する事ができ、DBにユーザー情報を格納する場合は「JDBCRealm」や「DataSourceRealm」といった方式を選択していく事になります。
(表)Tomcatで選択可能な認証方法
方式 | 説明 |
MemoryRealm | XML形式のユーザ定義ファイル(tomcat-users.xmlなど)で管理する方式です。何も指定しなかったデフォルト時はこの「MemoryRealm」が適用されます。 |
JDBCRealm | データベースのテーブルにて認証情報を保持する方式です。JDBCドライバを介してアクセスを行います。 |
DataSourceRealm | データベースのテーブルにて認証情報を保持する方式です。データソースを介してアクセスを行います。 |
JNDIRealm | LDAPサーバで管理する方式です。JDNIのプロバイダを介してアクセスします。 ⇒(参考)JNDIとは?JDBCとの違いやメリット・デメリットについてもご紹介 |
では早速、追記の手順を確認していきます。
(1-3-1) DB認証の設定追記
認証方法を定義するためにはcontext.xml内に要素を追記していきます。
(構文)
<Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/LoginTemplate" localDataSource="true" roleNameCol="ROLE" userCredCol="PASSWORD" userNameCol="USER_ID" userRoleTable="USER_ROLE" userTable="USER_MASTER"> <CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler" algorithm="MD5" /> </Realm>
(各項目の説明)
className | 認証方式を実装したクラスを指定します。今回は「DataSourceRealm」を使うため「org.apache.catalina.realm.DataSourceRealm」を指定します。 |
dataSourceName | データソースの名前を指定します。コネクションプール設定の時に追記した<Resource>要素のname属性と一致させる必要があります。 |
localDataSource | 「META-INF/context.xml」配下の<Resource>要素を使用する場合はこの値を「true」に指定します。 |
userTable | ユーザー情報を保持するテーブル名(テーブル定義は後述)を指定します。 |
userCredCol | userTableで指定したテーブルのうち、パスワード情報を保持するカラムの名前を指定します。 |
userNameCol | userTableで指定したテーブルのうち、ユーザID情報を保持するカラムの名前を指定します。 |
userRoleTable | ロール情報を保持するテーブル名(テーブル定義は後述)を指定します。 |
roleNameCol | userRoleTableで指定したテーブルのうち、ユーザに紐づくロール情報を保持するカラムの名前を指定します。 |
<CredentialHandler>要素 | パスワードの暗号化のアルゴリズムを指定するための要素で、<Realm>内に入れ子にして記述します。次は「MD5」方式を指定した例です。
<CredentialHandler |
<?xml version="1.0" encoding="UTF-8"?> <Context displayName="Sample DataSource" docBase="LoginTemplate" path="/LoginTemplate" reloadable="true" > <Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/LoginTemplate" localDataSource="true" roleNameCol="ROLE" userCredCol="PASSWORD" userNameCol="USER_ID" userRoleTable="USER_ROLE" userTable="USER_MASTER"> <CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler" algorithm="MD5" /> </Realm> <Resource name="jdbc/[ご自身のデータソース名]" auth="Container" type="javax.sql.DataSource" username="[ご自身のDBユーザ名]" password="[ご自身のDBパスワード]" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@[ホスト名]:[ポート番号]:[SID]" maxWait="5000" maxIdle="2" validationQuery="[バリデーション用のSQL]" /> </Context>
(図122)
(1-4) STEP3:ユーザ管理用のテーブル作成
次にユーザ情報(ID、パスワード等)を管理するためのテーブルをデータベースに作成します。
(1-4-1) ユーザ情報テーブルをCREATE
<Realm>要素の「userTable」属性で指定したテーブルを作成します。テーブルの名称やカラムの名前はcontext.xmlとしっかり一致していれば、任意の名前に変更が可能です。以下はテーブル構造の例です。
・テーブル構造
(表)
論理名 | 物理名 | PK | NotNull | データ型 | 桁数 | バイト数 |
ユーザID | user_id | Y | Y | VARCHAR2 | – | 10 |
パスワード | password | N | Y | CHAR | 32 | 32 |
ユーザ名 | user_name | N | Y | VARCHAR2 | – | 50 |
以下はOracleDBにテーブル作成したDDLの例をご紹介します。
・DDL
CREATE TABLE USER_MASTER ( user_id VARCHAR2(10) ,password CHAR(32) NOT NULL ,user_name VARCHAR2(50) NOT NULL ,CONSTRAINT PK_ USER_MASTER PRIMARY KEY (user_id) ) TABLESPACE TWITTERTOOLTBS;
(図131)
(1-4-2) ユーザ情報テーブルにINSERT
テーブルを作成したら、ご自身のユーザ情報もINSERTしていきます。
(図132)
(1-4-3) ロール情報テーブルをCREATE
<Realm>要素の「userRoleTable」属性で指定したテーブルを作成します。テーブルの名称やカラムの名前はcontext.xmlとしっかり一致していれば、任意の名前に変更が可能です。以下はテーブル構造の例です。
●テーブル構造
(表)
論理名 | 物理名 | PK | NotNull | データ型 | 桁数 | バイト数 |
ユーザID | user_id | Y | Y | VARCHAR2 | – | 10 |
ロール名 | role | Y | Y | VARCHAR2 | – | 50 |
CREATE TABLE USER_ROLE ( user_id VARCHAR2(10) ,role VARCHAR2(50) ,CONSTRAINT PK_ USER_ROLE PRIMARY KEY (user_id,role) ) TABLESPACE TWITTERTOOLTBS;
(1-4-4) ロール情報テーブルにINSERT
テーブルを作成したら、ご自身のユーザー情報もINSERTしていきます。
(1-5) STEP4:web.xmlの設定
web.xmlについてはForm認証時の設定をした際のものをそのまま利用できます(特に変更の必要なし)。記述内容については下記の記事にてご紹介していますので、ご参照頂けたらと思います。
(1-6) STEP5:ログイン/ログインエラーページの作成
web.xmlで指定したログインページ&ログインエラーページについても、Form認証で作成したものをそのまま利用できます。以下の別記事にて、それぞれのサンプルプログラムをご紹介しているので、ご参照頂けたらと思います。
・ログインページ(サンプル付き)
https://rainbow-engine.com/create-logon-form-java/#title2-3
・ログインエラーページ(サンプル付き)
https://rainbow-engine.com/create-logon-form-java/#title2-4
(1-7) STEP6:疎通確認
実際に認証が必要なページにアクセスし、ログインページが表示される事、またDBに登録したユーザでログインできる事の確認を行います。