セキュリティの基礎と ASP.NET のサポート (VB)
Note
この記事を作成した後で、ASP.NET メンバーシップ プロバイダーよりも ASP.NET Identity のほうが適切になりました。 この記事の作成時点で紹介されている Membership プロバイダーではなく、ASP.NET Identity プラットフォームを使うようにアプリを更新することを強くお勧めします。 ASP.NET メンバーシップ システムと比べると、ASP.NET Identity には次のような多くの利点があります。
- パフォーマンスの向上
- 向上した拡張性とテストの容易性
- OAuth、OpenID Connect、2 要素認証のサポート
- クレームベースの ID のサポート
- ASP.Net Core との相互運用性の向上
このチュートリアルから始まる一連のチュートリアルでは、ASP.NET アプリケーションの中で Web フォームを介して訪問者の認証を行い、特定のページと機能へのアクセスを認可し、ユーザー アカウントを管理するための手法を紹介します。
はじめに
フォーラム、e コマース サイト、オンライン メール Web サイト、ポータル Web サイト、ソーシャル ネットワーク サイトのすべてに共通するものが 1 つありますが、それは何でしょうか。 これらのすべてに、"ユーザー アカウント" があります。 ユーザー アカウントを使用するサイトは、多数のサービスを用意する必要があります。 少なくとも、新しい訪問者がアカウントを作成できることと、再びアクセスした訪問者がログインできことが必要です。 このような Web アプリケーションは、ログイン済みユーザーに基づいて決定を下すことができます。たとえば、一部のページまたはアクションへのアクセスをログイン済みユーザーに、つまり一部のユーザーに限定することや、ログイン済みユーザーに固有の情報をページ上に表示することや、どのユーザーがそのページを見ているかに応じて表示する情報を増減することが考えられます。
このチュートリアルから始まる一連のチュートリアルでは、ASP.NET アプリケーションの中で Web フォームを介して訪問者の認証を行い、特定のページと機能へのアクセスを認可し、ユーザー アカウントを管理するための手法を紹介します。 これらのチュートリアルを順に進めながら、次のことを行う方法を説明します。
- ユーザーの身元を特定して Web サイトにログインさせる
- ASP.NET の Membership フレームワークを使用してユーザー アカウントを管理する
- ユーザー アカウントを作成、更新、削除する
- ログイン済みユーザーに基づいて Web ページ、ディレクトリ、または特定の機能へのアクセスを制限する
- ASP.NET の Roles フレームワークを使用してユーザー アカウントにロールを関連付ける
- ユーザー ロールの管理
- ログイン済みユーザーのロールに基づいて Web ページ、ディレクトリ、または特定の機能へのアクセスを制限する
- ASP.NET のセキュリティ Web コントロールをカスタマイズして拡張する
これらのチュートリアルは簡潔で、プロセスを視覚的に説明するためのスクリーン ショットを豊富に含む詳細な手順を説明することを目的としています。 チュートリアルにはそれぞれ C# と Visual Basic のバージョンが用意されており、使用される完全なコードのダウンロードが含まれています (この最初のチュートリアルは、セキュリティの概念を概要レベルで説明するものであるため、関連するコードはありません)。
このチュートリアルでは、重要なセキュリティの概念について説明するとともに、ASP.NET ではフォーム認証、認可、ユーザー アカウント、ロールの実装を支援するためにどのような機能が用意されているかを説明します。 それでは始めましょう。
Note
セキュリティはどのアプリケーションにとっても重要な面の 1 つであり、その意思決定は物理的、技術的、ポリシー面にまたがり、高度な計画とドメイン知識を必要とします。 このチュートリアル シリーズは、セキュリティで保護された Web アプリケーションの開発方法の案内を目的とするものではなく、 フォーム認証、認可、ユーザー アカウント、ロールのみに焦点を当てています。 これらの点に関係するセキュリティの概念のいくつかをこのシリーズで説明しますが、それ以外は取り上げません。
認証、認可、ユーザー アカウント、ロール
認証、認可、ユーザー アカウント、ロールという 4 つの用語は、このチュートリアル シリーズ全体で頻繁に使用されるものであるため、ここで少し時間を取り、Web セキュリティというコンテキストでのこれらの用語の定義を確認しておきます。 クライアント/サーバー モデル (たとえばインターネット) では、要求を行っているクライアントの身元をサーバーが特定することが必要になるシナリオが多数あります。 "認証" とは、クライアントの ID つまり身元を突き止めるプロセスです。 身元の特定が完了したクライアントは、"認証済み" であるといいます。 身元が特定されていないクライアントは、"未認証" または "匿名" であるといいます。
セキュリティで保護された認証システムには、本人が知っているもの (something you know)、本人が所有しているもの (something you have)、本人の特徴 (something you are) の 3 つのファセットのうち少なくとも 1 つが関与します。 ほとんどの Web アプリケーションは、クライアントが知っているもの (たとえばパスワードや PIN) に依存しています。 ユーザーの身元の特定に使用される情報 (たとえばその人のユーザー名とパスワード) は、"資格情報" と呼ばれます。 このチュートリアル シリーズでは、"フォーム認証" に焦点を当てていますが、この認証モデルではユーザーは Web ページ フォームで自分の資格情報を入力するという方法でサイトにログインします。 私たちの誰もが、この種の認証をこれまでに経験したことがあります。 たとえば、e コマース サイトを利用するときです。 購入手続きに進もうとすると、ユーザー名とパスワードを Web ページ上のテキスト ボックスに入力するという方法でのログインが求められます。
クライアントの身元を特定することに加えて、サーバー側では、どのリソースや機能をアクセス可能にするかを要求元のクライアントに応じて制限することが必要になることがあります。 "認可" とは、あるユーザーが特定のリソースまたは機能へのアクセスに必要な権限を保有しているかどうかを判定するプロセスです。
"ユーザー アカウント" は、特定のユーザーに関する情報を保持するためのストアです。 ユーザー アカウントには少なくとも、そのユーザーを一意に特定する情報 (たとえばそのユーザーのログイン名とパスワード) が含まれている必要があります。 この必須情報の他に、ユーザー アカウントにはユーザーのメール アドレスや、アカウントが作成された日時、最後にログインした日時、氏名、電話番号、住所などが含まれることもあります。 フォーム認証を使用するときは、ユーザー アカウント情報は一般的にリレーショナル データベース (たとえば Microsoft SQL Server) に格納されます。
ユーザー アカウントをサポートする Web アプリケーションでは、ユーザーが "ロール" にグループ化されることもあります。 ロールとは、簡単にいえばユーザーに適用されるラベルですが、これを使用すると認可規則とページ レベルの機能の定義を抽象化できます。 たとえば、ある Web サイトでは "管理者" というロールと認可規則が規定されており、これで管理者以外の全員について特定の Web ページへのアクセスを禁止しています。 さらに、すべてのユーザー (これには管理者以外も含まれます) がアクセスできるさまざまなページに "管理者" ロールのユーザーがアクセスしたときに、追加データを表示したり、特別な機能を利用可能にしたりしています。 ロールを使用すると、このような認可規則をユーザーごとにではなくロールごとに定義できます。
ASP.NET アプリケーションでのユーザーの認証
ユーザーがブラウザーのアドレス ウィンドウに URL を入力するかリンクをクリックすると、指定されたコンテンツ (ASP.NET ページ、画像、JavaScript ファイル、またはその他の種類のコンテンツ) を取得するために、そのブラウザーから Web サーバーに HTTP (ハイパーテキスト転送プロトコル) 要求が送られます。 要求されたコンテンツを返すというタスクが Web サーバーに課せられます。 これを行うには、その要求に関するさまざまな事項を特定する必要があります。たとえば、誰がその要求を行ったか、その ID にはその要求されたコンテンツの取得が認可されているかどうかといったことです。
既定では、ブラウザーから送信される HTTP 要求にはいかなる身元特定情報も含まれません。 ただし、ブラウザーからの要求に認証情報が含まれている場合は、Web サーバー側で認証ワークフローが開始し、要求を行っているクライアントの身元特定がこのワークフローで試行されます。 この認証ワークフローのステップは、その Web アプリケーションで使用される認証の種類によって異なります。 ASP.NET では、Windows、Passport、フォームの 3 種類の認証がサポートされています。 このチュートリアル シリーズではフォーム認証に焦点を当てていますが、ここで少し時間を取り、Windows 認証のユーザー ストアおよびワークフローと比較してみましょう。
Windows 認証による認証
Windows 認証ワークフローでは、次の認証手法のいずれかが使用されます。
- 基本認証
- ダイジェスト認証
- Windows 統合認証
3 つの手法のどれも、機能はほぼ同じです。つまり、未認可の匿名要求を受け取った Web サーバーは、続行するには認可が必要であることを示す HTTP 応答を返します。 これを受けて、ブラウザーはモーダル ダイアログ ボックスを表示してユーザーにユーザー名とパスワードの入力を求めます (図 1 を参照)。 この情報は、HTTP ヘッダーを介して Web サーバーに返されます。
図 1: ユーザーに資格情報の入力を求めるモーダル ダイアログ ボックス
入力された資格情報は、Web サーバーの Windows ユーザー ストアと比較して検証されます。 つまり、Web アプリケーション内で認証されるユーザーのそれぞれが、そのアプリケーションの組織内での Windows アカウントを保有していることが必要です。 これは、イントラネットのシナリオでは一般的です。 実際には、Windows 統合認証をイントラネットで使用するときは、ネットワークへのログオンに使用される資格情報が自動的にブラウザーから Web サーバーに渡されるので、図 1 に示すダイアログ ボックスは表示されません。 Windows 認証はイントラネット アプリケーションに適していますが、インターネット アプリケーションでの使用は通常は不可能です。サイトにサインアップするユーザーそれぞれの Windows アカウントを作成することは現実的ではないからです。
フォーム認証による認証
一方、フォーム認証はインターネット Web アプリケーションに最適です。 前述のとおり、フォーム認証では Web フォームを使用してユーザーに資格情報を入力させるという方法でユーザーの身元を特定します。 したがって、認可されていないリソースにアクセスしようとしたユーザーは、自動的にログイン ページにリダイレクトされ、そのページで自分の資格情報を入力できます。 送信された資格情報は、カスタム ユーザー ストア (通常はデータベース) と比較して検証されます。
送信された資格情報の確認後に、そのユーザーの "フォーム認証チケット" が作成されます。 このチケットは、ユーザーが認証済みであることを示すものであり、身元を特定する情報 (たとえばユーザー名) が含まれています。 フォーム認証チケットは (一般的に) Cookie としてクライアント コンピューターに保存されます。 したがって、その Web サイトへのそれ以降のアクセスではフォーム認証チケットが HTTP 要求の中に含まれているので、ユーザーがログイン済みならば Web アプリケーションがそのユーザーの身元を特定できます。
図 2 は、フォーム認証ワークフローを概要レベルで描いたものです。 ASP.NET の中で認証と認可がどのように 2 つの独立したエンティティとしての役割を果たすかに注目してください。 フォーム認証システムは、ユーザーの身元を特定します (または、匿名であることを報告します)。 認可システムは、要求されたリソースへのアクセス権をそのユーザーが保有しているかどうかを判定します。 そのユーザーが未認可の場合は (たとえば図 2 で ProtectedPage.aspx に匿名でアクセスを試みているとき)、認可システムから、そのユーザーが拒否されたことが報告されるため、フォーム認証システムは自動的にそのユーザーをログイン ページにリダイレクトします。
ユーザーが正常にログインすると、それ以降の HTTP 要求にはフォーム認証チケットが含まれます。 フォーム認証システムの機能は、ユーザーの身元を特定することだけです。要求されたリソースにユーザーがアクセスできるかどうかの判定は、認可システムが行います。
図 2: フォーム認証ワークフロー
フォーム認証については、次のチュートリアル「フォーム認証の概要」でさらに詳しく説明します。 ASP.NET での認証のオプションの詳細については、「ASP.NET の認証」を参照してください。
Web ページ、ディレクトリ、ページ機能へのアクセスを制限する
ASP.NET では、特定のユーザーが特定のファイルまたはディレクトリにアクセスする権限を持っているかどうかを判断する方法として次の 2 つがあります。
- ファイル認可 - ASP.NET のページと Web サービスは、Web サーバーのファイル システム上に存在するファイルとして実装されるため、これらのファイルへのアクセス権をアクセス制御リスト (ACL) を通して指定できます。 ファイル認可は Windows 認証と共に最もよく使用されますが、ACL は Windows アカウントに適用されるアクセス許可であることがその理由です。 フォーム認証を使用するときは、サイトにアクセスするユーザーに関係なく、オペレーティング システム レベルとファイル システム レベルのすべての要求が同じ Windows アカウントによって実行されます。
- URL 認可 - URL 認可を使用するときは、ページ開発者が認可規則を Web.config で指定します。この認可規則では、どのユーザーまたはロールがアプリケーション内の特定のページまたはディレクトリへのアクセスを許可されるか、またはアクセスを拒否されるかを指定します。
ファイル認可と URL 認可では、特定の ASP.NET ページへの、または特定のディレクトリ内のすべての ASP.NET ページへのアクセスの認可規則を定義します。 これらの手法を使用すると、特定のユーザーからの特定のページへの要求を拒否するように ASP.NET に指示することも、特定のグループのユーザーにアクセスを許可してその他全員のアクセスを拒否するよう指示することもできます。 すべてのユーザーが同じページにアクセスできるけれども、そのページの機能がユーザーによって異なるというシナリオはどうなるでしょうか? たとえば、ユーザー アカウントをサポートする多くのサイトには、認証済みユーザーか匿名ユーザーかによって異なるコンテンツまたはデータが表示されるページがあります。 たとえば、匿名ユーザーに対してはサイトにログインするためのリンクを表示し、認証済みのユーザーに対しては「お帰りなさい、<ユーザー名> さん」のようなメッセージと、ログアウトするためのリンクを表示します。別の例としては、オークション サイトで、ある品物を見ている人が入札者か、その品物をオークションにかけた出品者かによって異なる情報が表示されるというものがあります。
このようなページ レベルの調整は、宣言的に行うことも、プログラムで行うこともできます。 匿名ユーザー向けに、認証済みユーザー向けとは異なるコンテンツを表示するには、LoginView コントロールをそのページまでドラッグし、その AnonymousTemplate と LoggedInTemplate のテンプレートに適切なコンテンツを入力します。 別の方法として、現在の要求が認証済みかどうか、ユーザーが誰であるか、ユーザーがどのロールに属しているか (ある場合) をプログラムで判断することもできます。 この情報を使用して、ページ上のグリッドまたはパネルの列を表示または非表示にすることができます。
このシリーズには、認可に焦点を当てた 3 つのチュートリアルが含まれています。 ユーザー ベースの認可では、特定のユーザー アカウントに対して特定のディレクトリ内の特定のページへのアクセスを制限する方法を説明し、ロールベースの認可ではロール レベルでの認可規則の指定について説明し、最後の現在ログインしているユーザーに基づくコンテンツの表示のチュートリアルでは、ページを訪問しているユーザーに基づいて特定のページのコンテンツと機能に変更を加える方法を説明します。 ASP.NET の認可のオプションの詳細については、「ASP.NET の認可」を参照してください。
ユーザー アカウントとロール
ASP.NET のフォーム認証は、ユーザーをサイトにログインさせて、そのユーザーの認証状態をページ訪問間で記憶しておくためのインフラストラクチャとなります。 また、URL 認可は、ASP.NET アプリケーションの中で特定のファイルまたはフォルダーへのアクセスを制限するためのフレームワークとなります。 ただし、どちらの機能も、ユーザー アカウント情報の保存やロールの管理の手段にはなりません。
ASP.NET 2.0 の前までは、ユーザーとロールのストアを作成することは開発者の責任でした。 また、ユーザー アカウント関連の必須のページ、たとえばログイン ページや新規アカウント作成のページなどのユーザー インターフェイスを設計してコードを書くことも、開発者がしなければなりませんでした。 ユーザー アカウント フレームワークが ASP.NET に組み込まれていないため、ユーザー アカウントを実装する開発者のそれぞれが、自分の設計に関するさまざまな事項を自分で決定しなければなりませんでした。たとえば、パスワードやその他の機密情報をどのように保存するか、パスワードの長さと強度に関してどのようなガイドラインを適用するかといったことです。
現在では、ASP.NET アプリケーション内でのユーザー アカウントの実装は "Membership フレームワーク" と組み込みの Login Web コントロールによって大幅に単純になっています。 Membership フレームワークは、System.Web.Security 名前空間内の少数のクラスで構成されており、ユーザー アカウント関連の必須のタスクを実行するための機能を備えています。 Membership フレームワーク内の鍵となるクラスが Membership クラスであり、次のようなメソッドが定義されています。
- CreateUser
- DeleteUser
- GetAllUsers
- GetUser
- UpdateUser
- ValidateUser
Membership フレームワークではプロバイダー モデルが使用されており、このモデルでは Membership フレームワークの API とその実装が明確に分離されています。 これで、開発者が 1 つの共通 API を使用すると同時に、開発者それぞれがそのアプリケーション独自のニーズを満たす実装を使用できるようになります。 つまり、Membership クラスによってこのフレームワークの重要な機能 (メソッド、プロパティ、およびイベント) が定義されますが、実装の詳細は一切定義されません。 代わりに、構成済みのプロバイダーが Membership クラスのメソッドによって呼び出され、このプロバイダーが実際の作業を実行します。 たとえば、Membership クラスの CreateUser メソッドが呼び出されたときに、Membership クラスがユーザー ストアの詳細を知ることはありません。 ユーザーの情報がデータベースに保持されているか、それとも XML ファイルやその他のストアかを知ることはありません。 Membership クラスは Web アプリケーションの構成を調べて、どのプロバイダーに呼び出しを委任するかを決定します。実際に新しいユーザー アカウントを適切なユーザー ストアの中で作成することは、そのプロバイダー クラスの責任です。 この相互作用を描いたものが図 3 です。
Microsoft は、次の 2 つの Membership プロバイダー クラスを .NET Framework の中で用意しています。
- ActiveDirectoryMembershipProvider - Membership API を Active Directory および Active Directory Application Mode (ADAM) のサーバー内で実装します。
- SqlMembershipProvider - Membership API を SQL Server データベース内で実装します。
このチュートリアル シリーズでは、SqlMembershipProvider のみを取り上げます。
図 3: プロバイダー モデルが採用されているため、さまざまな実装をシームレスにフレームワークに接続できます (フルサイズの画像を表示するにはここをクリックしてください)。
プロバイダー モデルの利点は、代替実装を Microsoft、サードパーティ ベンダー、または個人開発者が開発してシームレスに Membership フレームワークに接続できることです。 たとえば、Microsoft は Microsoft Access データベースのための Membership プロバイダーをリリース済みです。 Membership プロバイダーの詳細については、Provider Toolkit を参照してください。この中に含まれるものとしては、Membership プロバイダーのウォークスルー、サンプル カスタム プロバイダー、プロバイダー モデルに関する 100 ページを超えるドキュメント、組み込みの Membership プロバイダー (ActiveDirectoryMembershipProvider と SqlMembershipProvider) の完全なソース コードがあります。
ASP.NET 2.0 では、Roles フレームワークも導入されています。 メンバーシップ フレームワークと同様に、ロール フレームワークもプロバイダー モデルの上に構築されます。 その API は Roles クラスを介して公開され、次の 3 つのプロバイダー クラスが .NET Framework に付属しています。
- AuthorizationStoreRoleProvider - 認可マネージャー ポリシー ストア (たとえば Active Directory または ADAM) の中のロール情報を管理します。
- SqlRoleProvider - ロールを SQL Server データベース内で実装します。
- WindowsTokenRoleProvider - 訪問者の Windows グループに基づいてロール情報を関連付けます。 このメソッドは一般的に、Windows 認証と共に使用されます。
このチュートリアル シリーズでは、SqlRoleProvider のみに焦点を当てます。
プロバイダー モデルに含まれるのは単一の前方向き API (Membership クラスと Roles クラス) であるため、実装の詳細を一切考えずに、その API を中心とする機能を構築することも可能です。実装は、ページ開発者が選択したプロバイダーによって処理されるからです。 この統合 API が採用されているため、Membership と Roles のフレームワークとインターフェイスする Web コントロールを Microsoft とサードパーティ ベンダーが構築できます。 ASP.NET には、共通のユーザー アカウント ユーザー インターフェイスを実装するための多数の Login Web コントロールが付属しています。 たとえば、Login コントロールは、フォーム認証を介してユーザーに資格情報の入力を要求し、その資格情報を検証した後にユーザーをログインさせます。 LoginView コントロールのテンプレートを使用すると、匿名ユーザーか認証済みユーザーかに応じて異なるマークアップを表示することや、ユーザーのロールに基づいて異なるマークアップを表示することができます。 また、CreateUserWizard コントロールを利用すると、新しいユーザー アカウントを作成するためのステップ バイ ステップのユーザー インターフェイスを提示できます。
その内部では、Login のさまざまなコントロールが Membership フレームワークや Roles フレームワークと相互作用しています。 Login のコントロールのほとんどは、コードを 1 行も書かなくても実装できます。 これらのコントロールについては、その機能の拡張とカスタマイズの手法も含めて、後のチュートリアルで詳しく説明します。
まとめ
ユーザー アカウントをサポートするすべての Web アプリケーションは、同じような機能を必要とします。たとえば、ユーザーがログインして、そのログイン状態をページ訪問間で記憶できることが必要であり、新しい訪問者がアカウントを作成するための Web ページも必要であり、どのリソース、データ、機能の使用をどのユーザーまたはロールに許可するかをページ開発者が指定できることも必要です。 ユーザーの認証および認可と、ユーザー アカウントおよびロールの管理というタスクを ASP.NET アプリケーションの中で行うことは、きわめて簡単ですが、これはフォーム認証、URL 認可、Membership フレームワークと Roles フレームワークが導入されているからです。
これらの要素については、次のいくつかのチュートリアルで、実際に動作する Web アプリケーションを一から段階を追って構築しながら詳しく説明します。 次の 2 つのチュートリアルで、フォーム認証について詳しく説明します。 フォーム認証ワークフローの実際の動作を確認し、フォーム認証チケットの内部構造を説明し、セキュリティ上の懸念事項について説明し、フォーム認証システムを構成する方法を説明します。これらすべてを、訪問者のログインとログアウトができる Web アプリケーションを構築しながら行います。
プログラミングに満足!
もっと読む
この記事で説明したトピックの詳細については、次のリソースを参照してください。
- ASP.NET 2.0 メンバーシップ、ロール、フォーム認証、セキュリティのリソース
- ASP.NET 2.0 セキュリティ ガイドライン
- ASP.NET の認証
- ASP.NET の認可
- ASP.NET Login コントロールの概要
- ASP.NET 2.0 のメンバーシップ、ロール、プロファイルを確認する
- 操作方法: メンバーシップとロールを使用して自分のサイトをセキュリティで保護する (ビデオ)
- メンバーシップの概要
- MSDN Security Developer Center
- 『Professional ASP.NET 2.0 Security, Membership, and Role Management』 (ISBN: 978-0-7645-9698-8)
- Provider Toolkit
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアル シリーズは多数の協力的なレビュー担当者によるレビューを受けています。 このチュートリアルのリード レビュー担当者には、Alicja Maziarz、John Suru、Teresa Murphy が含まれます。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。