ロールベースの承認 (C#)
Note
この記事を作成した後で、ASP.NET メンバーシップ プロバイダーよりも ASP.NET Identity のほうが適切になりました。 この記事の作成時点で紹介されている Membership プロバイダーではなく、ASP.NET Identity プラットフォームを使うようにアプリを更新することを強くお勧めします。 ASP.NET メンバーシップ システムと比べると、ASP.NET Identity には次のような多くの利点があります。
- パフォーマンスの向上
- 向上した拡張性とテストの容易性
- OAuth、OpenID Connect、2 要素認証のサポート
- クレームベースの ID のサポート
- ASP.Net Core との相互運用性の向上
このチュートリアルでは、まず Roles フレームワークでユーザーのロールをそのユーザーのセキュリティ コンテキストに関連付ける方法について説明します。 次に、ロール ベースの URL 認可規則を適用する方法について調べます。 その後、表示されるデータや ASP.NET ページで提供される機能を変更するための宣言型の方法とプログラムによる方法の使用について説明します。
はじめに
「ユーザー ベースの認可」のチュートリアルでは、URL 認可を使用して、特定の一連のページにアクセスできるユーザーを指定する方法について説明しました。 Web.config
内のほんの少しのマークアップを使用して、認証されたユーザーだけがページにアクセスできるようにするよう ASP.NET に指示することができました。 あるいは、ユーザー Tito と Bob だけが許可されるように規定したり、Sam を除くすべての認証されたユーザーが許可されるように指定したりすることができました。
URL 認可に加えて、アクセスしているユーザーに基づいて、表示されるデータやページで提供される機能を制御するための宣言型の方法とプログラムによる方法についても説明しました。 特に、現在のディレクトリの内容を一覧表示するページを作成しました。 このページには誰でもアクセスできますが、認証されたユーザーだけがファイルの内容を表示でき、Tito だけがファイルを削除できました。
認可規則をユーザーごとに適用すると、ブックキーピングが非常に面倒になる場合があります。 より保守しやすいアプローチは、ロール ベースの認可を使用することです。 幸いなことに、認可規則を適用するために自由に使用できるツールは、ロールに対してもユーザー アカウントに対する場合と同様に適切に機能します。 URL 認可規則では、ユーザーの代わりにロールを指定できます。 認証されたユーザーと匿名ユーザーに対して異なる出力をレンダリングする LoginView コントロールは、ログインしているユーザーのロールに基づいて異なるコンテンツ表示するように構成できます。 また、Roles API には、ログインしているユーザーのロールを特定するためのメソッドが含まれています。
このチュートリアルでは、まず Roles フレームワークでユーザーのロールをそのユーザーのセキュリティ コンテキストに関連付ける方法について説明します。 次に、ロール ベースの URL 認可規則を適用する方法について調べます。 その後、表示されるデータや ASP.NET ページで提供される機能を変更するための宣言型の方法とプログラムによる方法の使用について説明します。 それでは始めましょう。
ロールがユーザーのセキュリティ コンテキストに関連付けられる方法の理解
要求は、ASP.NET パイプラインに入力されるたびに、要求元を識別する情報が含まれているセキュリティ コンテキストに関連付けられます。 フォーム認証を使用している場合は、ID トークンとして認証チケットが使用されます。 「フォーム認証の概要」のチュートリアルで説明したように、FormsAuthenticationModule
は要求元の ID を特定する役割を果たします。これは、AuthenticateRequest
イベント中に実行されます。
有効期限が切れていない有効な認証チケットが見つかった場合、FormsAuthenticationModule
は、それをデコードして要求元の ID を確認します。 新しい GenericPrincipal
オブジェクトを作成し、これを HttpContext.User
オブジェクトに割り当てます。 プリンシパル (GenericPrincipal
など) の目的は、認証されたユーザーの名前とそのユーザーが属しているロールを識別することです。 この目的は、すべてのプリンシパル オブジェクトに Identity
プロパティと IsInRole(roleName)
メソッドがあるという事実により明らかです。 ただし、FormsAuthenticationModule
ではロール情報の記録は行われず、それによって作成される GenericPrincipal
オブジェクトでもロールは指定されません。
Roles フレームワークが有効になっている場合は、RoleManagerModule
HTTP モジュールが FormsAuthenticationModule
の後にステップ インし、認証されたユーザーのロールを AuthenticateRequest
イベントの後に発生する PostAuthenticateRequest
イベント中に識別します。 その要求が認証されたユーザーからのものである場合、RoleManagerModule
は FormsAuthenticationModule
によって作成された GenericPrincipal
オブジェクトを上書きし、それを RolePrincipal
オブジェクトに置き換えます。 RolePrincipal
クラスは Roles API を使用して、そのユーザーが属しているロールを特定します。
図 1 は、フォーム認証と Roles フレームワークを使用しているときの ASP.NET パイプライン ワークフローを示しています。 最初に FormsAuthenticationModule
が実行され、そのユーザーの認証チケットを使用してユーザーを識別し、新しい GenericPrincipal
オブジェクトを作成します。 次に、RoleManagerModule
がステップ インし、GenericPrincipal
オブジェクトを RolePrincipal
オブジェクトで上書きします。
匿名ユーザーがサイトにアクセスした場合は、FormsAuthenticationModule
も RoleManagerModule
もプリンシパル オブジェクトを作成しません。
図 1: フォーム認証と Roles フレームワークを使用しているときの認証されたユーザーのための ASP.NET パイプライン イベント (クリックするとフルサイズの画像が表示されます)
ロール情報の Cookie へのキャッシュ
RolePrincipal
オブジェクトの IsInRole(roleName)
メソッドは、Roles.GetRolesForUser
を呼び出してユーザーのロールを取得することにより、そのユーザーが roleName のメンバーであるかどうかを判定します。 SqlRoleProvider
を使用している場合は、これにより、ロール ストア データベースへのクエリが生成されます。 ロール ベースの URL 認可規則を使用している場合、RolePrincipal
の IsInRole
メソッドは、ロール ベースの URL 認可規則によって保護されているページへの要求が発生するたびに呼び出されます。 要求のたびにデータベース内のロール情報を検索しなくても済むように、ロール フレームワークには、ユーザーのロールを Cookie にキャッシュするオプションが含まれています。
Roles フレームワークがユーザーのロールを Cookie にキャッシュするように構成されている場合、RoleManagerModule
は、ASP.NET パイプラインの EndRequest
イベント中に Cookie を作成します。 この Cookie は、それ以降の要求の、RolePrincipal
オブジェクトが作成される PostAuthenticateRequest
で使用されます。 Cookie が有効で、かつ有効期限が切れていない場合は、Cookie 内のデータが解析され、ユーザーのロールを設定するために使用されます。これにより、RolePrincipal
は、ユーザーのロールを特定するために Roles
クラスを呼び出す必要がなくなります。 図 2 は、このワークフローを示しています。
図 2: ユーザーのロール情報を Cookie に格納してパフォーマンスを向上させることができる (クリックするとフルサイズの画像が表示されます)
既定では、ロール キャッシュ Cookie のメカニズムは無効になっています。 これは、Web.config
内の <roleManager>
; 構成マークアップを使用して有効にすることができます。 <roleManager>
要素を使用したロール プロバイダーの指定については「ロールの作成と管理」のチュートリアルで説明したため、アプリケーションの Web.config
ファイルにはこの要素が既に含まれているはずです。 ロール キャッシュ Cookie の設定は <roleManager>
; 要素の属性として指定され、表 1 にまとめられています。
Note
表 1 に一覧表示されている構成設定は、結果として得られるロール キャッシュ Cookie のプロパティを示しています。 Cookie と、そのしくみ、さまざまなプロパティの詳細については、この Cookie のチュートリアルを参照してください。
プロパティ | 説明 |
---|---|
cacheRolesInCookie |
Cookie のキャッシュが使用されているかどうかを示すブール値。 既定値は false です。 |
cookieName |
ロール キャッシュ Cookie の名前。 既定値は ".ASPXROLES" です。 |
cookiePath |
ロール名の Cookie のパス。 パス属性を使用すると、開発者は Cookie のスコープを特定のディレクトリ階層に制限できます。 既定値は "/" です。これは、そのドメインに対して行われたすべての要求に認証チケット Cookie を送信するようブラウザーに通知します。 |
cookieProtection |
ロール キャッシュ Cookie を保護するためにどのような手法が使用されるかを示します。 許容される値は、All (既定値)、Encryption 、None 、Validation です。 |
cookieRequireSSL |
認証 Cookie を送信するために SSL 接続が必要かどうかを示すブール値。 既定値は false です。 |
cookieSlidingExpiration |
ユーザーが 1 回のセッション中にサイトにアクセスするたびに Cookie のタイムアウトがリセットされるかどうかを示すブール値。 既定値は false です。 この値は、createPersistentCookie が true に設定されている場合のみ関連します。 |
cookieTimeout |
認証チケット Cookie の有効期限が切れる時間を分単位で指定します。 既定値は 30 です。 この値は、createPersistentCookie が true に設定されている場合のみ関連します。 |
createPersistentCookie |
ロール キャッシュ Cookie がセッション Cookie か永続 Cookie かを指定するブール値。 false (既定値) の場合、セッション Cookie が使用され、ブラウザーが閉じられると削除されます。 true である場合、永続 Cookie が使用されると、cookieSlidingExpiration の値に応じて、作成後または前回のアクセス後の cookieTimeout の時間 (分) の有効期限が切れます。 |
domain |
Cookie のドメイン値を指定します。 既定値は空の文字列です。これにより、ブラウザーは発行元からのドメイン (www.yourdomain.com など) に使用されます。 この場合、admin.yourdomain.com などのサブドメインに要求を行うときに Cookie は送信されません。 Cookie をすべてのサブドメインに渡す場合は domain 属性をカスタマイズ、それを "yourdomain.com" に設定する必要があります。 |
maxCachedResults |
Cookie にキャッシュされるロール名の最大数を指定します。 既定値は 25 です。 RoleManagerModule では、maxCachedResults 以上のロールに属するユーザーの Cookie は作成されません。 その結果、RolePrincipal オブジェクトの IsInRole メソッドは Roles クラスを使用してユーザーのロールを決定します。 多くのユーザー エージェントが 4,096 バイトを超える Cookie を許可していないため、maxCachedResults が存在します。 そのため、この上限は、このサイズ制限を超える可能性を軽減することを目的とします。 ロール名が非常に長い場合は、より小さな maxCachedResults 値を指定することを検討する必要がある場合があります。逆に、ロール名が非常に短い場合は、この値を増やすことができる可能性があります。 |
表 1: ロール キャッシュ Cookie の構成オプション
非永続的なロール キャッシュ Cookie を使用するようにアプリケーションを構成しましょう。 これを実現するには、Web.config
内の <roleManager>
要素を次の cookie 関連の属性が含まれるように更新します。
<roleManager enabled="true"
defaultProvider="SecurityTutorialsSqlRoleProvider"
cacheRolesInCookie="true"
createPersistentCookie="false"
cookieProtection="All">
<providers>
...
</providers>
</roleManager>
ここでは、cacheRolesInCookie
、createPersistentCookie
、cookieProtection
の 3 つの属性を追加することによって <roleManager>
要素を更新しました。 cacheRolesInCookie
を true
に設定することにより、RoleManagerModule
はユーザーのロールを自動的に Cookie にキャッシュするようになり、要求のたびにユーザーのロール情報を検索しなくても済みます。 また、createPersistentCookie
および cookieProtection
属性をそれぞれ false
と All
に明示的に設定しました。 技術的には、これらの属性は既定値に割り当てたばかりであるため、それらの値を指定する必要はなかったのですが、永続的な Cookie を使用しておらず、この Cookie には暗号化と検証の両方が行われていることを明示的に明らかにするために、ここに配置しました。
これですべて完了です。 この後、Roles フレームワークによってユーザーのロールが Cookie にキャッシュされます。 ユーザーのブラウザーが Cookie をサポートしていなかったり、Cookie が何らかの理由で削除されたり、失われたりしていても大きな問題ではありません。Cookie が使用できない (または、無効か、有効期限が切れている) 場合、RolePrincipal
オブジェクトは単純に Roles
クラスを使用します。
Note
Microsoft の Patterns & Practices グループは、永続的なロール キャッシュ Cookie の使用をお勧めしません。 ロール メンバーシップを証明するにはロール キャッシュ Cookie を所有するだけで十分であるため、ハッカーが有効なユーザーの Cookie へのアクセス権を何らかの方法で取得できた場合は、そのユーザーを偽装できます。 Cookie がユーザーのブラウザー上に永続化されていると、これが発生する可能性が高くなります。 このセキュリティに関する推奨事項やその他のセキュリティ上の問題の詳細については、ASP.NET 2.0 のセキュリティに関する質問の一覧に関するページを参照してください。
手順 1: ロール ベースの URL 認可規則の定義
「ユーザー ベースの認可」のチュートリアルで説明したように、URL 認可は、ユーザーまたはロールごとに一連のページへのアクセスを制限するための手段を提供します。 URL 認可規則は、Web.config
内で <allow>
と <deny>
の子要素を含む <authorization>
要素を使用して指定されます。 前のチュートリアルで説明したユーザー関連の認可規則に加えて、<allow>
と <deny>
の各子要素には、次のものも含めることができます。
- 特定のロール
- ロールのコンマ区切りリスト
たとえば、URL 認可規則では、管理者およびスーパーバイザー ロールのユーザーにはアクセス権を付与するが、その他のすべてのユーザーにはアクセス権を拒否することができます。
<authorization>
<allow roles="Administrators, Supervisors" />
<deny users="*" />
</authorization>
上記のマークアップ内の <allow>
要素は管理者およびスーパーバイザー ロールが許可されることを、<deny>
; 要素は "すべての" ユーザーが拒否されることを示しています。
ManageRoles.aspx
、UsersAndRoles.aspx
、CreateUserWizardWithRoles.aspx
の各ページが管理者ロールのユーザーからしかアクセスできないのに対して、RoleBasedAuthorization.aspx
ページはすべてのビジターからアクセス可能のままになるようにアプリケーションを構成しましょう。
これを実現するには、まず Roles
フォルダーに Web.config
ファイルを追加します。
図 3: Roles
ディレクトリに Web.config
ファイルを追加する (クリックするとフルサイズの画像が表示されます)
次に、Web.config
に次の構成マークアップを追加します。
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles="Administrators" />
<deny users="*"/>
</authorization>
</system.web>
<!-- Allow all users to visit RoleBasedAuthorization.aspx -->
<location path="RoleBasedAuthorization.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
</configuration>
<system.web>
セクション内の <authorization>
要素は、Roles
ディレクトリ内の ASP.NET リソースには管理者ロールのユーザーしかアクセスできないことを示します。 <location>
要素は、RoleBasedAuthorization.aspx
ページに対する一連の代替の URL 認可規則を定義し、すべてのユーザーがこのページにアクセスできるようにします。
Web.config
への変更内容を保存したら、管理者ロールに属していないユーザーとしてログインし、保護されたページのいずれかにアクセスしてみてください。 UrlAuthorizationModule
は、要求されたリソースにアクセスするためのアクセス許可を持っていないことを検出し、それにより FormsAuthenticationModule
によってログイン ページにリダイレクトされます。 その後、ログイン ページによって UnauthorizedAccess.aspx
ページ (図 4 を参照) にリダイレクトされます。 このログイン ページから UnauthorizedAccess.aspx
への最後のリダイレクトは、「ユーザー ベースの認可」のチュートリアルの手順 2 でログイン ページに追加したコードのために発生します。 特に、クエリ文字列に ReturnUrl
パラメーターが含まれている場合、このパラメーターは、ユーザーが表示を認可されていないページを表示しようとした後にログイン ページに到達したことを示すため、ログイン ページにより、すべての認証されたユーザーが自動的に UnauthorizedAccess.aspx
にリダイレクトされます。
図 4: 保護されたページは管理者ロールのユーザーしか表示できない (クリックするとフルサイズの画像が表示されます)
ログオフしてから、管理者ロールに属しているユーザーとしてログインします。 今度は、3 つの保護されたページを表示できるはずです。
図 5: Tito は管理者ロールに属しているため UsersAndRoles.aspx
ページにアクセスできる (クリックするとフルサイズの画像が表示されます)
Note
URL 認可規則を (ロールまたはユーザーごとに) 指定する場合は、それらの規則が一番上から下に 1 つずつ分析される点に注意することが重要です。 一致が見つかるとすぐに、一致が <allow>
または <deny>
のどちらの要素で見つかったかに応じて、そのユーザーにアクセス権が付与または拒否されます。 一致が見つからなかった場合は、そのユーザーにアクセス権が付与されます。 そのため、アクセスを 1 つ以上のユーザー アカウントに制限したい場合は、必ず URL 認可構成内の最後の要素として <deny>
要素を使用する必要があります。 URL 認可規則に <deny>
要素が含まれていない場合は、すべてのユーザーにアクセス権が付与されます。URL 認可規則が分析される方法の詳細については、「ユーザー ベースの認可」のチュートリアルの UrlAuthorizationModule
で認可規則を使用してアクセス権を付与または拒否する方法に関するセクションを参照し直してください。
手順 2: 現在ログインしているユーザーのロールに基づいた機能の制限
URL 認可により、特定のページ (または、あるフォルダーとそのサブフォルダー内のすべてのページ) の表示をどの ID が許可され、どの ID が拒否されるかを示す粗い認可規則を指定することが容易になります。 ただし、特定のケースでは、ページへのアクセスはすべてのユーザーに許可するが、アクセスしているユーザーのロールに基づいてページの機能を制限したい場合があります。 これには、ユーザーのロールに基づいてデータを表示または非表示にしたり、特定のロールに属しているユーザーに追加機能を提供したりすることか必要になる場合があります。
このようなきめ細かいロール ベースの認可規則は、宣言的にまたはプログラムで (あるいは、この 2 つの何らかの組み合わせを使用して) 実装できます。 次のセクションでは、LoginView コントロールを使用して、宣言型のきめ細かい認可を実装する方法について説明します。 その後、プログラムによる方法について調べます。 ただし、きめ細かい認可規則の適用を確認するには、最初に、アクセスしているユーザーのロールによって異なる機能を持つページを作成する必要があります。
システム内のすべてのユーザー アカウントを GridView に一覧表示するページを作成しましょう。 GridView には、各ユーザーのユーザー名、メール アドレス、最後のログイン日付、そのユーザーに関するコメントが含まれます。 各ユーザーの情報の表示に加えて、GridView には編集および削除機能が含まれます。 最初に、すべてのユーザーが編集および削除機能を使用できるようにこのページを作成します。 「LoginView コントロールの使用」と「プログラムによる機能の制限」のセクションでは、アクセスしているユーザーのロールに基づいて、これらの機能を有効または無効にする方法について説明します。
Note
作成しようとしている ASP.NET ページでは、GridView コントロールを使用してユーザー アカウントを表示します。 このチュートリアル シリーズでは、フォーム認証、認可、ユーザー アカウント、ロールに焦点を絞っているため、GridView コントロールの内側動作の説明にはあまり時間を費やしたくありません。 このチュートリアルでは、このページを設定するための具体的な詳しい手順を提供しますが、特定の選択が行われた理由や、特定のプロパティがレンダリングされる出力に与える影響の詳細については詳しく説明しません。 GridView コントロールの詳細な確認については、「ASP.NET 2.0 でのデータの操作」のチュートリアル シリーズを参照してください。
まず、Roles
フォルダーの RoleBasedAuthorization.aspx
ページを開きます。 GridView をこのページからデザイナーにドラッグし、その ID
を UserGrid
に設定します。 しばらく待ってから Membership.GetAllUsers
メソッドを呼び出し、結果の MembershipUserCollection
オブジェクトを GridView にバインドするコードを記述します。 MembershipUserCollection
には、システム内の各ユーザー アカウントの MembershipUser
オブジェクトが含まれており、MembershipUser
オブジェクトには UserName
、Email
、LastLoginDate
などのプロパティがあります。
ユーザー アカウントをグリッドにバインドするコードを記述する前に、まず GridView のフィールドを定義しましょう。 GridView のスマート タグから、[列の編集] リンクをクリックして [フィールド] ダイアログ ボックスを起動します (図 6 を参照)。 ここから、左下隅にある [フィールドの自動生成] チェックボックスをオフにします。 この GridView には編集および削除機能を含めたいため、CommandField を追加し、その ShowEditButton
および ShowDeleteButton
プロパティを True に設定します。 次に、UserName
、Email
、LastLoginDate
、Comment
の各プロパティを表示するための 4 つのフィールドを追加します。 2 つの読み取り専用プロパティ (UserName
と LastLoginDate
) には BoundField を、2 つの編集可能フィールド (Email
と Comment
) には TemplateField を使用します。
最初の BoundField に UserName
プロパティを表示させ、その HeaderText
および DataField
プロパティを "UserName" に設定します。 このフィールドは編集可能にならないため、その ReadOnly
プロパティを True に設定します。 LastLoginDate
BoundField を、その HeaderText
を "Last Login" に、その DataField
を "LastLoginDate" に設定することによって構成します。 この BoundField の出力を (日付と時刻の代わりに) 日付だけが表示されるように書式設定しましょう。 これを実現するには、この BoundField の HtmlEncode
プロパティを False に、その DataFormatString
プロパティを "{0:d}" に設定します。 また、ReadOnly
プロパティを True に設定します。
2 つの TemplateField の HeaderText
プロパティを "Email" と "Comment" に設定します。
図 6: GridView のフィールドは [フィールド] ダイアログ ボックスで構成できる (クリックするとフルサイズの画像が表示されます)
次に、"Email" および "Comment" TemplateField の ItemTemplate
と EditItemTemplate
を定義する必要があります。 それぞれの ItemTemplate
に Label Web コントロールを追加し、Text
プロパティを Email
および Comment
プロパティにそれぞれバインドします。
"Email" TemplateField の場合は、その EditItemTemplate
に Email
という名前の TextBox を追加し、双方向データ バインドを使用して、その Text
プロパティを Email
プロパティにバインドします。 EditItemTemplate
に RequiredFieldValidator と RegularExpressionValidator を追加して、Email プロパティを編集しているビジターが有効なメール アドレスを入力したことを確認します。 "Comment" TemplateField の場合は、その EditItemTemplate
に Comment
という名前の複数行の TextBox を追加します。 TextBox の Columns
および Rows
プロパティをそれぞれ 40 と 4 に設定してから、双方向データ バインドを使用して、その Text
プロパティを Comment
プロパティにバインドします。
これらの TemplateField を構成すると、その宣言型マークアップは次のようになります。
<asp:TemplateField HeaderText="Email">
<ItemTemplate>
<asp:Label runat="server" ID="Label1" Text='<%# Eval("Email") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="Email" Display="Dynamic"
ErrorMessage="You must provide an email address."
SetFocusOnError="True">*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
ControlToValidate="Email" Display="Dynamic"
ErrorMessage="The email address you have entered is not valid. Please fix
this and try again."
SetFocusOnError="True"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
</asp:RegularExpressionValidator>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Comment">
<ItemTemplate>
<asp:Label runat="server" ID="Label2" Text='<%# Eval("Comment") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="Comment" TextMode="MultiLine"
Columns="40" Rows="4" Text='<%# Bind("Comment") %>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
ユーザー アカウントを編集または削除するときは、そのユーザーの UserName
プロパティ値がわかっている必要があります。 この情報を GridView の DataKeys
コレクションから取得できるように、GridView の DataKeyNames
プロパティを "UserName" に設定します。
最後に、このページに ValidationSummary コントロールを追加し、その ShowMessageBox
プロパティを True に、その ShowSummary
プロパティを False に設定します。 これらの設定により、ユーザーがメール アドレスがないか、または無効な状態でユーザー アカウントを編集しようとすると、ValidationSummary にクライアント側のアラートが表示されます。
<asp:ValidationSummary ID="ValidationSummary1"
runat="server"
ShowMessageBox="True"
ShowSummary="False" />
これで、このページの宣言型マークアップが完了しました。 次のタスクは、一連のユーザー アカウントを GridView にバインドすることです。 RoleBasedAuthorization.aspx
ページの分離コード クラスに、Membership.GetAllUsers
によって返された MembershipUserCollection
を UserGrid
GridView にバインドする BindUserGrid
という名前のメソッドを追加します。 このメソッドは、最初のページ アクセス時に Page_Load
イベント ハンドラーから呼び出します。
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindUserGrid();
}
private void BindUserGrid()
{
MembershipUserCollection allUsers = Membership.GetAllUsers();
UserGrid.DataSource = allUsers;
UserGrid.DataBind();
}
このコードを有効にして、ブラウザー経由でこのページにアクセスします。 図 7 に示すように、システム内の各ユーザー アカウントに関する情報が一覧表示された GridView が表示されます。
図 7: システム内の各ユーザーに関する情報が一覧表示された UserGrid
GridView (クリックするとフルサイズの画像が表示されます)
Note
UserGrid
GridView には、すべてのユーザーがページングされていないインターフェイスで一覧表示されます。 この単純なグリッド インターフェイスは、ユーザーが数十人以上存在するシナリオには適していません。 1 つのオプションは、ページングを有効にするように GridView を構成することです。 Membership.GetAllUsers
メソッドには、次の 2 つのオーバーロードがあります。入力パラメーターを受け付けず、すべてのユーザーを返すものと、ページ インデックスとページ サイズの整数値を受け取り、ユーザーの指定されたサブセットのみを返すものです。 2 つ目のオーバーロードでは、"すべての" ユーザー アカウントではなく、その正確なサブセットのみが返されるため、これによりユーザーをより効率的にページングできます。 数千のユーザー アカウントが存在する場合は、たとえば、選択された文字で始まる UserName を持つユーザーのみが表示されるフィルター ベースのインターフェイスを検討することもできます。 Membership.FindUsersByName method
は、フィルターベースのユーザー インターフェイスを構築するために最適です。 このようなインターフェイスの構築については、今後のチュートリアルで説明します。
GridView コントロールでは、このコントロールが正しく構成されたデータ ソース コントロール (SqlDataSource や ObjectDataSource など) にバインドされている場合、組み込みの編集および削除サポートが提供されます。 ただし、UserGrid
GridView では、そのデータがプログラムでバインドされているため、これらの 2 つのタスクを実行するコードを記述する必要があります。 特に、ビジターが GridView の [編集]、[キャンセル]、[更新]、または [削除] ボタンをクリックすると発生する GridView の RowEditing
、RowCancelingEdit
、RowUpdating
、RowDeleting
イベントのイベント ハンドラーを作成する必要があります。
まず、GridView の RowEditing
、RowCancelingEdit
、RowUpdating
イベントのイベント ハンドラーを作成し、次のコードを追加します。
protected void UserGrid_RowEditing(object sender, GridViewEditEventArgs e)
{
// Set the grid's EditIndex and rebind the data
UserGrid.EditIndex = e.NewEditIndex;
BindUserGrid();
}
protected void UserGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
// Revert the grid's EditIndex to -1 and rebind the data
UserGrid.EditIndex = -1;
BindUserGrid();
}
protected void UserGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
// Exit if the page is not valid
if (!Page.IsValid)
return;
// Determine the username of the user we are editing
string UserName = UserGrid.DataKeys[e.RowIndex].Value.ToString();
// Read in the entered information and update the user
TextBox EmailTextBox = UserGrid.Rows[e.RowIndex].FindControl("Email") as TextBox;
TextBox CommentTextBox = UserGrid.Rows[e.RowIndex].FindControl("Comment") as TextBox;
// Return information about the user
MembershipUser UserInfo = Membership.GetUser(UserName);
// Update the User account information
UserInfo.Email = EmailTextBox.Text.Trim();
UserInfo.Comment = CommentTextBox.Text.Trim();
Membership.UpdateUser(UserInfo);
// Revert the grid's EditIndex to -1 and rebind the data
UserGrid.EditIndex = -1;
BindUserGrid();
}
RowEditing
および RowCancelingEdit
イベント ハンドラーは、単純に GridView の EditIndex
プロパティを設定し、ユーザー アカウントの一覧をグリッドに再バインドします。 RowUpdating
イベント ハンドラーでは、興味深いことが発生します。 このイベント ハンドラーは、まずデータが有効であることを確認してから、編集されたユーザー アカウントの UserName
値を DataKeys
コレクションから取得します。 次に、2 つの TemplateField の EditItemTemplate
内の Email
および Comment
TextBox がプログラムで参照されます。 それらの Text
プロパティには、編集されたメール アドレスとコメントが含まれています。
Membership API 経由でユーザー アカウントを更新するために、まずユーザーの情報を取得する必要があります。これは、Membership.GetUser(userName)
を呼び出すことによって行います。 その後、返された MembershipUser
オブジェクトの Email
および Comment
プロパティは、編集インターフェイスから 2 つの TextBox に入力された値で更新されます。 最後に、これらの変更が Membership.UpdateUser
の呼び出しで保存されます。 RowUpdating
イベント ハンドラーは、GridView をその編集前インターフェイスに戻すことによって完了します。
次に、RowDeleting
イベント ハンドラーを作成してから、次のコードを追加します:
protected void UserGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
// Determine the username of the user we are editing
string UserName = UserGrid.DataKeys[e.RowIndex].Value.ToString();
// Delete the user
Membership.DeleteUser(UserName);
// Revert the grid's EditIndex to -1 and rebind the data
UserGrid.EditIndex = -1;
BindUserGrid();
}
上記のイベント ハンドラーは、まず UserName
値を GridView の DataKeys
コレクションから取得します。次に、この UserName
値が Membership クラスの DeleteUser
メソッドに渡されます。 DeleteUser
メソッドは、関連するメンバーシップ データ (このユーザーが属しているロールなど) を含むユーザー アカウントをシステムから削除します。 ユーザーを削除した後、グリッドの EditIndex
が -1 に設定され (別の行が編集モードにある間にユーザーが [削除] をクリックした場合)、BindUserGrid
メソッドが呼び出されます。
Note
[削除] ボタンでは、ユーザー アカウントを削除する前に、どのような種類の確認もユーザーに求められません。 アカウントが誤って削除される可能性を減らすために、何らかの形式のユーザー確認を追加することをお勧めします。 アクションを確認するための最も簡単な方法の 1 つは、クライアント側の確認ダイアログ ボックスを使用することです。 この手法の詳細については、「削除時のクライアント側での確認の追加」を参照してください。
このページが期待どおりに機能することを確認します。 任意のユーザーのメール アドレスやコメントを編集したり、任意のユーザー アカウントを削除したりできるはずです。 RoleBasedAuthorization.aspx
ページはすべてのユーザーからアクセスできるため、どのユーザーでも (匿名ビジターでさえ) このページにアクセスしてユーザー アカウントを編集したり、削除したりできます。 このページを更新して、スーパーバイザーおよび管理者ロールのユーザーのみがユーザーのメール アドレスやコメントを編集でき、管理者のみがユーザー アカウントを削除できるようにしましょう。
「LoginView コントロールの使用」のセクションでは、LoginView コントロールの使用について説明し、ユーザーのロールに固有の手順を示します。 管理者ロールのユーザーがこのページにアクセスした場合は、ユーザーを編集および削除する方法に関する手順を示します。 スーパーバイザー ロールのユーザーがこのページに到達した場合は、ユーザーの編集に関する手順を示します。 また、ビジターが匿名であるか、あるいはスーパーバイザーまたは管理者ロールのどちらにも属していない場合は、ユーザー アカウント情報を編集したり削除したりできないことを説明するメッセージを表示します。 「プログラムによる機能の制限」のセクションでは、ユーザーのロールに基づいて、[編集] および [削除] ボタンの表示/非表示をプログラムで切り替えるコードを記述します。
LoginView コントロールの使用
以前のチュートリアルで見てきたように、LoginView コントロールは、認証されたユーザーと匿名ユーザーに異なるインターフェイスを表示するために役立ちますが、LoginView コントロールを使用すると、ユーザーのロールに基づいて異なるマークアップを表示することもできます。 LoginView コントロールを使用して、アクセスしているユーザーのロールに基づいて異なる手順を表示しましょう。
まず、UserGrid
GridView の上に LoginView を追加します。 前に説明したように、LoginView コントロールには、AnonymousTemplate
と LoggedInTemplate
という 2 つの組み込みテンプレートがあります。 これらのテンプレートの両方に、どのユーザー情報も編集したり削除したりできないことをユーザーに通知する簡単なメッセージを入力します。
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
You are not a member of the Supervisors or Administrators roles. Therefore you
cannot edit or delete any user information.
</LoggedInTemplate>
<AnonymousTemplate>
You are not logged into the system. Therefore you cannot edit or delete any user
information.
</AnonymousTemplate>
</asp:LoginView>
AnonymousTemplate
と LoggedInTemplate
に加えて、LoginView コントロールには、ロール固有のテンプレートである RoleGroup を含めることができます。 各 RoleGroup には、その RoleGroup が適用されるロールを指定する 1 つのプロパティ Roles
が含まれています。 Roles
プロパティは、1 つのロール ("Administrators" など)、またはロールのコンマ区切りリスト ("Administrators, Supervisors" など) に設定できます。
RoleGroup を管理するには、このコントロールのスマート タグから [RoleGroup の編集] リンクをクリックして、RoleGroup コレクション エディターを起動します。 2 つの新しい RoleGroup を追加します。 最初の RoleGroup の Roles
プロパティを "Administrators" に、2 番目については "Supervisors" に設定します。
図 8: RoleGroup コレクション エディターを使用して LoginView のロール固有のテンプレートを管理する (クリックするとフルサイズの画像が表示されます)
[OK] をクリックして RoleGroup コレクション エディターを閉じます。これにより、LoginView の宣言型マークアップが更新され、RoleGroup コレクション エディターで定義された RoleGroup ごとの <asp:RoleGroup>
子要素を含む <RoleGroups>
セクションが含まれます。 さらに、最初は AnonymousTemplate
と LoggedInTemplate
だけが表示されていた LoginView のスマート タグ内の [ビュー] ドロップダウン リストに、追加された RoleGroup も含まれるようになりました。
RoleGroup を編集して、スーパーバイザー ロールのユーザーにはユーザー アカウントを編集する方法に関する手順が表示されるのに対して、管理者ロールのユーザーには編集および削除するための手順が表示されるようにします。 これらの変更を行うと、LoginView の宣言型マークアップは次のようになります。
<asp:LoginView ID="LoginView1" runat="server">
<RoleGroups>
<asp:RoleGroup Roles="Administrators">
<ContentTemplate>
As an Administrator, you may edit and delete user accounts.
Remember: With great power comes great responsibility!
</ContentTemplate>
</asp:RoleGroup>
<asp:RoleGroup Roles="Supervisors">
<ContentTemplate>
As a Supervisor, you may edit users' Email and Comment information.
Simply click the Edit button, make your changes, and then click Update.
</ContentTemplate>
</asp:RoleGroup>
</RoleGroups>
<LoggedInTemplate>
You are not a member of the Supervisors or Administrators roles.
Therefore you cannot edit or delete any user information.
</LoggedInTemplate>
<AnonymousTemplate>
You are not logged into the system. Therefore you cannot edit or delete any user
information.
</AnonymousTemplate>
</asp:LoginView>
これらの変更を行った後、このページを保存してから、ブラウザー経由でそこにアクセスします。 最初に、匿名ユーザーとしてこのページにアクセスします。 次のメッセージが表示されます。"システムにログインしてません。 そのため、ユーザー情報を編集または削除することはできません。"その後、認証されたユーザーではあるが、スーパーバイザーまたは管理者ロールのどちらにも属していないユーザーとしてログインします。 今度は、次のメッセージが表示されます。"スーパーバイザーまたは管理者ロールのメンバーではありません。 そのため、ユーザー情報を編集または削除することはできません。"
次に、スーパーバイザー ロールのメンバーであるユーザーとしてログインします。 今度は、スーパーバイザー ロール固有のメッセージが表示されます (図 9 を参照)。 また、管理者ロールのユーザーとしてログインした場合は、管理者ロール固有のメッセージが表示されます (図 10 を参照)。
図 9: Bruce にはスーパーバイザー ロール固有のメッセージが表示される (クリックするとフルサイズの画像が表示されます)
図 10: Tito には管理者ロール固有のメッセージが表示される (クリックするとフルサイズの画像が表示されます)
図 9 と図 10 のスクリーンショットが示すように、複数のテンプレートが適用される場合でも、LoginView は 1 つのテンプレートのみをレンダリングします。 Bruce と Tito はどちらもログインしているユーザーですが、LoginView は LoggedInTemplate
ではなく、一致する RoleGroup のみをレンダリングします。 さらに、Tito は管理者ロールとスーパーバイザー ロールの両方に属していますが、LoginView コントロールはスーパーバイザー ロールではなく、管理者ロール固有のテンプレートをレンダリングします。
図 11 は、レンダリングするテンプレートを決定するために LoginView コントロールによって使用されるワークフローを示しています。 複数の RoleGroup が指定されている場合、LoginView テンプレートは、一致する "最初の" RoleGroup をレンダリングすることに注意してください。 つまり、スーパーバイザーの RoleGroup を最初の RoleGroup として、管理者の RoleGroup を 2 番目として配置している場合は、Tito がこのページにアクセスするとスーパーバイザーのメッセージが表示されます。
図 11: レンダリングするテンプレートを決定するための LoginView コントロールのワークフロー (クリックするとフルサイズの画像が表示されます)
プログラムによる機能の制限
LoginView コントロールは、ページにアクセスしているユーザーのロールに基づいて異なる手順を表示しますが、[編集] および [キャンセル] ボタンはすべてのユーザーに表示されたままです。 匿名ビジターと、スーパーバイザーまたは管理者ロールのどちらにも属していないユーザーに対しては、[編集] および [削除] ボタンをプログラムで非表示にする必要があります。 [削除] ボタンは、管理者でないすべてのユーザーに対して非表示にする必要があります。 これを実現するために、CommandField の "Edit" および "Delete" LinkButton をプログラムで参照し、必要に応じてそれらの Visible
プロパティを false
に設定する少量のコードを記述します。
CommandField 内のコントロールをプログラムで参照するための最も簡単な方法は、最初にそれをテンプレートに変換することです。 これを実現するには、GridView のスマート タグから [列の編集] リンクをクリックし、現在のフィールドの一覧から CommandField を選択して [このフィールドを TemplateField に変換する] リンクをクリックします。 これにより、その CommandField が ItemTemplate
と EditItemTemplate
を含む TemplateField に変換されます。 ItemTemplate
には "Edit" および "Delete" LinkButton が含まれているのに対して、EditItemTemplate
には "Update" および "Cancel" LinkButton が含まれています。
図 12: CommandField を TemplateField に変換する (クリックするとフルサイズの画像が表示されます)
ItemTemplate
で "Edit" および "Delete" LinkButton を更新して、それらの ID
プロパティをそれぞれ EditButton
と DeleteButton
の値に設定します。
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True"
CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="EditButton" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
GridView にデータがバインドされるたびに、GridView はその DataSource
プロパティ内にレコードを列挙し、対応する GridViewRow
オブジェクトを生成します。 各 GridViewRow
オブジェクトが作成されると、RowCreated
イベントが発生します。 認可されていないユーザーに対して [編集] および [削除] ボタンを非表示にするには、このイベントのイベント ハンドラーを作成して、"Edit" および "Delete" LinkButton をプログラムで参照し、それに応じてそれらの Visible
プロパティを設定する必要があります。
RowCreated
イベントのイベント ハンドラーを作成し、次のコードを追加します。
protected void UserGrid_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != UserGrid.EditIndex)
{
// Programmatically reference the Edit and Delete LinkButtons
LinkButton EditButton = e.Row.FindControl("EditButton") as LinkButton;
LinkButton DeleteButton = e.Row.FindControl("DeleteButton") as LinkButton;
EditButton.Visible = (User.IsInRole("Administrators") || User.IsInRole("Supervisors"));
DeleteButton.Visible = User.IsInRole("Administrators");
}
}
RowCreated
イベントは、ヘッダー、フッター、ポケットベル インターフェイスなどを含む "すべての" GridView 行で発生することに注意してください。 "Edit" および "Delete" LinkButton をプログラムで参照するのは、編集モードではないデータ行を処理している場合だけにする必要があります (編集モードの行には [編集] と [削除] ではなく、[更新] と [キャンセル] のボタンがあるため)。 このチェックは、if
ステートメントによって処理されます。
編集モードではないデータ行を処理している場合は、"Edit" および "Delete" LinkButton が参照され、それらの Visible
プロパティは、User
オブジェクトの IsInRole(roleName)
メソッドによって返されたブール値に基づいて設定されます。 ユーザー オブジェクトは、RoleManagerModule
によって作成されたプリンシパルを参照します。その結果として、IsInRole(roleName)
メソッドが Roles API を使用して、現在のビジターが roleName に属しているかどうかを判定します。
Note
Roles クラスを直接使用して、User.IsInRole(roleName)
の呼び出しを Roles.IsUserInRole(roleName)
メソッドの呼び出しに置き換えることも可能でした。 この例では、Roles API を直接使用するより効率的であるため、プリンシパル オブジェクトの IsInRole(roleName)
メソッドを使用することにしました。 このチュートリアルの前の方では、ユーザーのロールを Cookie にキャッシュするようにロール マネージャーを構成しました。 このキャッシュされた Cookie データは、プリンシパルの IsInRole(roleName)
メソッドが呼び出された場合にのみ利用されます。Roles API を直接呼び出すと、常にロール ストアとの往復が必要になります。 ロールが Cookie にキャッシュされていない場合でも、プリンシパル オブジェクトの IsInRole(roleName)
メソッドでは、要求中の初めて呼び出されたときに結果がキャッシュされるため、通常はこれを呼び出す方がより効率的です。 これに対して、Roles API ではキャッシュは実行されません。 RowCreated
イベントは GridView 内のどの行でも 1 回発生するため、User.IsInRole(roleName)
を使用するとロール ストアとの往復が 1 回だけ必要なのに対して、Roles.IsUserInRole(roleName)
では N 回の往復が必要です。ここで、N は、グリッドに表示されているユーザー アカウントの数です。
[編集] ボタンの Visible
プロパティは、このページにアクセスしているユーザーが管理者またはスーパーバイザー ロールに属している場合は true
に設定され、そうでない場合は false
に設定されます。 [削除] ボタンの Visible
プロパティは、ユーザーが管理者ロールに属している場合にのみ true
に設定されます。
ブラウザー経由でこのページをテストします。 匿名ビジターとして、あるいはスーパーバイザーまたは管理者のどちらでもないユーザーとしてこのページにアクセスした場合、CommandField は空です。引き続き存在しますが、[編集] または [削除] ボタンのない薄いスライバーとしてだけです。
Note
スーパーバイザーでも管理者でもないユーザーがこのページにアクセスしているときに CommandField を完全に非表示にすることができます。 これは、読者のための演習として残しておきます。
図 13: スーパーバイザーでも管理者でもないユーザーに対して [編集] および [削除] ボタンが非表示になっている (クリックするとフルサイズの画像が表示されます)
スーパーバイザー ロールに属している (ただし、管理者ロールには属していない) ユーザーがアクセスした場合は、[編集] ボタンだけが表示されます。
図 14: スーパーバイザーは [編集] ボタンを使用できるが、[削除] ボタンが非表示になっている (クリックするとフルサイズの画像が表示されます)
また、管理者がアクセスした場合は、[編集] ボタンと [削除] ボタンの両方にアクセスできます。
図 15: [編集] および [削除] ボタンは管理者のみが使用できる (クリックするとフルサイズの画像が表示されます)
手順 3: ロール ベースの認可規則のクラスとメソッドへの適用
手順 2 では、編集機能をスーパーバイザーおよび管理者ロールのユーザーに、削除機能を管理者のみに制限しました。 これは、認可されていないユーザーに関連付けられたユーザー インターフェイス要素をプログラムによる方法で非表示にすることによって実現されました。 このような方法では、認可されていないユーザーが特権アクションを実行できなくなることは保証されません。 後で追加されるか、または認可されていないユーザーに対して非表示にし忘れたユーザー インターフェイス要素が存在する可能性があります。 あるいは、ハッカーが、ASP.NET ページに目的のメソッドを実行させるための他の何らかの方法を発見する可能性があります。
認可されていないユーザーが特定の機能に絶対にアクセスできないようにするための簡単な方法は、そのクラスまたはメソッドを PrincipalPermission
属性で修飾することです。 .NET ランタイムはクラスを使用したり、そのメソッドのうちの 1 つを実行したりする場合、現在のセキュリティ コンテキストにアクセス許可があることをチェックして確認します。 PrincipalPermission
属性は、これらの規則を定義できるメカニズムを提供します。
PrincipalPermission
属性の使用については、以前の「ユーザー ベースの認可」のチュートリアルで説明しました。 具体的には、GridView の SelectedIndexChanged
および RowDeleting
イベント ハンドラーを修飾して、それらをそれぞれ、認証されたユーザーと Tito だけが実行できるようにする方法について確認しました。 PrincipalPermission
属性はロールとも連携します。
GridView の RowUpdating
および RowDeleting
イベント ハンドラーで PrincipalPermission
属性を使用して、認可されていないユーザーの実行を禁止する方法を示しましょう。 そのために必要なのは、各関数定義の上に適切な属性を追加することだけです。
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
[PrincipalPermission(SecurityAction.Demand, Role = "Supervisors")]
protected void UserGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
...
}
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
protected void UserGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
...
}
RowUpdating
イベント ハンドラーの属性が、このイベント ハンドラーは管理者またはスーパーバイザー ロールのユーザーだけが実行できることを指定するのに対して、RowDeleting
イベント ハンドラーの上にある属性はその実行を管理者ロールのユーザーに制限します。
Note
PrincipalPermission
属性は、System.Security.Permissions
名前空間内のクラスとして表されます。 この名前空間をインポートするには、分離コード クラス ファイルの一番上に必ず using System.Security.Permissions
ステートメントを追加してください。
何らかの方法で管理者以外のユーザーが RowDeleting
イベント ハンドラーを実行しようとするか、またはスーパーバイザーでも管理者でもないユーザーが RowUpdating
イベント ハンドラーを実行しようとすると、.NET ランタイムによって SecurityException
が生成されます。
図 16: セキュリティ コンテキストがメソッドの実行を認可されていない場合は、SecurityException
がスローされる (クリックするとフルサイズの画像が表示されます)
ASP.NET ページに加えて、多くのアプリケーションには、さまざまなレイヤー (ビジネス ロジック レイヤーやデータ アクセス レイヤーなど) を含むアーキテクチャもあります。 これらのレイヤーは通常、クラス ライブラリとして実装され、ビジネス ロジックやデータ関連の機能を実行するためのクラスとメソッドを提供します。 PrincipalPermission
属性は、これらのレイヤーにも認可規則を適用するために役立ちます。
PrincipalPermission
属性を使用してクラスやメソッドで認可規則を定義する方法の詳細については、Scott Guthrie の PrincipalPermissionAttributes
を使用したビジネスおよびデータ レイヤーへの認可規則の追加に関するブログ エントリを参照してください。
まとめ
このチュートリアルでは、ユーザーのロールに基づいて、粗い認可規則ときめ細かい認可規則を指定する方法について説明しました。 ASP.NET の URL 認可機能を使用すると、ページ開発者は、どの ID がどのページへのアクセスを許可または拒否されるかを指定できます。 以前の「ユーザー ベースの認可」のチュートリアルで説明したように、URL 認可規則はユーザーごとに適用できます。 また、このチュートリアルの手順 1 で説明したように、ロールごとに適用することもできます。
きめ細かい認可規則は、宣言的にまたはプログラムで適用できます。 手順 2 では、LoginView コントロールの RoleGroup 機能を使用して、アクセスしているユーザーのロールに基づいて異なる出力をレンダリングする方法について説明しました。 また、ユーザーが特定のロールに属しているかどうかをプログラムで判定し、それに応じてページの機能を調整する方法についても説明しました。
プログラミングに満足!
もっと読む
この記事で説明したトピックの詳細については、次のリソースを参照してください。
PrincipalPermissionAttributes
を使用したビジネスおよびデータ レイヤーへの認可規則の追加- ASP.NET 2.0 のメンバーシップ、ロール、プロファイルの確認: ロールの操作
- ASP.NET 2.0 のセキュリティに関する質問の一覧
<roleManager>
要素に関するテクニカル ドキュメント
作成者について
複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell 氏は、1998 年から Microsoft Web のテクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 Mitchell 氏には、mitchell@4guysfromrolla.com で、または彼のブログ (http://ScottOnWriting.NET) 経由で連絡できます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者には、Suchi Banerjee と Teresa Murphy が含まれます。 今後の MSDN の記事を確認することに関心がありますか? ご希望の場合は、mitchell@4GuysFromRolla.com 宛にメールをお送りください