注
この記事が作成されて以来、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられました。 この記事の執筆時点で紹介したメンバーシップ プロバイダーではなく 、ASP.NET ID プラットフォームを使用するようにアプリを更新することを強くお勧めします。 ASP.NET ID には、ASP.NET メンバーシップ システムに比して、次のような多くの利点があります。
- パフォーマンスの向上
- 拡張性とテスト容易性の向上
- OAuth、OpenID Connect、および 2 要素認証のサポート
- クレームベースのアイデンティティサポート
- 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 プロバイダーを使用すると、アプリケーションをデプロイするときにいくつかの課題が発生します。 まず、アプリケーション サービス データベース オブジェクトは、開発データベースと運用データベースの両方で適切に作成し、適切に初期化する必要があります。 また、行う必要がある重要な構成設定もあります。
注
アプリケーション サービス 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 アプリケーションをデプロイする手順を説明し、最後に、運用環境でのユーザー アカウントとロールの管理に関する一般的な問題に対処します。
書籍レビュー アプリケーションの更新
過去のいくつかのチュートリアルで、ブック レビュー Web アプリケーションは静的な Web サイトから、ジャンルとレビューを管理するための一連の管理ページを備えた動的なデータ ドリブン Web アプリケーションに更新されました。 ただし、この管理セクションは現在保護されていません。管理ページの URL を知っている (または推測する) ユーザーは、サイトでレビューを作成、編集、または削除できます。 Web サイトの特定の部分を保護する一般的な方法は、ユーザー アカウントを実装してから、URL 承認規則を使用して、特定のユーザーまたはロールへのアクセスを制限することです。 このチュートリアルでダウンロードできる Book Reviews Web アプリケーションは、ユーザー アカウントとロールをサポートしています。 管理者という名前の 1 つのロールが定義されており、このロールのユーザーのみが管理ページにアクセスできます。
注
書籍レビュー Web アプリケーションで、Scott、Jisun、Alice という 3 つのユーザー アカウントを作成しました。 3 人のユーザーはすべて同じパスワードを持っています: password! Scott と Jisun は管理者ロールであり、Alice は役割を果たしていません。 サイトの管理以外のページには、匿名ユーザーが引き続きアクセスできます。 つまり、サイトを管理する場合を除き、サイトにアクセスするためにサインインする必要はありません。その場合は、管理者ロールのユーザーとしてサインインする必要があります。
Book Reviews アプリケーションのマスター ページが更新され、認証済みユーザーと匿名ユーザー用の別のユーザー インターフェイスが含まれています。 匿名ユーザーがサイトにアクセスすると、右上隅にログイン リンクが表示されます。 認証されたユーザーには、"ようこそ、 ユーザー名!" というメッセージと、ログアウトするためのリンクが表示されます。ログイン ページ (~/Login.aspx) もあります。このページには、訪問者を認証するためのユーザー インターフェイスとロジックを提供する Login Web コントロールが含まれています。 管理者のみが新しいアカウントを作成できます。 ( ~/Admin フォルダーにユーザー アカウントを作成および管理するためのページがあります)。
メンバーシップ API とロール API の構成
Book Reviews Web アプリケーションでは、メンバーシップ API とロール API を使用してユーザー アカウントをサポートし、それらのユーザーをロール (つまり、管理者ロール) にグループ化します。 アカウントとロールの情報を SQL Server データベースに格納するため、 SqlMembershipProvider および SqlRoleProvider プロバイダー クラスが使用されます。
注
このチュートリアルは、メンバーシップ API とロール API をサポートするように Web アプリケーションを構成する際の詳細な調査を目的としたものではありません。 これらの API の詳細と、Web サイトを使用するように Web サイトを構成するために必要な手順については、 Web サイトのセキュリティ に関するチュートリアルを参照してください。
SQL Server データベースでアプリケーション サービスを使用するには、まず、これらのプロバイダーによって使用されるデータベース オブジェクトを、ユーザー アカウントとロール情報を格納するデータベースに追加する必要があります。 これらの必要なデータベース オブジェクトには、さまざまなテーブル、ビュー、ストアド プロシージャが含まれます。 特に指定しない限り、SqlMembershipProvider および SqlRoleProvider プロバイダー クラスは、アプリケーションの ASPNETDB フォルダーにある App_Data という名前の SQL Server Express Edition データベースを使用します。このようなデータベースが存在しない場合は、実行時にこれらのプロバイダーによって必要なデータベース オブジェクトを使用して自動的に作成されます。
Web サイトのアプリケーション固有のデータが格納されているのと同じデータベースにアプリケーション サービス データベース オブジェクトを作成することが可能であり、通常は理想的です。 .NET Framework には、指定したデータベースにデータベース オブジェクトをインストールする aspnet_regsql.exe という名前のツールが付属しています。 このツールを使用して、Reviews.mdf フォルダー (開発データベース) のApp_Data データベースにこれらのオブジェクトを追加しました。 これらのオブジェクトを運用データベースに追加するときに、このチュートリアルの後半でこのツールを使用する方法について説明します。
アプリケーション サービス データベース オブジェクトを ASPNETDB 以外のデータベースに追加する場合は、適切なデータベースを使用するように、 SqlMembershipProvider と SqlRoleProvider プロバイダー クラスの構成をカスタマイズする必要があります。 メンバーシップ プロバイダーをカスタマイズするには、<の > セクション内に Web.configを追加します。<roleManager> 要素を使用して Roles プロバイダーを構成します。 次のスニペットは、Book Reviews アプリケーションの Web.config から取得され、メンバーシップとロール 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 承認 機能を使用して、ユーザーまたはロールによって特定のファイルまたはフォルダーへのアクセスを簡単に許可または拒否できます。 ( 「IIS と ASP.NET Development Server のコアの違い 」チュートリアルで URL 承認について簡単に説明し、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 サイトのセキュリティ に関するチュートリアルの User-Based 承認と Role-Based 承認に関するチュートリアルを参照してください。
Application Services を使用する Web アプリケーションのデプロイ
アプリケーション サービスを使用する Web サイトと、アプリケーション サービス情報をデータベースに格納するプロバイダーをデプロイする場合は、アプリケーション サービスに必要なデータベース オブジェクトを運用データベースに作成する必要があります。 最初は運用データベースにこれらのオブジェクトが含まれていないため、アプリケーションが最初にデプロイされたとき (またはアプリケーション サービスが追加された後に初めてデプロイされる場合) は、運用データベースでこれらの必要なデータベース オブジェクトを取得するための追加の手順を実行する必要があります。
開発環境で作成されたユーザー アカウントを運用環境にレプリケートする場合は、アプリケーション サービスを使用する Web サイトをデプロイするときに、もう 1 つの課題が発生する可能性があります。 メンバーシップとロールの構成によっては、開発環境で作成されたユーザー アカウントを運用環境のデータベースに正常にコピーした場合でも、これらのユーザーは運用環境の Web アプリケーションにサインインできない可能性があります。 この問題の原因を見て、発生を防ぐ方法について説明します。
ASP.NET には、Visual Studio から起動できる優れた Web サイト管理ツール (WSAT) が付属しており、ユーザー アカウント、ロール、および承認規則を Web ベースのインターフェイスを介して管理できます。 残念ながら、WSAT はローカル Web サイトでのみ機能します。つまり、運用環境で Web アプリケーションのユーザー アカウント、ロール、承認規則をリモートで管理するために使用することはできません。 運用 Web サイトから WSAT に似た動作を実装するさまざまな方法について説明します。
aspnet_regsql.exe を使用したデータベース オブジェクトの追加
データベースの配置に関するチュートリアルでは、開発データベースから運用データベースにテーブルとデータをコピーする方法について説明しました。これらの手法を使用して、アプリケーション サービス データベース オブジェクトを実稼働データベースにコピーできます。 もう 1 つのオプションは、アプリケーション サービス データベース オブジェクトをデータベースに追加または削除する aspnet_regsql.exe ツールです。
注
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: Application Services 用に SQL Server を構成することを選択する (フルサイズの画像を表示する場合はクリックします)
[サーバーとデータベースの選択] 画面で、データベースに接続するための情報の入力を求められます。 Web ホスティング会社から提供されたデータベース サーバー、セキュリティ資格情報、およびデータベース名を入力し、[次へ] をクリックします。
注
データベース サーバーと資格情報を入力すると、データベース のドロップダウン リストを展開するときにエラーが発生する可能性があります。
aspnet_regsql.exe ツールは、sysdatabases システム テーブルに対してクエリを実行してサーバー上のデータベースの一覧を取得しますが、一部の Web ホスティング企業はデータベース サーバーをロックダウンして、この情報が一般公開されないようにしています。 このエラーが発生した場合は、データベース名をドロップダウン リストに直接入力できます。
図 2: データベースの接続情報をツールに提供する (フルサイズの画像を表示する をクリックします)
次の画面では、実行しようとしているアクション 、つまり、アプリケーション サービスデータベースオブジェクトが指定されたデータベースに追加される予定であることを要約します。 この操作を完了するには、[次へ] をクリックします。 しばらくすると、データベース オブジェクトが追加されたことを示す最後の画面が表示されます (図 3 を参照)。
図 3: 成功! Application Services データベース オブジェクトが実稼働データベースに追加されました (フルサイズの画像を表示する をクリックします)。
アプリケーション サービス データベース オブジェクトが実稼働データベースに正常に追加されたことを確認するには、SQL Server Management Studio を開き、運用データベースに接続します。 図4が示すように、あなたのデータベースには現在、アプリケーション サービスのデータベース テーブル、aspnet_Applications、aspnet_Membership、aspnet_Usersなどが表示されるはずです。
図 4: データベース オブジェクトが実稼働データベースに追加されたことを確認します (フルサイズの画像を表示する をクリックします)。
Web アプリケーションを初めてデプロイするとき、またはアプリケーション サービスの使用を開始した後に初めて Web アプリケーションをデプロイする場合にのみ、 aspnet_regsql.exe ツールを使用する必要があります。 これらのデータベース オブジェクトが実稼働データベース上に存在する場合、再追加または変更する必要はありません。
開発から運用環境へのユーザー アカウントのコピー
SqlMembershipProviderおよびSqlRoleProvider プロバイダー クラスを使用してアプリケーション サービス情報を SQL Server データベースに格納する場合、ユーザー アカウントとロール情報は、aspnet_Users、aspnet_Membership、aspnet_Roles、aspnet_UsersInRolesなど、さまざまなデータベース テーブルに格納されます。 開発中に開発環境でユーザー アカウントを作成する場合は、該当するデータベース テーブルから対応するレコードをコピーすることで、運用環境でそれらのユーザー アカウントをレプリケートできます。 データベース発行ウィザードを使用してアプリケーション サービス データベース オブジェクトを展開した場合は、レコードのコピーを選択した可能性もあります。その結果、開発中に作成されたユーザー アカウントも運用環境に存在することになります。 ただし、構成設定によっては、開発中に作成され、運用環境にコピーされたアカウントを持つユーザーが、運用 Web サイトからログインできない場合があります。 何が与えますか?
SqlMembershipProviderおよびSqlRoleProvider プロバイダー クラスは、1 つのデータベースが複数のアプリケーションのユーザー ストアとして機能できるように設計されています。この場合、各アプリケーションは理論上、ユーザー名とロールが重複するユーザーを同じ名前で持つことができます。 この柔軟性を実現するために、データベースは aspnet_Applications テーブル内のアプリケーションの一覧を保持し、各ユーザーはこれらのアプリケーションのいずれかに関連付けられています。 具体的には、aspnet_Users テーブルには、各ユーザーを ApplicationId テーブル内のレコードに関連付けるaspnet_Applications列があります。
ApplicationId列に加えて、aspnet_Applications テーブルには ApplicationName 列も含まれています。この列には、アプリケーションにわかりやすい名前が付けられます。 Web サイトは、ログイン ページからユーザーの資格情報を検証するなど、ユーザー アカウントの操作を試みると、 SqlMembershipProvider クラスに、操作するアプリケーションを通知する必要があります。 これは通常、アプリケーション名を指定することによって行われます。この値は、 Web.config のプロバイダーの構成 (特に applicationName 属性を介して) から取得されます。
しかし、applicationNameでWeb.config属性が指定されていない場合はどうなりますか? このような場合、メンバーシップ システムは、アプリケーション ルート パスを applicationName 値として使用します。
applicationName属性が Web.config で明示的に設定されていない場合、開発環境と運用環境で別のアプリケーション ルートが使用されるため、アプリケーション サービス内の異なるアプリケーション名に関連付けられる可能性があります。 このような不一致が発生した場合、開発環境で作成されたユーザーの ApplicationId 値は、運用環境の ApplicationId 値と一致しません。 その結果、これらのユーザーはログインできなくなります。
注
この状況で、ユーザー アカウントが運用環境にコピーされ、 ApplicationId 値が一致しない場合は、これらの不適切な ApplicationId 値を運用環境で使用されている ApplicationId に更新するクエリを作成できます。 更新されると、開発環境でアカウントが作成されたユーザーは、運用環境で Web アプリケーションにサインインできるようになります。
良いニュースは、2 つの環境で同じApplicationIdを使用し、すべてのアプリケーション サービス プロバイダーに対して applicationName で Web.config 属性を明示的に設定する簡単な手順があることです。
applicationNameの属性を "BookReviews" に明示的に設定し、このスニペットが示すように<membership>と<roleManager>要素に適用します。
<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 によって提供されるすべての機能が、Membership API と Roles API を介してプログラムで利用できるということです。さらに、WSAT 画面の多くは、標準の ASP.NET ログイン関連のコントロールを使用します。 要するに、必要な管理機能を提供する ASP.NET ページを Web サイトに追加できます。
前のチュートリアルで Book Reviews Web アプリケーションが更新され、 ~/Admin フォルダーが含まれるようになっていることを思い出してください。このフォルダーは、管理者ロールのユーザーのみを許可するように構成されています。 管理者が新しいユーザー アカウントを作成できる CreateAccount.aspx という名前のページをそのフォルダーに追加しました。 このページでは、CreateUserWizard コントロールを使用して、新しいユーザー アカウントを作成するためのユーザー インターフェイスとバックエンド ロジックを表示します。 さらに、新しいユーザーを管理者ロールに追加するかどうかを確認する CheckBox を含むようにコントロールをカスタマイズしました (図 5 を参照)。 少しの作業で、WSAT によって提供されるユーザーおよびロール管理関連のタスクを実装するページのカスタム セットを構築できます。
注
メンバーシップとロールの API とログイン関連の ASP.NET Web コントロールの使用の詳細については、 Web サイトのセキュリティ に関するチュートリアルを参照してください。 CreateUserWizard コントロールのカスタマイズの詳細については、 ユーザー アカウントの作成 と 追加ユーザー情報の保存 に関するチュートリアルを参照するか、 Erich Peterson の記事「 CreateUserWizard コントロールのカスタマイズ」を参照してください。
図 5: 管理者は新しいユーザー アカウントを作成できます (フルサイズの画像を表示する をクリックします)
WSAT の完全な機能が必要な場合は、 独自の Web サイト管理ツールのローリング を確認してください。このツールでは、作成者 Dan Clem が、カスタム WSAT に似たツールを構築するプロセスについて説明します。 Dan は(C#で) アプリケーションのソース コードを共有し、ホストされている Web サイトに追加する手順を説明します。
まとめ
アプリケーション サービス データベースの実装を使用する Web アプリケーションをデプロイする場合は、まず、運用データベースに必要なデータベース オブジェクトがあることを確認する必要があります。 これらのオブジェクトは、 データベースの配置 に関するチュートリアルで説明されている手法を使用して追加できます。または、このチュートリアルで説明したように、 aspnet_regsql.exe ツールを使用することもできます。 開発環境と運用環境で使用されるアプリケーション名の同期 (開発環境で作成されたユーザーとロールを運用環境で有効にする場合に重要) と、運用環境でユーザーとロールを管理するための手法を中心に取り上げ、その他の課題に取り組んでいます。
楽しいプログラミングを!
もっと読む
このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。