ロールを作成し、管理する (C#)

作成者: Scott Mitchell

Note

この記事が作成された後で、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられました。 アプリを更新し、この記事の作成時点で紹介したメンバーシップ プロバイダーではなく、ASP.NET Identity プラットフォームを使用することを強く推奨します。 ASP.NET メンバーシップ システムと比べると、ASP.NET Identity には次のような多くの利点があります。

  • パフォーマンスの向上
  • 向上した拡張性とテストの容易性
  • OAuth、OpenID Connect、2 要素認証のサポート
  • クレームベースの ID のサポート
  • ASP.Net Core との相互運用性の向上

コードのダウンロードまたは PDF のダウンロード

このチュートリアルでは、ロール フレームワークを構成するために必要な手順について説明します。 その後、ロールを作成および削除するための Web ページをビルドします。

はじめに

チュートリアル「ユーザー ベースの承認」では、URL 認可を使用して特定のユーザーを一連のページから制限し、アクセスしているユーザーに基づいて ASP.NET ページの機能を調整するための宣言およびプログラムによる手法について説明しました。 ただし、ユーザーごとにページ アクセスまたは機能のアクセス許可を付与すると、ユーザー アカウントの数が多いシナリオや、ユーザーの特権が頻繁に変更されるシナリオでは、メンテナンスが面倒になる可能性があります。 ユーザーが特定のタスクを実行するための認可を取得するか失うたびに、管理者は、適切な URL 認可規則、宣言型マークアップ、コードを更新する必要があります。

通常、ユーザーベースの認可は、ユーザーをグループまたは "ロール" に分類し、ロールごとにアクセス許可を適用するのに役立ちます。 たとえば、ほとんどの Web アプリケーションには、管理ユーザー専用に予約された特定のページまたはタスクのセットがあります。 チュートリアル「ユーザーベースの承認」で学習した手法を使用して、適切な URL 認可規則、宣言型マークアップ、コードを追加し、指定されたユーザー アカウントが管理タスクを実行できるようにします。 しかし、新しい管理者が追加された場合、または既存の管理者が自分の管理権限を取り消す必要がある場合、構成ファイルと Web ページを返して更新する必要があります。 ただし、ロールを使用すると、Administrators という名前のロールを作成し、それらの信頼されたユーザーに Administrators ロールを割り当てることができます。 次に、適切な URL 認可規則、宣言型マークアップ、コードを追加して、Administrators ロールでさまざまな管理タスクを実行できるようにします。 このインフラストラクチャを導入すると、サイトに対する新しい管理者の追加や既存の管理者の削除が、Administrators ロールに対するユーザーの追加や削除と同じくらい簡単になります。 構成、宣言型マークアップ、またはコードを変更する必要はありません。

ASP.NET には、ロールを定義し、それらをユーザー アカウントに関連付けるためのロール フレームワークが用意されています。 ロール フレームワークを使用すると、ロールの作成と削除、ロールに対するユーザーの追加または削除、特定のロールに属するユーザー セットの決定、ユーザーが特定のロールに属しているかどうかの確認を行うことができます。 ロール フレームワークが構成されたら、URL 認可規則を使用して、ページへのアクセスをロールごとに制限し、現在ログオンしているユーザーのロールに基づいて、ページ上の追加情報や機能を表示するか、または非表示にすることができます。

このチュートリアルでは、ロール フレームワークを構成するために必要な手順について説明します。 その後、ロールを作成および削除するための Web ページをビルドします。 チュートリアル「ユーザーにロールを割り当てる」では、ロールに対してユーザーの追加と削除を行う方法について説明しています。 また、チュートリアル「ロールベースの承認」では、ページへのアクセスをロールごとに制限する方法と、アクセスしているユーザーのロールに応じてページの機能を調整する方法について説明しています。 それでは始めましょう。

手順 1: 新しい ASP.NET ページの追加

このチュートリアルと次の 2 つのチュートリアルでは、ロール関連のさまざまな機能について説明します。 これらのチュートリアル全体で説明するトピックを実装するには、一連の ASP.NET ページが必要です。 これらのページを作成し、サイト マップを更新してみましょう。

まず、プロジェクトに Roles という名前の新しいフォルダーを作成します。 次に、4 つの新しい ASP.NET ページを Roles フォルダーに追加し、各ページを Site.master マスター ページにリンクします。 ページに次の名前を付けます。

  • ManageRoles.aspx
  • UsersAndRoles.aspx
  • CreateUserWizardWithRoles.aspx
  • RoleBasedAuthorization.aspx

この時点で、プロジェクトのソリューション エクスプローラーは、図 1 に示すスクリーンショットのようになります。

Four New Pages Have Been Added to the Roles Folder

図 1: Roles フォルダーに追加された 4 つの新しいページ (クリックするとフルサイズの画像を表示されます)

この時点で、各ページには、マスター ページの ContentPlaceHolders ごとに 1 つずつ、MainContentLoginContent という 2 つの Content コントロールが含まれます。

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"Runat="Server">
</asp:Content>

LoginContent ContentPlaceHolder の既定のマークアップでは、ユーザーが認証されているかどうかに応じて、サイトにログオンまたはログオフするためのリンクが表示されることを思い出してください。 ただし、ASP.NET ページに Content2 Content コントロールが存在すると、マスター ページの既定のマークアップがオーバーライドされます。 チュートリアル「フォーム認証の概要」で説明したように、これは、ページで左側の列にログイン関連のオプションを表示しない場合に役立ちます。

ただし、これらの 4 つのページでは、LoginContent ContentPlaceHolder のマスター ページの既定のマークアップを表示します。 そのため、Content2 Content コントロールの宣言型マークアップを削除します。 削除すると、4 つのページの各マークアップに含まれる Content コントロールは 1 つのみになります。

最後に、これらの新しい Web ページが含まれるようにサイト マップ (Web.sitemap) を更新してみましょう。 メンバーシップのチュートリアル用に追加した <siteMapNode> の後に、次の XML を追加します。

<siteMapNode title="Roles">
 <siteMapNode url="~/Roles/ManageRoles.aspx" title="Manage Roles"/>
 <siteMapNode url="~/Roles/UsersAndRoles.aspx" title="Users and Roles" />
 <siteMapNode url="~/Roles/CreateUserWizardWithRoles.aspx" title="Create Account (with Roles)" />
 <siteMapNode url="~/Roles/RoleBasedAuthorization.aspx" title="Role-Based Authorization" />
</siteMapNode>

サイト マップを更新したら、ブラウザーからサイトにアクセスします。 図 2 に示すように、左側のナビゲーションに、ロールのチュートリアル用の項目が含まれるようになりました。

The navigation on the left now includes items for the Roles tutorials.

図 2: Roles フォルダーに追加された 4 つの新しいページ (クリックするとフルサイズの画像を表示されます)

手順 2: ロール フレームワーク プロバイダーの指定と構成

メンバーシップ フレームワークと同様に、ロール フレームワークもプロバイダー モデルの上に構築されます。 チュートリアル「セキュリティの基礎と ASP.NET のサポート」で説明したように、.NET Framework には、3 つの組み込みのロール プロバイダー (AuthorizationStoreRoleProviderWindowsTokenRoleProviderSqlRoleProvider) が付属しています。 このチュートリアル シリーズでは、ロール ストアとして Microsoft SQL Server データベースを使用する SqlRoleProvider について重点的に説明します。

内部的には、ロール フレームワークおよび SqlRoleProvider は、メンバーシップ フレームワークおよび SqlMembershipProvider と同様に動作します。 .NET Framework には、ロール フレームワークの API として機能する Roles クラスが含まれています。 Roles クラスには、CreateRoleDeleteRoleGetAllRolesAddUserToRoleIsUserInRole などの静的メソッドがあります。 これらのメソッドのいずれかが呼び出されると、Roles クラスは、その呼び出しを、構成されたプロバイダーに委任します。 SqlRoleProvider は、応答で、ロール固有のテーブル (aspnet_Roles および aspnet_UsersInRoles) で動作します。

アプリケーションで SqlRoleProvider プロバイダーを使用するには、ストアとして使用するデータベースを指定する必要があります。 SqlRoleProvider は、指定されたロール ストアに特定のデータベース テーブル、ビュー、ストアド プロシージャがあると想定しています。 これらの必要なデータベース オブジェクトは、aspnet_regsql.exe ツールを使用して追加できます。 この時点で、SqlRoleProvider に必要なスキーマを持つデータベースが既にあります。 前のチュートリアル「SQL Server でメンバーシップ スキーマを作成する」では、SecurityTutorials.mdf という名前のデータベースを作成し、aspnet_regsql.exe を使用してアプリケーション サービスを追加しました。これには、SqlRoleProvider で必要なデータベース オブジェクトが含まれていました。 そのため、ロール サポートを有効にすることと、SecurityTutorials.mdf データベースをロール ストアとして使用する SqlRoleProvider を使用するように、ロール フレームワークに指示するだけで済みます。

ロール フレームワークは、アプリケーションの Web.config ファイル内の <roleManager> 要素を使用して構成されます。 既定では、ロール サポートは無効になっています。 これを有効にするには、次のように <roleManager> 要素の enabled 属性を true に設定する必要があります。

<?xml version="1.0"?>
<configuration>
 <system.web>
 ... Additional configuration markup removed for brevity ...

 <roleManager enabled="true" />
 <system.web>
</configuration>

既定では、すべての Web アプリケーションに、型が SqlRoleProviderAspNetSqlRoleProvider という名前のロール プロバイダーが含まれます。 この既定のプロバイダーは、machine.config (%WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG にあります) に登録されています。

<roleManager>
 <providers>
 <add name="AspNetSqlRoleProvider"
 connectionStringName="LocalSqlServer"
 applicationName="/"
 type="System.Web.Security.SqlRoleProvider, 
 System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
 </providers>
</roleManager>

プロバイダーの connectionStringName 属性は、使用されるロール ストアを指定します。 AspNetSqlRoleProvider プロバイダーは、この属性を LocalSqlServer に設定します。これは、machine.config でも定義され、既定では、aspnet.mdf という名前の App_Data フォルダー内の SQL Server 2005 Express Edition データベースを指します。

したがって、アプリケーションの Web.config ファイルでプロバイダー情報を指定せずに単にロール フレームワークを有効にすると、アプリケーションでは、既定の登録済みロール プロバイダーである AspNetSqlRoleProvider が使用されます。 ~/App_Data/aspnet.mdf データベースが存在しない場合、ASP.NET ランタイムによって自動的に作成され、アプリケーション サービス スキーマが追加されます。 ただし、ここでは、aspnet.mdf データベースを使用せず、代わりに、既に作成してアプリケーション サービス スキーマを追加した SecurityTutorials.mdf データベースを使用します。 この変更は、次の 2 つの方法のいずれかで実現できます。

  • Web.configで接続文字列名LocalSqlServerの値を指定しますWeb.config で接続文字列名 LocalSqlServer の値を上書きすると、既定の登録済みロール プロバイダー (AspNetSqlRoleProvider) を使用し、SecurityTutorials.mdf データベースと正しく連携させることができます。 この手法の詳細については、Scott Guthrie のブログ記事「ASP.NET 2.0 アプリケーション サービスを構成して SQL Server 2000 または SQL Server 2005 を使用する」を参照してください。
  • 型がSqlRoleProviderの新しい登録済みプロバイダーを追加し、そのconnectionStringName設定を、SecurityTutorials.mdfデータベースを指すように構成します。これは推奨されるアプローチであり、チュートリアル「SQL Server でメンバーシップ スキーマを作成する」で使用したアプローチです。このチュートリアルでも、このアプローチを使用します。

次のロール構成マークアップを Web.config ファイルに追加します。 このマークアップにより、SecurityTutorialsSqlRoleProvider という名前の新しいプロバイダーが登録されます。

<?xml version="1.0"?>    
<configuration>    
 <connectionStrings>    
 <add name="SecurityTutorialsConnectionString"    
 connectionString="..."/>    
 </connectionStrings>

 <system.web>    
 ... Additional configuration markup removed for brevity ...

 <roleManager enabled="true" defaultProvider="SecurityTutorialsSqlRoleProvider">    
 <providers>    
 <add name="SecurityTutorialsSqlRoleProvider"    
 type="System.Web.Security.SqlRoleProvider"    
 applicationName="SecurityTutorials"    
 connectionStringName="SecurityTutorialsConnectionString" />    
 </providers>    
 </roleManager>    
 <system.web>    
</configuration>

上記のマークアップにより、既定のプロバイダーとして SecurityTutorialsSqlRoleProvider が定義されます (<roleManager> 要素の defaultProvider 属性を使用します)。 また、SecurityTutorialsSqlRoleProviderapplicationName 設定が SecurityTutorials に設定されます。これは、メンバーシップ プロバイダー (SecurityTutorialsSqlMembershipProvider) で使用される applicationName 設定と同じです。 ここには示されていませんが、SqlRoleProvider<add> 要素 には、データベースのタイムアウト期間を秒単位で指定する commandTimeout 属性も含まれます。 既定値は 30 です。

この構成マークアップが完成すると、アプリケーションでロール機能の使用を開始できるようになります。

Note

上記の構成マークアップは、<roleManager> 要素の enabled および defaultProvider 属性の使用を示しています。 ロール フレームワークでユーザーごとにロール情報を関連付ける方法に影響を与える属性は、他にも多数あります。 これらの設定については、チュートリアル「ロールベースの承認」で確認します。

手順 3: ロール API を調べる

ロール フレームワークの機能は、Roles クラス を使用して公開されます。このクラスには、ロールベースの操作を実行するための 13 のメソッドが含まれています。 手順 4 と 6 でロールの作成と削除について説明する際に、ロールをシステムに追加する CreateRole メソッドとロールをシステムから削除する DeleteRole メソッドを使用します。

システム内のすべてのロールの一覧を取得するには、GetAllRoles メソッドを使用します (手順 5 を参照)。 RoleExists メソッドは、指定されたロールの有無を示すブール値を返します。

次のチュートリアルでは、ユーザーとロールを関連付ける方法を確認します。 Roles クラスの AddUserToRoleAddUserToRolesAddUsersToRoleAddUsersToRoles メソッドは、1 人以上のユーザーを 1 つ以上のロールに追加します。 ロールからユーザーを削除するには、RemoveUserFromRoleRemoveUserFromRolesRemoveUsersFromRole、または RemoveUsersFromRoles メソッドを使用します。

チュートリアル「ロールベースの承認」では、プログラムで、現在ログインしているユーザーのロールに基づいて機能を表示するか、または非表示にする方法について説明します。 これを実現するには、Role クラスの FindUsersInRoleGetRolesForUserGetUsersInRole、または IsUserInRole メソッドを使用します。

Note

これらのメソッドのいずれかが呼び出されるたびに、Roles クラスは、構成されたプロバイダーにその呼び出しを委任することに注意してください。 ここでは、これは、呼び出しが SqlRoleProvider に送信されることを意味します。 その後、SqlRoleProvider により、呼び出されたメソッドに基づいて適切なデータベース操作が実行されます。 たとえば、コード Roles.CreateRole("Administrators") により、SqlRoleProvider でストアド プロシージャ aspnet_Roles_CreateRole が実行され、Administrators という名前の新しいレコードが aspnet_Roles テーブルに挿入されます。

このチュートリアルの残りの部分では、Roles クラスの CreateRoleGetAllRolesDeleteRole メソッドを使用してシステム内のロールを管理する方法について説明します。

手順 4: 新しいロールの作成

ロールを使用すると、ユーザーを任意にグループ化できます。最も一般的には、このグループ化は認可規則をより便利な方法で適用するために使用されます。 ただし、ロールを認可メカニズムとして使用するには、まず、アプリケーションに存在するロールを定義する必要があります。 残念ながら、ASP.NET には、CreateRoleWizard コントロールが含まれていません。 新しいロールを追加するには、適切なユーザー インターフェイスを作成し、ロール API を自分で呼び出す必要があります。 幸いなことに、これは非常に簡単に実現できます。

Note

CreateRoleWizard Web コントロールはありませんが、ASP.NET Web サイト管理ツール があります。これは、Web アプリケーションの構成の表示と管理を支援するように設計されたローカル ASP.NET アプリケーションです。 ただし、次の 2 つの理由から、私は ASP.NET Web サイト管理ツールを非常に気に入っているわけではありません。 まず、これはバグが少々多く、ユーザー エクスペリエンスにも改善の余地が多く残っています。 2 つ目は、ASP.NET Web サイト管理ツールは、ローカルでのみ動作するように設計されています。つまり、リモートでライブ サイトのロールを管理する必要がある場合、独自のロール管理 Web ページを作成する必要があります。 これら 2 つの理由から、このチュートリアルと次のチュートリアルでは、ASP.NET Web サイト管理ツールに依存しないで、Web ページで必要なロール管理ツールを作成することに重点を置いて説明します。

Roles フォルダー内の ManageRoles.aspx ページを開き、このページに TextBox および Button Web コントロールを追加します。 TextBox コントロールの ID プロパティを RoleName に設定し、Button の ID および Text プロパティをそれぞれ CreateRoleButton と "ロールの作成" に設定します。 この時点で、ページの宣言型マークアップは次のようになります。

<b>Create a New Role: </b>
<asp:TextBox ID="RoleName" runat="server"></asp:TextBox>
<br />
<asp:Button ID="CreateRoleButton" runat="server" Text="Create Role" />

次に、デザイナーで CreateRoleButton Button コントロールをダブルクリックして Click イベント ハンドラーを作成し、次のコードを追加します。

protected void CreateRoleButton_Click(object sender, EventArgs e)
{
    string newRoleName = RoleName.Text.Trim();

    if (!Roles.RoleExists(newRoleName))
        // Create the role
        Roles.CreateRole(newRoleName);

    RoleName.Text = string.Empty;
}

上記のコードでは、まず、RoleName TextBox に入力された、トリミングされたロール名を変数 newRoleName に割り当てます。 次に、Roles クラスの RoleExists メソッドを呼び出して、ロール newRoleName がシステム内に既に存在しているかどうかを判断します。 このロールが存在していない場合、CreateRole メソッドを呼び出して作成します。 システム内に既に存在しているロール名が CreateRole メソッドに渡されると、ProviderException 例外がスローされます。 これは、コードで、CreateRole を呼び出す前に、まず、ロールがシステム内にまだ存在していないことが確認されているためです。 Click イベント ハンドラーは、RoleName TextBox の Text プロパティをクリアすると終了します。

Note

ユーザーが RoleName TextBox に値を入力しないとどうなるのか疑問に思うかもしれません。 CreateRole メソッドに渡される値が null または空の文字列である場合、例外が発生します。 同様に、ロール名にコンマが含まれている場合も例外が発生します。 そのため、ページには、ユーザーがロールを入力したことと、それにコンマが含まれていないことを確認するための検証コントロールが含まれている必要があります。 読者のための演習として残しておきます。

では、Administrators という名前のロールを作成してみましょう。 ブラウザーから ManageRoles.aspx ページにアクセスし、テキストボックスに「Administrators」と入力し (図 3 を参照)、[ロールの作成] ボタンをクリックします。

Create an Administrators Role

図 3: Administrators ロールを作成する (クリックするとフルサイズの画像が表示されます)

何が起きていますか? ポストバックは発生しますが、ロールが実際にシステムに追加されたことを示すビジュアル キューは提供されません。 手順 5 では、このページを更新して、視覚的なフィードバックが含まれるようにします。 ただし、現時点では、SecurityTutorials.mdf データベースにアクセスし、aspnet_Roles テーブルのデータを表示すると、ロールが作成されたことを確認できます。 図 4 に示すように、aspnet_Roles テーブルには、追加したばかりの Administrators ロールのレコードが含まれています。

The aspnet_Roles Table has a Row for the Administrators

図 4: Administrators の行が含まれた aspnet_Roles テーブル (クリックするとフルサイズの画像が表示されます)

手順 5: システム内のロールの表示

システム内の現在のロールの一覧を含めるように ManageRoles.aspx ページを拡張してみましょう。 これを実現するには、GridView コントロールをページに追加し、その ID プロパティを RoleList に設定します。 次に、次のコードを使用して、DisplayRolesInGrid という名前のメソッドをページの分離コード クラスに追加します。

private void DisplayRolesInGrid()
{
    RoleList.DataSource = Roles.GetAllRoles();
    RoleList.DataBind();
}

Roles クラスの GetAllRoles メソッドは、システム内のすべてのロールを文字列の配列として返します。 その後、この文字列配列は、GridView にバインドされます。 ページが最初に読み込まれるときにロールの一覧を GridView にバインドするには、ページの Page_Load イベント ハンドラーから DisplayRolesInGrid メソッドを呼び出す必要があります。 次のコードは、ページが最初にアクセスされたときにこのメソッドを呼び出しますが、後続のポストバックでは呼び出しません。

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    DisplayRolesInGrid();
}

