Rainbow Planet (GT×IT×SP×SA)

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

01_IT技術 (Technology)

サーバサイドJava(JSP&サーブレット)のFORM認証を用いたログイン画面の開発

投稿日:2019年12月17日 更新日:

(0)目次&概説

(1) サーバー側JavaのFORM認証
 (1-1) 認証の種類
 (1-2) FORM認証の特徴
 (1-3) FORM認証の実装概要
(2) FORM認証の実装手順
 (2-1) web.xmlの準備
 (2-2) ユーザー情報ファイルの準備
 (2-3) ログインページの実装
 (2-4) ログインエラーページの実装
(3) エラー事象の解説
 (3-1) 404エラー
 (3-2) ログインボタンを2回押さないとログイン不可

(1) サーバー側JavaのFORM認証

(1-1) 認証の種類

認証には下記の方式があります。その中でも「フォーム認証」が最も良く利用される方法になります。
・基本認証(BASIC)
・フォーム認証(FORM)
・ダイジェスト認証

・クライアント証明書認証

それぞれの認証方式の比較を次ぎに示します。

(図1)

認証方式 暗号化 セッションID HTTP仕様(RFC2617)での存在有無
基本認証 なし
(Base64平文)
なし
(ブラウザにて認証情報管理=ブラウザを閉じると終了する)
あり
(httpで定義あり)
フォーム認証 なし あり なし
(それぞれのアプリで要実装)
ダイジェスト認証 あり
(MD5ハッシュ関数)
なし
(ブラウザにて認証情報管理=ブラウザを閉じると終了する)
あり
(httpで定義あり)

また各方式の原理/特徴は下記の通りです。
(表2)

認証方式 原理/特徴
基本認証 ・利用者がユーザID/パスワードを入力して、サーバー側で認証を行う
・サーバー側でユーザID/パスワードを設定し、それをメール等でユーザに通知
・Base64でエンコードしているため、Base64でデコードすれば盗聴されるリスクがある
・ほぼ全てのWebサーバ&ブラウザに対応している
・ログアウトの機能がない(認証を削除するためにはブラウザを終了する必要ある)
 →※セッション管理が出来ない
・平文のテキストでパスワード等が送られるため、セキュリティが弱い
 →用途としては利用者が限定された内部的なwebサービス等に限定される
フォーム認証 ・HTMLで作られたフォーム画面からIDとパスワードを入力して認証を行う方式です。
・利用者がユーザID/パスワードを入力して、サーバー側で認証を行う
・認証が通るとセッションIDを発行してログイン管理を行う
 →一般公開されているwebサービスでも使われている方式
・認証の範囲指定が行えるため、SSOなども可能。
・問題点として、パスワードが平文で送られる点が挙げられる
ダイジェスト認証 ・盗聴防止のため、ユーザー名とパスワードをMD5(ハッシュ関数)で送る

(図1)基本認証のイメージ図

目次にもどる

(1-2) FORM認証の特徴

Form認証の特徴として、ルールの範囲内でログイン画面のレイアウトを自由に配置する事ができます。認証のおおまかな流れは下記の通りです。

(図2)

①リクエスト送付
クライアント⇒サーバへリクエストを送付します。

②認証の要否チェック
サーバにて認証が必要かをチェックします。認証不要の場合は要求ページを表示します。

③認証の済チェック
サーバにて認証済みかをチェックします。
(a) 認証済みの場合 → 要求ページを表示

(b) 認証未済みの場合 → ログインページに遷移

④ログインページの表示
クライアントにてログインの実施します。
(a) 成功の場合 → 要求ページを表示

(b) 失敗の場合 → 再度ログインページに遷移

目次にもどる

(1-3) FORM認証の実装概要

(1-3-1) config系ファイルの設定全体像
(図3)

(1-3-2) フォーム実装&画面遷移イメージ
(図4)

目次にもどる

(2) FORM認証の実装手順

