ログイン機能を作成する
業務アプリならばログイン画面やメニューが必要になる場合が多いと思います。ログイン画面でIDとパスワードを入力してユーザー認証を行う場合、ユーザーテーブルのようなテーブルにパスワードを保存せず、画面での入力値でデータベースの認証を行えれば、次のようなセキュリティ面での有利さを得ることができます。
- Webアプリがデータベースに接続するためのIDとパスワードをconfigファイルなどでシステム内に保存不要
- 利用者ごとにデータベースに接続するIDが異なるため、データベースのアクセス権限を使って不要なデータへの操作を禁止
- トリガーなどの機能を使い、ユーザーIDと操作などを記録することで操作ログをRDBMS側で出力
今回のサンプルではmdbファイルを使用しているので、データベースの個別ユーザー認証がないため、IDとパスワードが一致すればログインできるという簡単な認証方式としています。
今回のソリューション構造

今回のサンプルのソリューションは、「CZ1001Service」と「CZ1001Web」の2つのプロジェクトから構成されています。
CZ1001ServiceはXML Webサービスプロジェクトで、App_Dataフォルダには今回のサンプルのデータストアであるBill.mdbファイルを配置しています。
CZ1001WebはWebアプリプロジェクトで、スタートアッププロジェクトとしておき、IDEでソリューションを実行するとWebアプリ側の実行結果がブラウザに表示されます。
フォーム認証とログイン画面の実現
ASP.NETでWebアプリを作成した場合、フォーム認証やログイン画面の指定はweb.configファイルの中で定義します。
<configuration>
:
:
:
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/CZ1001Login.aspx" protection="All" timeout="60" path="/"
defaultUrl="~/CZ1001Menu.aspx" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
:
:
:
[System.Web]要素の中にある[authentication]要素と[Authorization]要素がフォーム認証で重要な定義です。[Authorization]-[deny]要素でusers=”?”とし、認証が通らなかったらアクセスが許可されないWebアプリとして定義しています。[authentication]要素でmode=”Forms”と定義することで認証方式はフォーム認証にし、[authentication]-[forms]要素にフォーム認証用のログイン画面をloginUrl="~/CZ1001Login.aspx"と定義しています。
これらの定義により、このWebアプリが配置されたURLへ認証前にアクセスすると、自動的にCZ1001Login.aspxにリダイレクトされてログイン画面が表示されることになります。

今回のサンプルでは、積極的にCSSを活用しています。そのため、ログイン画面のように認証前の画面でCSSを使う場合、aspxファイルに直接CSSを記述するときはいいのですが、外部定義ファイルにCSSを記述してリスト2のように使用する場合、認証前なのでCSS定義ファイルにアクセスできずにCSSが効きません。
<link href="css/stylesheet.css" rel="stylesheet" type="text/css" />
それを回避するために、web.configに[location]要素を定義します。
<configuration>
:
:
:
<location path="css">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
:
:
:
リスト3の定義では、[location]要素で指定したcssフォルダについては、[allow]要素にusers="*"を指定し、アクセス許可がなくてもアクセス可能になるようにしています。
ログイン画面での認証処理
ログイン画面で[OK]をクリックすると、CZ1001Login.aspx.vbのOK_Button.Clickイベントが発生します。
Protected Sub OK_Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles OK_Button.Click
Dim userID As String = String.Empty
Dim password As String = String.Empty
Dim isOK As Boolean = False
Dim errorMessage As String = String.Empty
'チェック
isOK = True
userID = StrConv(Me.UserId_TextBox.Text, VbStrConv.Narrow Or VbStrConv.Lowercase)
password = StrConv(Me.Password_TextBox.Text, VbStrConv.Narrow Or VbStrConv.Lowercase)
'サーバー側チェック
If isOK Then
'ここにDBサーバーの認証チェックロジックなどを記述する
isOK = (userID = password)
If Not isOK Then
errorMessage = "利用者IDまたはパスワードに誤りがあります。"
End If
End If
If isOK Then
Me.Message_Label.Text = String.Empty
FormsAuthentication.SetAuthCookie(userID, False)
'共通情報をセッション情報に設定(userIDはMy.User.Name)
Me.Session("password") = password
Me.Response.Redirect("~/CZ1001Menu.aspx", True)
Else
FormsAuthentication.SignOut()
Me.Message_Label.Text = errorMessage.Replace("\n", "<br />")
Me.UserId_TextBox.Focus()
End If
End Sub
isOK = (userID = password)ならば認証OKとします- 認証OKの場合、FormsAuthentication.SetAuthCookieメソッドにより、指定したユーザーに対して認証チケットを作成してCookieに格納します
- 認証に成功したらCZ1001Menu.aspxにリダイレクトして、必ずトップ画面を表示します
自分が使いたいURLをブックマークしておき、ブックマークからURLを指定するとログイン画面が表示され、ログインしたら自動的に指定したURLにリダイレクトされた方が使い勝手がよい気がするのですが、業務アプリでは「ログインしたら必ずトップ画面が表示されること」という要件がよくあるので、サンプルではリスト3のように認証成功した場合に特定の画面に飛ぶ動きにしています。
なお、FormsAuthentication.RedirectFromLoginPageメソッドにより、ログイン画面が表示される要因となったURLにリダイレクトすることもできます。