このコードを配置したら、ブラウザーからページにアクセスします。 図 5 に示すように、Item というラベルの付いた単一の列を含むグリッドが表示されます。 このグリッドには、手順 4 で追加した Administrators ロールの行が含まれています。

The GridView Displays the Roles in a Single Column

図 5: 単一の列にロールを表示する GridView (クリックするとフルサイズの画像が表示されます)

GridView には、Item というラベルの付いた列だけが表示されています。これは、GridView の AutoGenerateColumns プロパティが True (既定値) に設定されており、GridView によって、DataSource 内の各プロパティの列が自動的に作成されるためです。 配列には、配列内の要素を表す 1 つのプロパティがあるため、GridView に単一の列が表示されます。

GridView でデータを表示する場合、GridView によって暗黙的に生成された列を含めるのではなく、列を自分で明示的に定義することをお勧めします。 列を明示的に定義すると、データの書式設定、列の並べ替え、その他の一般的なタスクの実行がはるかに容易になります。 そのため、GridView の宣言的マークアップを更新して列を明示的に定義することにしましょう。

まず、GridView の AutoGenerateColumns プロパティを False に設定します。 次に、TemplateField をグリッドに追加し、その HeaderText プロパティを "ロール" に設定し、その ItemTemplate を、配列の内容を表示するように構成します。 これを実現するには、RoleNameLabel という名前の Label Web コントロールを ItemTemplate に追加し、その Text プロパティを Container.DataItem にバインドします。