(2-1) web.xmlの準備

■配備場所 (2020/1/7追記)
web.xmlの配備場所については次の規則に沿って配備します。
適用範囲 配備先
全アプリケーション

$CATALINA_HOME/conf/web.xml

(例)
/usr/local/src/apache-tomcat-8.5.42/conf/web.xml

現在のアプリケーション [アプリケーションルート]/WEB_INF/web.xml
(例)
/home/admin/eclipse-workspace/LoginForms/WebContent/WEB-INF

私の環境においては、現在のアプリケーションにのみ適用するために「WEB-INF」配下に置きました。

■記述内容
web.xmlに記述する要素は大きく3つありります。

<security-constraint> アクセス制御や許可範囲に関する設定をします。
<login-config> 認証方式や方法の設定をします。
<security-role> 認証を利用できるロールの設定を行います。

もう少し記述内容を詳細に書くと、次のようになります。

<security-constraint>
 ∟<web-resource-collection> ①アクセス制御の範囲指定
(アプリケーションのルートフォルダ以下のディレクトリ指定を行う)
   ∟<web-resource-name>  
   ∟<url-pattern> 範囲をURL指定する。
 ∟<auth-constraint> ②上記のアクセス制御範囲について、アクセス許可するロール名を指定します。
   ∟<role-name> ロールの名前を指定します。指定する名前は<security-role>にて定義されている必要があります。
<login-config>
 ∟<auth-method> 認証の方式
(BASIC/FORM/DIGEST/CLIENT-CERT)
 ∟<form-login-config> フォーム認証の際に記述します。
  ∟<form-login-page> ログインページの指定
(アプリケーションのルートフォルダ以下の指定を行う)
  ∟<form-error-page> ログインエラーページの指定
(アプリケーションのルートフォルダ以下の指定を行う)
<security-role>
 ∟<role-name> ロールの名前を定義

今回、実際に設定した例は下記の通りです。

