アプリケーション サービスを使用する Web サイトを構成する (C#)
Note
この記事が作成されてから、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられました。 この記事の作成時点で取り上げたメンバーシップ プロバイダーではなく、ASP.NET Identity プラットフォームを使用するようにアプリを更新することを強くお勧めします。 ASP.NET メンバーシップ システムと比べると、ASP.NET Identity には次のような多くの利点があります。
- パフォーマンスの向上
- 拡張性とテストの容易性の向上
- OAuth、OpenID Connect、2 要素認証のサポート
- クレームベースの ID のサポート
- ASP.Net Core との相互運用性の向上
ASP.NET バージョン 2.0 では、.NET Framework の一部であり一連の構成要素サービスとして機能し、Web アプリに豊富な機能性を追加するために使用できる一連のアプリケーション サービスが導入されました。 このチュートリアルでは、アプリケーション サービスを使用するように運用環境で Web サイトを構成する方法について説明し、運用環境でのユーザー アカウントとロールの管理に関する一般的な問題に対処します。
はじめに
ASP.NET バージョン 2.0 では、.NET Framework の一部であり一連の構成要素サービスとして機能し、、お使いの Web アプリに豊富な機能性を追加するために使える一連のアプリケーション サービスが導入されました。 アプリケーション サービスには次のものが含まれます。
- メンバーシップ - ユーザー アカウントを作成および管理するための API。
- ロール - ユーザーをグループに分類するための API。
- プロファイル - ユーザー固有のカスタム コンテンツを格納するための API。
- サイト マップ - 階層の形式でサイトの論理構造を定義するための API。メニューや階層リンクなどのナビゲーション コントロールを使用して表示できます。
- パーソナル化 - カスタマイズ設定を維持するための API。ほとんどの場合、Web パーツと使用されます。
- 稼働状況の監視 - 実行中の Web アプリのパフォーマンス、セキュリティ、エラー、およびその他のシステム正常性メトリックを監視するための API。
アプリケーション サービスの API は、特定の実装には関連付けられていません。 代わりに、特定のプロバイダーを使用するようにアプリケーション サービスに指示し、そのプロバイダーは特定のテクノロジを使用してサービスを実装します。 Web ホスティング会社でホストされているインターネットベースの Web アプリで最もよく使用されるプロバイダーは、SQL Server データベースの実装を使用するプロバイダーです。 たとえば、SqlMembershipProvider
は Microsoft SQL Server データベースにユーザー アカウント情報を格納するメンバーシップ API のプロバイダーです。
アプリケーション サービスと SQL Server プロバイダーを使用すると、アプリケーションをデプロイするときにいくつかの課題が発生します。 まず、アプリケーション サービスのデータベース オブジェクトは、開発データベースと運用データベースの両方で適切に作成し、適切に初期化する必要があります。 また、重要な構成の設定も必要です。
Note
アプリケーション サービス API は、実行時に API の実装の詳細を提供できるようにする設計パターンであるプロバイダー モデルを使用して設計されました。 .NET Framework には、SQL Server データベース実装を使用するメンバーシップ API とロール API のプロバイダーである SqlMembershipProvider
や SqlRoleProvider
など、使用できる多数のアプリケーション サービス プロバイダーが付属しています。 カスタム プロバイダーを作成してプラグインすることもできます。 実際、Book Reviews Web アプリには、サイト マップ API (ReviewSiteMapProvider
) のカスタム プロバイダーが既に含まれています。このプロバイダーは、データベース内の Genres
および Books
テーブルのデータからサイト マップを構築します。
このチュートリアルでは、まず、メンバーシップ API とロール API を使用するように Book Reviews Web アプリを拡張する方法について説明します。 次に、SQL Server データベース実装でアプリケーション サービスを使用する Web アプリをデプロイする手順を説明し、最後に、運用環境でのユーザー アカウントとロールの管理に関する一般的な問題に対処します。
Book Reviews アプリケーションの更新
これまでのいくつかのチュートリアルで、Book Reviews Web アプリは、静的な Web サイトから、ジャンルとレビューを管理するための一連の管理ページを備えた動的なデータ ドリブン Web アプリに更新されました。 ただし、この管理セクションは現在保護されていません。管理ページの URL を知っている (または推測する) ユーザーは誰でもサイトに入ってレビューを作成、編集、または削除できます。 Web サイトの特定の部分を保護する一般的な方法は、ユーザー アカウントを実装してから、URL 認可規則を使用して、特定のユーザーまたはロールへのアクセスを制限することです。 このチュートリアルでダウンロードできる Book Reviews Web アプリは、ユーザー アカウントとロールをサポートしています。 Admin という名前の 1 つのロールが定義されており、このロールのユーザーのみが管理ページにアクセスできます。
Note
Book Reviews Web アプリで、Scott、Jisun、Alice という 3 つのユーザー アカウントを作成しました。 3 人のユーザーは全員次の同じパスワードを持っています: password!Scott と Jisun には Admin ロールがありますが、Alice にはありません。 サイトの管理以外のページには、匿名ユーザーが引き続きアクセスできます。 つまり、サイトを管理する場合を除き、サイトにアクセスするためにサインインする必要はありません。サイトを管理する場合は、Admin ロールのユーザーとしてサインインする必要があります。
Book Reviews アプリケーションのマスター ページが更新され、認証済みユーザーと匿名ユーザー用に別のユーザー インターフェイスが含まれるようになりました。 匿名ユーザーがサイトにアクセスすると、右上隅にログイン リンクが表示されます。 認証されたユーザーには、"おかえりなさい、username!" というメッセージと、ログアウトするためのリンクが表示されます。ログイン ページ (~/Login.aspx
) もあります。このページには、訪問者を認証するためのユーザー インターフェイスとロジックを提供する Login Web コントロールが含まれています。 新しいアカウントを作成できるのは管理者のみです。 (~/Admin
フォルダー内のユーザー アカウントを作成および管理するためのページがあります)。
メンバーシップ API とロール API の構成
Book Reviews Web アプリでは、メンバーシップ API とロール API を使用してユーザー アカウントをサポートし、それらのユーザーをロール (つまり、Admin ロール) にグループ化します。 アカウントとロールの情報を SQL Server データベースに格納するため、SqlMembershipProvider
プロバイダー クラスと SqlRoleProvider
プロバイダー クラスが使用されます。
Note
このチュートリアルは、メンバーシップ API とロール API をサポートするように Web アプリを構成する際の詳細な調査を目的としたものではありません。 これらの API の詳細と、Web サイトを使用できるように構成するために必要な手順については、Web サイトのセキュリティ に関するチュートリアルをお読みください。
SQL Server データベースでアプリケーション サービスを使用するには、まず、これらのプロバイダーによって使用されるデータベース オブジェクトを、ユーザー アカウントとロール情報を格納するデータベースに追加する必要があります。 これらの必要なデータベース オブジェクトには、さまざまなテーブル、ビュー、ストアド プロシージャが含まれます。 特に指定しない限り、SqlMembershipProvider
プロバイダー クラスと SqlRoleProvider
プロバイダー クラスは、アプリケーションの App_Data
フォルダーにある ASPNETDB
という名前の SQL Server Express Edition データベースを使用します。そのようなデータベースが存在しない場合は、実行時に必要なデータベース オブジェクトを使用してこれらのプロバイダーによって自動的に作成されます。
Web サイトのアプリケーション固有のデータが格納されているのと同じデータベースにアプリケーション サービスのデータベース オブジェクトを作成することが可能であり、通常はこの方法が理想的です。 .NET Framework には、指定したデータベースにデータベース オブジェクトをインストールする aspnet_regsql.exe
という名前のツールが付属しています。 このツールを使用して、これらのオブジェクトを (開発データベースの) Reviews.mdf
データベースの App_Data
フォルダーに追加しました。 このチュートリアルの後半でこれらのオブジェクトを運用データベースに追加するときに、このツールの使用方法について説明します。
アプリケーション サービスのデータベース オブジェクトを ASPNETDB
以外のデータベースに追加する場合は、適切なデータベースを使用するように、SqlMembershipProvider
および SqlRoleProvider
プロバイダー クラスの構成をカスタマイズする必要があります。 メンバーシップ プロバイダーをカスタマイズするには、Web.config
の <system.web>
セクション内に<メンバーシップ>要素を追加します。<roleManager >要素を使用してロール プロバイダーを構成します。 次のスニペットは、Book Reviews アプリケーションの Web.config
から取得され、メンバーシップ API とロール API の構成設定を示しています。 どちらも新しいプロバイダー (SqlMembershipProvider
および SqlRoleProvider
プロバイダーをそれぞれ使用する ReviewMembership
と ReviewRole
) を登録することに注意してください。
<configuration>
<system.web>
...
<membership defaultProvider="ReviewMembership">
<providers>
<clear />
<add type="System.Web.Security.SqlMembershipProvider"
name="ReviewMembership"
connectionStringName="ReviewsConnectionString"
applicationName="BookReviews" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="ReviewRole">
<providers>
<clear />
<add type="System.Web.Security.SqlRoleProvider"
name="ReviewRole"
connectionStringName="ReviewsConnectionString"
applicationName="BookReviews" />
</providers>
</roleManager>
...
</system.web>
</configuration>
Web.config
ファイルの <authentication>
要素も、フォーム ベースの認証をサポートするように構成されています。
<configuration>
<system.web>
...
<authentication mode="Forms" />
...
</system.web>
</configuration>
管理ページへのアクセスの制限
ASP.NET を使用すると、URL 承認機能を使用して、ユーザーまたはロールによって特定のファイルまたはフォルダーへのアクセスを簡単に許可または拒否できます。 (URL 承認についてはIIS と ASP.NET 開発サーバーの間の主な違いに関するチュートリアルで簡単に説明し、IIS と ASP.NET 開発サーバーが静的コンテンツと動的コンテンツに対して URL 承認規則を異なる方法で適用する方法について説明しました)。管理者ロールのユーザーを除き、~/Admin
フォルダーへのアクセスを禁止するため、このフォルダーに URL 承認規則を追加する必要があります。 具体的には、URL 承認規則では、管理者 ロールのユーザーを許可し、他のすべてのユーザーを拒否する必要があります。 これを行うには、次の内容の Web.config
ファイルを ~/Admin
フォルダーに追加します。
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
ASP.NET の URL 承認機能の詳細と、この機能を使用してユーザーとロールの承認規則をスペル アウトする方法については、Web サイトのセキュリティに関するチュートリアルのユーザーベースの承認とロールベースの承認に関するチュートリアルを参照してください。
アプリケーション サービスを使用する Web アプリのデプロイ
アプリケーション サービスを使用する Web サイトと、そのアプリケーション サービスの情報をデータベースに格納するプロバイダーをデプロイする場合は、アプリケーション サービスに必要なデータベース オブジェクトを運用データベースに作成する必要があります。 最初は運用データベースにこれらのオブジェクトが含まれていないため、アプリケーションが最初にデプロイされたとき (またはアプリケーション サービスが追加された後に初めてデプロイされる場合) は、運用データベースでこれらの必要なデータベース オブジェクトを取得するための追加の手順を実行する必要があります。
開発環境で作成されたユーザー アカウントを運用環境にレプリケートする場合は、アプリケーション サービスを使用する Web サイトをデプロイするときに、別の課題が発生する可能性があります。 メンバーシップとロールの構成によっては、開発環境で作成されたユーザー アカウントを運用環境のデータベースに正常にコピーした場合でも、これらのユーザーは運用環境の Web アプリにサインインできない可能性があります。 この問題の原因を調べ、発生を防ぐ方法について説明します。
ASP.NET には、Visual Studio から起動できる優れた Web サイト 管理ツール (WSAT) が付属しており、ユーザー アカウント、ロール、および認可規則を Web ベースのインターフェイスを介して管理できます。 残念ながら、WSAT はローカル Web サイトでのみ機能します。つまり、運用環境で Web アプリのユーザー アカウント、ロール、認可規則をリモートで管理するために使用することはできません。 運用 Web サイトから WSAT に似た動作を実装するさまざまな方法について説明します。
aspnet_regsql.exe を使用したデータベース オブジェクトの追加
データベースの配置に関するチュートリアルでは、開発データベースから運用データベースにテーブルとデータをコピーする方法について説明しました。これらの手法を使用すれば、アプリケーション サービスのデータベース オブジェクトを運用データベースにコピーできます。 もう 1 つのオプションは、アプリケーション サービスのデータベース オブジェクトをデータベースに追加または削除する aspnet_regsql.exe
ツールです。
Note
aspnet_regsql.exe
ツールは、指定したデータベースにデータベース オブジェクトを作成します。 これらのデータベース オブジェクト内のデータは、開発データベースから運用データベースに移行されません。 開発データベースのユーザー アカウントとロール情報を運用データベースにコピーする場合は、データベースの配置に関するチュートリアルで説明されている手法を使用します。
aspnet_regsql.exe
ツールを使用して、運用データベースにデータベース オブジェクトを追加する方法を見てみましょう。 まず、Windows エクスプローラーを開き、コンピューターの .NET Framework バージョン 2.0 ディレクトリ "%WINDIR%\ Microsoft.NET\Framework\v2.0.50727" に移動します。 aspnet_regsql.exe
ツールが見つかります。 このツールはコマンドラインから使用できますが、グラフィカル ユーザー インターフェイスも含まれています。aspnet_regsql.exe
ファイルをダブルクリックして、グラフィカル コンポーネントを起動します。
ツールは、起動時にその目的を説明するスプラッシュ スクリーンを表示します。 [次へ] をクリックして、図 1 に示す [セットアップ オプションの選択] 画面に進みます。 ここから、アプリケーション サービスのデータベース オブジェクトを追加するか、データベースから削除することができます。 これらのオブジェクトを運用データベースに追加するため、[アプリケーション サービスのために SQL Server を構成する] オプションを選択し、[次へ] をクリックします。
図 1: アプリケーション サービス用の SQL Server の構成を選択する (クリックしてフルサイズの画像を表示)
[Select the Server and Database] (サーバーとデータベースの選択) 画面で、データベースに接続するための情報の入力を求められます。 Web ホスティング会社から提供されたデータベース サーバー、セキュリティ資格情報、およびデータベース名を入力し、[次へ] をクリックします。
Note
データベース サーバーと資格情報を入力すると、データベース のドロップダウン リストを展開するときにエラーが発生する可能性があります。 この aspnet_regsql.exe
ツールは sysdatabases
システム テーブルに対してクエリを実行してサーバー上のデータベースの一覧を取得しますが、一部の Web ホスティング企業はデータベース サーバーをロックダウンして、この情報が一般公開されないようにしています。 このエラーが発生した場合は、データベース名をドロップダウン リストに直接入力できます。
図 2: データベースの接続情報をツールに提供する (クリックしてフルサイズの画像を表示)
次の画面は、実行しようとしているアクション、つまり、指定されたデータベースへのアプリケーション サービスのデータベースオブジェクトの追加をまとめたものです。 [次へ] をクリックして、このアクションを完了します。 しばらくすると、データベース オブジェクトが追加されたことを示す最後の画面が表示されます (図 3 を参照)。
図 3: 成功! アプリケーション サービスのデータベース オブジェクトが運用データベースに追加された (クリックしてフルサイズの画像を表示)
アプリケーション サービスのデータベース オブジェクトが実稼働データベースに正常に追加されたことを確認するには、SQL Server Management Studio を開き、運用データベースに接続します。 図 4 に示すように、アプリケーション サービスのデータベース テーブルがデータベース、aspnet_Applications
、aspnet_Membership
、aspnet_Users
などに表示されます。
図 4: データベース オブジェクトが運用データベースに追加されたことを確認する (クリックしてフルサイズの画像を表示)
この aspnet_regsql.exe
ツールを使用する必要があるのは、Web アプリケーションを初めてデプロイするとき、またはアプリケーション サービスの使用を開始した後に初めて行う場合のみです。 これらのデータベース オブジェクトが運用データベース上に存在する場合、再追加または変更する必要はありません。
開発環境から運用環境へのユーザー アカウントのコピー
アプリケーション サービス情報を SQL Server データベースに格納するために SqlMembershipProvider
プロバイダー クラスとSqlRoleProvider
プロバイダー クラスを使用する場合、ユーザー アカウントとロールの情報は、特に、aspnet_Users
、aspnet_Membership
、aspnet_Roles
、aspnet_UsersInRoles
などさまざまなデータベース テーブルに格納されます。 開発中に開発環境でユーザー アカウントを作成する場合は、該当するデータベース テーブルから対応するレコードをコピーすることで、運用環境でそれらのユーザー アカウントをレプリケートできます。 データベース発行ウィザードを使用してアプリケーション サービスのデータベース オブジェクトを展開した場合は、レコードのコピーを選択した可能性もあります。その結果、開発中に作成されたユーザー アカウントも運用環境に存在することになります。 ただし、構成設定によっては、開発中に作成され、運用環境にコピーされたアカウントを持つユーザーが、運用 Web サイトからログインできない場合があります。 何のためでしょう。
SqlMembershipProvider
プロバイダー クラスと SqlRoleProvider
プロバイダー クラスは、1 つのデータベースが複数のアプリケーションのユーザー ストアとして機能できるように設計されています。各アプリケーションでは、理論的には、同じ名前のユーザー名とロールが重複するユーザーを持つことができます。 この柔軟性を実現するために、データベースは aspnet_Applications
テーブルでアプリケーションの一覧を管理しており、各ユーザーはこれらのアプリケーションのいずれかに関連付けられています。 具体的には、aspnet_Users
テーブルには、各ユーザーを aspnet_Applications
テーブル内のレコードに関連付ける ApplicationId
列があります。
ApplicationId
列に加えて、aspnet_Applications
テーブルには ApplicationName
列も含まれ、アプリケーションのわかりやすい名前が指定されます。 Web サイトは、ログイン ページからユーザーの資格情報の検証など、ユーザー アカウントの操作を試みると、操作するアプリケーションを SqlMembershipProvider
クラスに通知する必要があります。 これは通常、アプリケーション名を指定することによって行われ、この値はWeb.config
のプロバイダーの構成 (特に applicationName
属性を介して) から取得されます。
しかし、applicationName
属性が Web.config
に指定されていない場合はどうなりますか? このような場合、メンバーシップ システムは applicationName
の値としてアプリケーション ルート パスを使用します。 applicationName
属性が Web.config
に明示的に設定されていない場合は、開発環境と運用環境で別のアプリケーション ルートが使用されるため、アプリケーション サービス内の異なるアプリケーション名に関連付けられる可能性があります。 このような不一致が発生した場合、開発環境で作成されたユーザーには、運用環境の ApplicationId
値と一致しない ApplicationId
値が設定されます。 その結果、これらのユーザーはログインできなくなります。
Note
ユーザー アカウントが運用環境にコピーされ、ApplicationId
値が一致しない場合は、これらの正しくない ApplicationId
値を運用環境で使用されている ApplicationId
に更新するクエリを作成できます。 更新されると、開発環境でアカウントが作成されたユーザーは、運用環境で Web アプリケーションにサインインできるようになります。
良いニュースは、2 つの環境で確実に同じ ApplicationId
を使用できるようにするために、すべてのアプリケーション サービス プロバイダーに対して Web.config
で applicationName
属性を明示的に設定するという簡単な手順があることです。 Web.config
のこのスニペットが示すように、<membership>
および <roleManager>
要素で明示的に applicationName
属性を "BookReviews" に設定しています。
<membership defaultProvider="ReviewMembership">
<providers>
<clear />
<add type="System.Web.Security.SqlMembershipProvider"
name="ReviewMembership"
connectionStringName="ReviewsConnectionString"
applicationName="BookReviews" />
</providers>
</membership>
applicationName
属性の設定とその背後にある根拠の詳細については、Scott Guthrie のブログ記事「ASP.NET メンバーシップとその他のプロバイダーを構成するときに常に applicationName プロパティを設定する」を参照してください。
運用環境でのユーザー アカウントの管理
ASP.NET Web サイト管理ツール (WSAT) は、ユーザー アカウントの作成と管理、ロールの定義と適用、およびユーザーベースとロールベースの認可規則の定義を容易にします。 Visual Studio から WSAT を起動するには、ソリューション エクスプローラーに移動して [ASP.NET 構成] アイコンをクリックするか、[Web サイト] メニューまたは [プロジェクト] メニューに移動し、[ASP.NET 構成] メニュー項目を選択します。 残念ながら、WSAT はローカル Web サイトでのみ機能します。 そのため、ワークステーションから WSAT を使用して、運用環境で Web サイトを管理することはできません。
良いニュースは、WSAT が提供するすべての機能が、メンバーシップ API と ロール API を介してプログラムで利用できるということです。さらに、WSAT 画面の多くは、標準の ASP.NET ログイン関連のコントロールを使用します。 要するに、必要な管理機能を提供する Web サイトに ASP.NET ページを 追加できます。
前のチュートリアルで Book Reviews Web アプリケーションが更新され、~/Admin
フォルダーが含まれたことを思い出してください。このフォルダーは、Admin ロールのユーザーのみを許可するように構成されています。 管理者が新しいユーザー アカウントを作成できる CreateAccount.aspx
という名前のフォルダーにページを追加しました。 このページでは、CreateUserWizard コントロールを使用して、新しいユーザー アカウントを作成するためのユーザー インターフェイスとバックエンド ロジックを表示します。 さらに、新しいユーザーを Admin ロールに追加するかどうかを確認する チェックボックスを含むようにコントロールをカスタマイズしました (図 5 を参照)。 少しの作業で、WSAT によって提供されるユーザーおよびロール管理関連のタスクを実装するページのカスタム セットを構築できます。
Note
メンバーシップおよびロール API とログイン関連の ASP.NET Web コントロールの使用の詳細については、Web サイトのセキュリティに関するチュートリアルを参照してください。 CreateUserWizard コントロールのカスタマイズの詳細については、ユーザー アカウントの作成と追加ユーザー情報の保存に関するチュートリアルを参照するか、Erich Peterson の記事と CreateUserWizard コントロールのカスタマイズに関する記事を参照してください。
図 5: 管理者は新しいユーザー アカウントを作成できる (クリックしてフルサイズの画像を表示)
WSAT の完全な機能が必要な場合は、Dan Clem がカスタム WSAT に似たツールを構築するプロセスについて説明している独自の Web サイト管理ツールのローリングを参照してください。 Dan は (C#で) アプリケーションのソース コードを共有し、ホストされている Web サイトに追加する手順を説明しています。
まとめ
アプリケーション サービス データベースの実装を使用する Web アプリケーションをデプロイする場合は、まず、運用データベースに必要なデータベース オブジェクトがあることを確認する必要があります。 これらのオブジェクトは、データベースの配置に関するチュートリアルで説明されている手法を使用して追加できます。または、このチュートリアルで説明したように、aspnet_regsql.exe
ツールを使用することもできます。 その他には、(開発環境で作成されたユーザーとロールを運用環境で有効にする場合に重要となる) 開発環境と運用環境で使用されるアプリケーション名の同期の問題と、運用環境でユーザーとロールを管理するための手法を中心に取り上げています。
プログラミングに満足!
もっと読む
この記事で説明したトピックの詳細については、次のリソースを参照してください。