これらのプロパティと ItemTemplate の内容は、宣言によって設定するか、または GridView の [フィールド] ダイアログ ボックスと [テンプレートの編集] インターフェイスを使用して設定することができます。 [フィールド] ダイアログ ボックスにアクセスするには、GridView のスマート タグで [列の編集] リンクをクリックします。 次に、[フィールドの自動生成] チェックボックスをオフにして、AutoGenerateColumns プロパティを False に設定し、TemplateField を GridView に追加して、その HeaderText プロパティを "ロール" に設定します。 ItemTemplate の内容を定義するには、GridView のスマート タグから [テンプレートの編集] オプションを選択します。 Label Web コントロールを ItemTemplate にドラッグし、その ID プロパティを RoleNameLabel に設定して、Text プロパティを Container.DataItem にバインドするようにデータバインド設定を構成します。

完了すると、使用するアプローチに関係なく、GridView で生成される宣言型マークアップは、次のようになります。

<asp:GridView ID="RoleList" runat="server" AutoGenerateColumns="false">    
 <Columns>    
 <asp:TemplateField HeaderText="Role">    
 <ItemTemplate>    
 <asp:Label runat="server" ID="RoleNameLabel" Text='<%# Container.DataItem %>' />    
 </ItemTemplate>    
 </asp:TemplateField>    
 </Columns>    