<web-app>
	<security-constraint>
		<web-resource-collection>
			<web-resource-name>From Auth</web-resource-name>
			<url-pattern>/*</url-pattern>
		</web-resource-collection>
		<auth-constrait>
			<role-name>admin-gui</role-name>
			<role-name>manager-gui</role-name>
		</auth-constrait>
	</security-constraint>
	
	<login-config>
		<auth-method>FORM</auth-method>
		<form-login-config>
			<form-login-page>/Login.jsp</form-login-page>
			<form-error-page>/LoginError.jsp</form-error-page>
		</form-login-config>
	</login-config>
	
	<security-role>
		<role-name>admin-gui</role-name>
	</security-role>
	<security-role>
		<role-name>manager-gui</role-name>
	</security-role>
</web-app>

ちなみに、ロールを設ける意義は「権限の設定をシンプルにするため」です。
各ユーザーに逐一権限を細かに設定すると煩雑になってしまうため「ロール」という形で権限の定義を設けて、そのロールをユーザーに付与する事によって権限設定を簡素化してミスを防止する事が出来ます。

(図5)

目次にもどる

(2-2) ユーザー情報ファイルの準備

「ユーザー情報ファイル」とは「権限」と「ユーザー」の情報を記述します。ユーザ情報ファイルの名前はコンテナの種類により異なり、Tomcatの場合は「tomcat-users.xml」という名前です。記述する内容は<tomcat-users></tomcat-users>の間に次の項目を追記します。

■主な設定内容
①「role」の名前
<role>要素の「rolename」属性を用いてロールの名前を定義します。

<role rolename="manager-gui"/>


②「ユーザー」のパスワード/付与権限

<user>要素を用いてユーザー情報の登録を行っていきます。主な属性は下記です。

構文 説明
name=”[ユーザ名]” ユーザ名を記載します
password=”[パスワード]” パスワードを記載します
roles=”[ロール名1],
[ロール名2],・・・”
付与するロール名を記載します。複数ロールを付与する場合はカンマで区切って記載します。

下記に具体的な記述例を示します。

<user name="Tatsuya" password="12345" roles="admin-gui, manager-gui" />

 

■設定例(tomcat-users.xml全体)
上記①②を踏まえた全体の設定例を示します。

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">

<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user name="Tatsuya" password="abcde" roles="admin-gui, manager-gui" />
<user name="Rainbow" password="bcdef" roles="admin-gui" />
<user name="Mofutarou" password="cdefg" roles="manager-gui" />

</tomcat-users>

 

■配備先
配備先は下記の通りです。CATALINA_HOMEの場所が分からない場合はこちらを参考にして頂けたらと思います。
http://rainbow-engine.com/linux-tomcat-install/#title2-4

# デフォルトの配備先
$CATALINA_HOME/conf/
# 私の環境では下記のパスです。
/usr/local/src/apache-tomcat-8.5.42/conf

 

■配備先#2(2020/1/7追記)
配備先というよりは、上記の内容を追記する「tomcat-users.xml」の先について、私の環境では「tomcat-users.xml」は次の通り3カ所にありました。

#①
/home/admin/eclipse-workspace/Servers/Tomcat v8.5 Server at localhost-config/tomcat-users.xml

#②
/home/admin/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/conf/tomcat-users.xml

#③
/usr/local/src/apache-tomcat-8.5.42/conf/tomcat-users.xml

 

最初は「/usr/local/src/apache-tomcat-8.5.42/conf/」配下のもののみを編集していましたが、認証時に正しいログインID・パスワードで認証をしても次のようにLoginError.jspに遷移してしまう事象が起きました。

回避のために、上記②③にも同様の内容を追記した所、認証が正常に通過しました。
(正確には②のみでも認証は正常に通りました。各ファイルの意味合いについては要確認)

目次にもどる

(2-3) ログインページの実装

次にログインページをJSPで作成していきます。 

(例)

<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Login to Tatsuya Yazaki portofolio</title>
	    <%-- ヘッダーの帯の画像を挿入 --%>
        <img src="http://rainbow-engine.com/wp-content/uploads/2017/09/cropped-c8a03ed7.jpg" alt="" width="30%"/>
        <img src="http://rainbow-engine.com/wp-content/uploads/2017/09/cropped-c8a03ed7.jpg" alt="" width="30%"/>
        <img src="http://rainbow-engine.com/wp-content/uploads/2017/09/cropped-c8a03ed7.jpg" alt="" width="30%"/>
        <%-- タイトルを中央寄せで記載 --%>
		<center>
                <h3 id="mokuji">Login to Tatsuya Yazaki portofolio</h3>
        </center>
</head>
<body>
<%-- 【ポイント①】 フォーム認証の<form>要素のaction属性は"j_security_check"を指定する --%>
<form method="POST" action="j_security_check" name="loginform">
<table border="0">
        <tr>
                <%-- 【ポイント②】 フォーム認証の<input>要素でtext属性の時にname属性は"j_username"を指定する --%>
                <th align="right">User:</th>
                <td><input type="text" name="j_username" /></td>
        </tr>
        <tr>
                <%-- 【ポイント③】 フォーム認証の<input>要素でpassword属性の時にname属性は"j_password"を指定する --%>
                <th align="right">Password:</th>
                <td><input type="password" name="j_password" /></td>
        </tr>
        <tr>
                <td>
                        <%-- type=”submit”で送信フォームのボタンを作成しています。<form>で送っているのでnameとvalueの値が一組になって送信されます。 --%>	
                        <input type="submit" value="Login" />
                        <input type="reset" value="Discard" />
                </td>
        </tr>
</table>
</form>
</body>
</html>

(図6)ログイン画面例

目次にもどる

(2-4) ログインエラーページの実装

ログイン画面と同様に、ログイン失敗時の画面もJSPで作成します。
(例)

<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;">
<title>Login Error</title>
</head>
<img src="http://rainbow-engine.com/wp-content/uploads/2017/09/cropped-c8a03ed7.jpg" alt="" width="30%"/>
<img src="http://rainbow-engine.com/wp-content/uploads/2017/09/cropped-c8a03ed7.jpg" alt="" width="30%"/>
<img src="http://rainbow-engine.com/wp-content/uploads/2017/09/cropped-c8a03ed7.jpg" alt="" width="30%"/>
<br/>
<body>
Error occured. Please go back to the previous screen.
[<a href="JavaScript:history.back();">** Back **</a>]
</body>
</html>

(図7)ログインエラー画面例

 >目次にもどる

(3) エラー事象の解説

(3-1) 404エラー

上記の4項目を実装した状態で、正しいパスワードでログインを行うと、恐らく404エラーになると思います。

(図8)

404 - Not Found メッセージ:/LoginForms/j_security_check 説明:The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

これはログイン後のURL(<form>タグの遷移先であるaction=”j_security_check”)に対して、JSPやHTMLが未設定のためです。今回の例では下記のURLです。
http://tk2-221-20382.vs.sakura.ne.jp:8080/LoginForms/j_security_check

以前の古いバージョンのTomcat(5.5より前)では、このようなケースでディレクトリの一覧を表示していたそうですが、Tomcat5.5以降はセキュリティの観点から、ディレクトリの一覧を表示せずに404エラーを返すようになったそうです。

また、本来的にFORM認証はあるページを要求した際にログイン画面に遷移させて、認証が通れば要求ページを表示するフローなので、これらも踏まえると動作的には正常であると思います。

目次にもどる

(3-2) ログインボタンを2回押さないとログイン不可

これは直接ログイン画面を要求した場合などで発生します。上記(3-2)でも述べていますが、[要求ページ]→[認証画面]→(認証成功)→[要求ページ]のような流れを辿るため、もしログイン画面を要求した場合はログインしたのに、再びログイン画面が出てきたように見えてしまいます・・。

<事象の流れ>

1.Login.jspを要求
2.Login.jspに遷移するので、認証情報を入力
3.要求したLogin.jspに遷移する
4.再度認証情報を入力
5.アノテーション(j_security_check)の画面に遷移する

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-01_IT技術 (Technology)

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

EclipseでJavaプロジェクトを別サーバにエクスポートする方法

(0)目次&概説 (1) プロジェクトのエクスポートの手順  (1-1) プロジェクトのエクスポート@転送元サーバ  (1-2) インポート先サーバへ転送  (1-3) プロジェクトのインポート@転送 …

システム開発におけるデータモデリングの方法とER図描画ツール紹介

(0)目次&概説 (1) 項目を洗い出す  (1-1) 現行システムが存在する場合  (1-2) 新規システムを開発する場合 (2) エンティティを定義する  (2-1) エンティティの作成  (2- …

Linuxで一般ユーザ(rootスイッチ権限有り)を作成する方法

Linuxでユーザを作成する方法を書きます。 (0)目次 >(1)作業の背景・目的・前提条件 >(2)ユーザの作成 >(3)ユーザの「Wheel」グループへの追加 (1)作業の背景・目的・前提条件 「 …

ディープラーニング入門でニューラルネットワークを用いてAND回路を学習させるプログラムをJavaで作成

ニューラルネットワークでAND回路を学習させるJavaプログラムを作成したので、その解説を行います。 (0)目次&概説 (1) ニューラルネットワークの概要  (1-1) ニューラルネットワークとは? …

Javaの動的Webプロジェクト作成での事前設定と雛形Webプロジェクト作成

「動的Webプロジェクト」とはHTMLのような静的ページのみならず、ServletやJSPを用いてWebアプリケーション開発をする際に作成します。本記事ではEclipseにて「動的Webプロジェクト」 …

Top