</asp:GridView>

Note

配列の内容は、データバインド構文 <%# Container.DataItem %> を使用して表示されます。 GridView にバインドされた配列の内容を表示するときにこの構文を使用する理由の詳しい説明は、このチュートリアルの範囲外です。 この理由の詳細については、データ Web コントロールへのスカラー配列のバインドに関するページをご覧ください。

現在、RoleList GridView は、ページが最初にアクセスされたときにのみロールの一覧にバインドされます。 新しいロールが追加されるたびにグリッドを更新する必要があります。 これを実現するには、新しいロールが作成された場合に DisplayRolesInGrid メソッドを呼び出すように CreateRoleButton Button の Click イベント ハンドラーを更新します。

protected void CreateRoleButton_Click(object sender, EventArgs e)    
{    
    string newRoleName = RoleName.Text.Trim();

    if (!Roles.RoleExists(newRoleName))    
    {    
        // Create the role    
        Roles.CreateRole(newRoleName);

        // Refresh the RoleList Grid    
        DisplayRolesInGrid();    
    }

    RoleName.Text = string.Empty;    
}

これで、ユーザーが新しいロールを追加すると、RoleList GridView により、追加されたばかりのロールがポストバックに表示され、ロールが正常に作成されたことを示す視覚的なフィードバックが提供されるようになりました。 これを示すために、ブラウザーから ManageRoles.aspx ページにアクセスし、Supervisors という名前のロールを追加します。 [ロールの作成] ボタンをクリックすると、ポストバックが発生し、グリッドが更新されて、Administrators と新しいロール Supervisors が含まれます。

The Supervisors Role has Been Added

図 6: 追加された Supervisors ロール (クリックするとフルサイズの画像が表示されます)

手順 6: ロールの削除

この時点で、ユーザーは、ManageRoles.aspx ページで、新しいロールを作成し、すべての既存のロールを表示できます。 ユーザーがロールの削除も実行できるようにしてみましょう。 Roles.DeleteRole メソッドには、次の 2 つのオーバーロードが含まれます。

  • DeleteRole(roleName) - ロール roleName を削除します。 ロールに 1 つ以上のメンバーが含まれている場合、例外がスローされます。
  • DeleteRole(roleName, throwOnPopulatedRole) - ロール roleName を削除します。 throwOnPopulateRoletrue の場合、ロールに 1 つ以上のメンバーが含まれていると、例外がスローされます。 throwOnPopulateRolefalse の場合、ロールにメンバーが含まれているかどうかにかかわらず、ロールは削除されます。 内部的には、DeleteRole(roleName) メソッドは DeleteRole(roleName, true) を呼び出します。

roleNamenull または空の文字列の場合、または roleName にコンマが含まれている場合も、DeleteRole メソッドは例外をスローします。 roleName がシステムに存在しない場合、DeleteRole は警告なしに失敗し、例外も発生しません。

クリックされたときに、選択されたロールを削除する [削除] ボタンを含むように、ManageRoles.aspx で GridView を拡張してみましょう。 まず、[フィールド] ダイアログ ボックスにアクセスし、CommandField オプションの下にある [削除] ボタンを追加して、GridView に [削除] ボタンを追加します。 [削除] ボタンを左端の列にし、その DeleteText プロパティを "ロールの削除" に設定します。

Add a Delete Button to the RoleList GridView

図 7: [削除] ボタンを RoleList GridView に追加する (クリックするとフルサイズの画像が表示されます)

[削除] ボタンを追加すると、GridView の宣言型マークアップは次のようになります。

<asp:GridView ID="RoleList" runat="server" AutoGenerateColumns="False">
 <Columns>
 <asp:CommandField DeleteText="Delete Role" ShowDeleteButton="True"/>
 <asp:TemplateField HeaderText="Role">
 <ItemTemplate>
 <asp:Label runat="server" ID="RoleNameLabel" Text='<%# Container.DataItem %>' />
 </ItemTemplate>
 </asp:TemplateField>
 </Columns>
</asp:GridView>

次に、GridView の RowDeleting イベントのイベント ハンドラーを作成します。 これは、[ロールの削除] ボタンがクリックされたときにポストバックで発生するイベントです。 イベント ハンドラーに次のコードを追加します。

protected void RoleList_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    // Get the RoleNameLabel
    Label RoleNameLabel = RoleList.Rows[e.RowIndex].FindControl("RoleNameLabel") as Label;

    // Delete the role
    Roles.DeleteRole(RoleNameLabel.Text, false);

    // Rebind the data to the RoleList grid
    DisplayRolesInGrid();
}

このコードでは、まず、[ロールの削除] ボタンがクリックされた行の RoleNameLabel Web コントロールをプログラムで参照します。 その後、Roles.DeleteRole メソッドが呼び出され、RoleNameLabelfalseText が渡されます。これにより、ロールに関連付けられているユーザーの有無にかかわらず、ロールが削除されます。 最後に、RoleList GridView が更新され、削除されたばかりのロールはグリッドに表示されなくなります。

Note

[ロールの削除] ボタンでは、ロールを削除する前に、ユーザーに対してどのような種類の確認も求められません。 アクションを確認するための最も簡単な方法の 1 つは、クライアント側の確認ダイアログ ボックスを使用することです。 この手法の詳細については、「削除時、クライアント側の確認を追加する」を参照してください。

まとめ

多くの Web アプリケーションには、特定の認可規則、または特定のクラスのユーザーのみが使用できるページレベルの機能があります。 たとえば、管理者のみがアクセスできる一連の Web ページが存在する場合があります。 多くの場合、これらの認可規則をユーザーごとに定義するのではなく、ロールに基づいて規則を定義する方が便利です。 つまり、ユーザー Scott と Jisun に管理 Web ページへのアクセスを明示的に許可するのではなく、Administrators ロールのメンバーにこれらのページへのアクセスを許可し、Scott と Jisun を Administrators ロールに属するユーザーとして指定する方が、保守が容易になります。

ロール フレームワークを使用すると、ロールを簡単に作成して管理できます。 このチュートリアルでは、Microsoft SQL Server データベースをロール ストアとして使用する SqlRoleProvider を使用するようにロール フレームワークを構成する方法を調べました。 また、システム内の既存のロールを一覧表示し、新しいロールを作成し、既存のロールを削除できる Web ページも作成しました。 以降のチュートリアルでは、ユーザーにロールを割り当てる方法と、ロールベースの認可を適用する方法について説明します。

プログラミングに満足!

もっと読む

この記事で説明したトピックの詳細については、次のリソースを参照してください。

作成者について

ASP および ASP.NET に関して複数の著作があり、4GuysFromRolla.com の創設者でもある Scott Mitchell は、1998 年から Microsoft Web のテクノロジに携わっています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 Mitchell には、mitchell@4guysfromrolla.com で、または彼のブログ (http://ScottOnWriting.NET) を通じて連絡することができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者には、Alicja Maziarz、Suchi Banerjee、Teresa Murphy が含まれます。 今後の MSDN の記事を確認することに関心がありますか? ご希望の場合は、mitchell@4GuysFromRolla.com 宛にメールをお送りください