Share via


セキュリティ保護された ASP.NET アプリケーションの構築 : 認証、認定、および通信のセキュリティ保護 第 8 章 ASP.NET セキュリティ

patterns and practices home

J.D. Meier, Alex Mackman, Michael Dunner, and Srinath Vasireddy
Microsoft Corporation

November 2002
日本語版最終更新日 2003 年 3 月 17 日

適用対象:
    Microsoft® ASP.NET

全体の概要については、「セキュリティ保護された ASP.NET アプリケーションの構築」の開始ページを参照してください。

要約 : この章では、セキュリティで保護された ASP.NET Web アプリケーションを構築するのに役立つ説明と推奨事項を記載します。ここに記載されている説明と推奨事項の多くは、ASP.NET Web サービス、および ASP.NET によってホストされる .NET リモート処理オブジェクトの開発にも当てはまります。

目次

ASP.NET のセキュリティ アーキテクチャ
認証および認定のしくみ
セキュリティの構成
セキュリティのプログラミング
Windows 認証
フォーム認証
Passport 認証
カスタム認証
ASP.NET のプロセス ID
偽装
システム リソースへのアクセス
COM オブジェクトへのアクセス
ネットワーク リソースへのアクセス
セキュリティで保護された通信
機密情報の格納
セッション状態および ViewState のセキュリティ保護
Web ファームについての考慮事項
まとめ

ASP.NET のセキュリティ アーキテクチャ

ASP.NET は、一連の認証および認定のメカニズムを実現するために、IIS、.NET Framework、およびオペレーティング システムに用意されている基本的なセキュリティ サービスと連携して動作します。これを要約したのが、図 8.1 です。

図 8.1 ASP.NET のセキュリティ サービス

図 8.1 では、IIS と ASP.NET によって実現される認証および認定のメカニズムが示されています。クライアントが Web 要求を発行すると、認証イベントおよび認定イベントが以下の順序で発生します。

  1. ネットワークからの HTTP Web 要求が受信されます。SSL は、サーバーの身元を (サーバー証明書を使用して) 保証したり、必要に応じてクライアント ID を保証したりするのに使用できます。

    メモ SSL はセキュリティで保護されたチャネルを確保して、クライアントとサーバーとの間で渡される機密データを保護することもできます。

  2. IIS は、基本認証、ダイジェスト認証、統合認証 (NTLM または Kerberos)、または証明書認証を使用して、呼び出し元を認証します。サイト全体または一部で、アクセスを認証する必要がない場合は、匿名認証を使用するように IIS を設定することができます。IIS は、認証された各ユーザーに対して、Windows アクセス トークンを作成します。匿名認証が選択されている場合は、IIS は匿名のインターネット ユーザー アカウント (既定では IUSR_MACHINE) のアクセス トークンを作成します。

  3. IIS は、呼び出し元が要求したリソースをアクセスすることを認証します。要求されたリソースにアタッチされている ACL で定義された NTFS アクセス権を使用して、アクセスを認定します。また、特定の IP アドレスを持つクライアント コンピュータからの要求のみを受理するように設定することも可能です。

  4. IIS は、認証された呼び出し元の Windows アクセス トークンを ASP.NET に渡します。匿名認証が使用されている場合は、匿名インターネット ユーザーのアクセス トークンとなります。

  5. ASP.NET が呼び出し元を認証します。

    Windows 認証を使用するように ASP.NET が設定されている場合、この時点ではこれ以外の認証は発生しません。ASP.NET は、IIS から受け取ったトークンをすべて受理します。

    フォーム認証を使用するように ASP.NET が設定されている場合、呼び出し元が (HTML フォームを使用して) 提供した資格情報は、通常は Microsoft® SQL Server® データベースまたは Active Directory® ディレクトリ サービスといったデータ ストアに対して認証されます。Passport 認証を使用するように ASP.NET が設定されている場合、ユーザーは Passport サイトにリダイレクトされ、Passport 認証サービスでユーザーが認証されます。

  6. ASP.NET は、要求されたリソースまたは操作へのアクセスを認定します。

    UrlAuthorizationModule (システムが提供した HTTP モジュール) は、Web.config (特に、<authorization> 要素) で設定された認定規則を使用して、要求したファイルやフォルダに呼び出し元がアクセスできるようにします。

    Windows 認証では、FileAuthorizationModule (上記とは別の HTTP モジュール) は、要求したリソースにアクセスするために必要なアクセス許可を呼び出し元が持っていることを確認します。呼び出し元のアクセス トークンは、リソースを保護する ACL と照らし合わせます。

    また、呼び出し元が要求したリソースにアクセスしたり、要求した操作を実行することをを認証するために .NET ロールを宣言またプログラムで使用することもできます。

  7. アプリケーション内のコードは、特定の ID を使用してローカルやリモートのリソースにアクセスします。既定では、ASP.NET は偽装を行いません。その結果、構成された ASP.NET プロセス アカウントによって、その ID が提供されます。このほか、最初の呼び出し元の ID (偽装が有効になっている場合) や構成済みのサービスの ID などを使用することもできます。

ゲートキーパー

ASP.NET Web アプリケーション内で認定を行うポイント、つまりゲートキーパーは、IIS および ASP.NET によって提供されています。

IIS

匿名認証がオフになっていると、IIS はそのドメインまたは信頼されたドメインで認証することが可能なユーザーからの要求しか許可しません。

静的なファイル タイプ (.jpg、.gif、.htm ファイルなどの ISAPI 拡張機能にマップされないファイル) の場合、IIS は要求されたファイルに関連付けられている NTFS アクセス権を使用してアクセス制御を行います。

ASP.NET

ASP.NET のゲートキーパーには、UrlAuthorizationModule、FileAuthorizationModule、およびプリンシパル アクセス許可要求とロール チェックがあります。

UrlAuthorizationModule

アプリケーションの Web.config ファイル内の <authorization> 要素を設定して、アプリケーションにアクセスするユーザーおよびユーザー グループを指定することができます。認定は、HttpContext.User に格納されている IPrincipal オブジェクトに基づいています。

FileAuthorizationModule

IIS によって ASP.NET の ISAPI 拡張機能 (Aspnet_isapi.dll) にマップされるファイル タイプについては、認証されたユーザーの Windows アクセス トークン (IUSR_MACHINE など) を使用して、要求された ASP.NET ファイルにアタッチされた ACL と照らし合わせて自動アクセス チェックが行われます。

メモ 偽装は、ファイル認定の動作には必要ありません。

FileAuthorizationModule クラスは、要求されたファイルのみに対してアクセス チェックを実行します。要求されたページのコードによってアクセスされるファイルのアクセス チェックは行いません。このようなファイルは IIS によってアクセス チェックが行われます。

たとえば、Default.aspx を要求したとき、これに Usercontrol.ascx という埋め込みのユーザー コントロールが存在し、さらにこのユーザー コントロールに Image.gif にポイントするイメージ タグが含まれている場合は、FileAuthorizationModule は Default.aspx と Usercontrol.ascx のアクセス チェックを実行します。この理由は、これらのファイル タイプが IIS によって ASP.NET ISAPI 拡張機能にマップされるためです。

Image.gif は IIS によって内部的に処理される静的なファイルであるため、FileAuthorizationModule はこのファイルのチェックを行いません。ただし、静的なファイルのアクセス チェックは IIS によって実行されるので、認証されたユーザーであっても、適切に構成された ACL でそのファイルの読み取り権限が許可されている必要があります。

これを図 8.2 に示します。

メモ (システム管理者用) 認証されたユーザーには、この例に含まれるすべてのファイルに対する NTFS 読み取りアクセス許可が必要です。どのゲートキーパーをアクセス制御の実行に使用するかということだけが選択可能になります。ASP.NET プロセス アカウントには、ASP.NET に登録されているファイル タイプへの読み取りアクセスのみが必要です。

図 8.2 連動して動作する IIS および ASP.NET ゲートキーパー

この例では、ファイル ゲートでアクセスを防止することができます。Default.aspx にアタッチされた ACL を構成し、特定のユーザーへのアクセスを禁止すると、ユーザー コントロールまたは埋め込まれたイメージは Default.aspx 内のコードによってクライアントに送信されることはなくなります。ユーザーがイメージを直接要求した場合は、IIS がアクセス チェックを実行します。

プリンシパル アクセス許可要求および明示的なロール チェック

IIS と ASP.NET の構成可能なゲートキーパーに加えて、プリンシパル アクセス許可要求を (宣言して、またはプログラムで使用して) きめ細かなアクセス制御メカニズムとして使用することができます。PrincipalPermissionAttribute クラスによって実行されるプリンシパル アクセス許可のチェックを行うと、現在のスレッドにアタッチされている IPrincipal オブジェクトによる定義に従って、個々のユーザー ID およびグループ メンバシップに基づき、クラス、メソッド、または個々のコード ブロックへのアクセスを制御することができます。

メモ ロール メンバシップの要求に使用されるプリンシパル アクセス許可要求は、IPrincipal.IsInRole を呼び出してロール メンバシップをテストするのとは異なります。前者では、呼び出し元が指定されたロールのメンバでないと、例外が発生します。後者では、ロール メンバシップを確認するためのブール値が返されます。

Windows 認証では、HttpContext.User を使用して ASP.NET は認証されたユーザーを表す WindowsPrincipal オブジェクトが現在の Web 要求に自動的にアタッチされます。フォーム認証および Passport 認証では、適切な ID を持つ、役割のない GenericPrincipal オブジェクトが作成され、HttpContext.User にアタッチされます。

詳細情報

認証および認定のしくみ

ASP.NET には、宣言型およびプログラムによる認定メカニズムが多数用意されており、さまざまな認証スキームと組み合わせて使用することができます。このため、徹底した認定機構を開発したり、ユーザー単位またはユーザー グループ単位 (ロール ベース) などの、さまざまなレベルで実行できるように構成された認定機構を開発したりすることが可能です。

ここでは、一般的に使用される認証オプションに用意されている構成可能、およびプログラム可能な認定オプションを説明します。

ここでは、以下の認証オプションの概要が説明されています。

  • 偽装を使用した Windows 認証
  • 偽装を使用しない Windows 認証
  • 固定 ID を使用した Windows 認証
  • フォーム認証
  • Passport 認証

使用可能な認定オプション

次の表には、使用可能な認定オプションが示されています。また、それぞれのオプションについて、Windows 認証および偽装が必要かどうかが示されています。Windows 認証が必要でない場合、その認定オプションは他の種類のすべての認証で使用することが可能です。この表を使用して、認証および認定の戦略を強化してください。

表 8.1 Windows 認証および偽装の必要性

認定オプション Windows 認証の必要性 偽装の必要性
FileAuthorizationModule はい。 いいえ。
UrlAuthorizationModule いいえ。 いいえ。
プリンシパル アクセス許可要求 いいえ。 いいえ。
.NET ロール いいえ。 いいえ。
Enterprise Services ロール はい。 はい (ASP.NET Web アプリケーション内での場合)。
NTFS アクセス権 (直接要求される静的なファイル タイプ用で、ISAPI 拡張機能にはマップされません) なし。これらのファイルは ASP.NET によって処理されません。
匿名以外のすべての IIS 認証メカニズムでは、認証された個々のユーザーに対してアクセス許可を設定する必要があります。
匿名認証では、IUSR_MACHINE に対してアクセス許可を設定する必要があります。
いいえ (IIS によってアクセス チェックが行われます)。
NTFS アクセス権 (Web アプリケーションのコードによってアクセスされるファイル用) いいえ。 いいえ。
偽装を行う場合は、偽装された Windows ID に対して ACL を構成します。この Windows ID は、最初の呼び出し元か、Web.config* の 要素で指定された ID です。

* 偽装された ID は、最初の呼び出し元または Web.config の <identity> 要素で指定された ID を使用できます。以下の 2 つの <identity> 要素を参照してください。

<identity impersonate="true" /> 
<identity impersonate="true" userName="Bob" password="pwd" />

1 番目の構成では、IIS によって認証された最初の呼び出し元が偽装されますが、2 番目の構成では Bob の ID が使用されます。以下の理由により、2 番目の構成はお勧めできません。

  • Microsoft Windows® 2000 オペレーティング システムで "オペレーティング システムの一部として動作する" ことを ASP.NET プロセス ID に許可する必要があります。
  • また、プレーン テキストのパスワードを Web.config に含める必要もあります。

これらの制限は、次のリリースの .NET Framework で改善される予定です。

偽装を使用した Windows 認証

以下の構成の要素は、Windows (IIS) 認証および偽装を Web.config または Machine.config で宣言して有効にする方法を示しています。

メモ 各アプリケーションの Web.config ファイルで、アプリケーションごとに認証を構成する必要があります。

<authentication mode="Windows" />
<identity impersonate="true" /> 

この構成では、ASP.NET のアプリケーション コードは IIS によって認証された呼び出し元を偽装します。

構成可能なセキュリティ

偽装と共に Windows 認証を使用するときは、以下の認定オプションを使用できます。

  • Windows ACL
    • クライアントが要求したリソース ASP.NET の FileAuthorizationModule は、ASP.NET ISAPI にマップされる、要求されたファイル タイプのアクセス チェックを実行します。FileAuthorizationModule は、アクセス チェックを行うために、最初の呼び出し元のアクセス トークンと要求されたリソースにアタッチされている ACL を使用します。

      ISAPI 拡張機能にマップされない静的なファイル タイプの場合は、IIS は呼び出し元のアクセス トークンとファイルにアタッチされている ACL を使用してアクセス チェックを行います。

    • アプリケーションによってアクセスされるリソース アプリケーションによってアクセスされるリソース (ファイル、フォルダ、レジストリ キー、Active Directory オブジェクトなど) の Windows ACL を、最初の呼び出し元に対して構成することができます。

URL 認定 Web.config で URL 認定を構成します。Windows 認証では、ユーザー名には DomainName\UserName という形式が使用され、ロールは Windows のグループを使用して 1 対 1 でマップされます。

<authorization>
<deny user="DomainName\UserName" />
<allow roles="DomainName\WindowsGroup" />
</authorization>

Enterprise Services (COM+) ロール ロールは、COM+ カタログに格納されます。コンポーネント サービスの管理ツールやスクリプトを使用して、ロールを構成することができます。

プログラムによるセキュリティ

プログラムによるセキュリティとは、Web アプリケーションのコード内に配置されているセキュリティ チェックのことです。Windows 認証と偽装を使用するときは、プログラムによるセキュリティの以下のオプションを使用することができます。

  • PrincipalPermission での要求
    • 強制型 (メソッドのコード内でインラインで使用します)
	PrincipalPermission permCheck = new PrincipalPermission(
	null, @"DomainName\WindowsGroup");
	permCheck.Demand();
	
  • 宣言型 (インターフェイス、クラス、およびメソッドの属性として使用します)
	[PrincipalPermission(SecurityAction.Demand, 
	Role=@"DomainName\WindowsGroup)]	

明示的なロール チェック IPrincipal インターフェイスを使用して、ロール チェックを実行することができます。

IPrincipal.IsInRole(@"DomainName\WindowsGroup");

Enterprise Services (COM+) ロール ContextUtil クラスを使用して、プログラムでロール チェックを実行することができます。

ContextUtil.IsCallerInRole("Manager")

どのような場合に使用するか

Windows 認証と偽装は、以下の場合に使用します。

  • アプリケーションのユーザーが、サーバーによる認証が可能な Windows アカウントを持っている。
  • 最初の呼び出し元のセキュリティ コンテキストを Web アプリケーションの中間層またはデータ層の両方またはいずれかにフローして、ユーザー単位のきめ細かい認定をサポートする必要がある。
  • 最初の呼び出し元のセキュリティ コンテキストを下位層にフローして、オペレーティング システム レベルの監査をサポートする必要がある。

アプリケーションで偽装を使用する前に、信頼サブシステム モデルを使用する場合と比較し、この方法のトレードオフを理解しておいてください。この詳細については、「第 3 章 認証と認定」の「リソース アクセス モデルの選択」で詳しく説明されています。

偽装には、以下のような短所があります。

  • データベース接続を効果的にプールできないため、アプリケーションの拡張性が低くなります。
  • バックエンド リソースの ACL を個々のユーザーに対して構成する必要があるため、管理作業が増加します。
  • 委任には、Kerberos 認証と、適切に構成された環境が必要です。

詳細情報

  • Windows 認証の詳細については、後の「Windows 認証」を参照してください。
  • 偽装の詳細については、後の「偽装」を参照してください。
  • URL 認定の詳細については、後の「URL 認定の注意事項」を参照してください。
  • Enterprise Services (COM+) ロールの詳細については、「第 9 章 Enterprise Services セキュリティ」を参照してください。
  • PrincipalPermission 要求の詳細については、このガイドの「パート I : セキュリティ モデル」にある第 2 章の「ID およびプリンシパル」を参照してください。

偽装を使用しない Windows 認証

以下の構成の要素は、偽装を使用しない Windows (IIS) 認証を Web.config で宣言して有効にする方法を示しています。

<authentication mode="Windows" />
<!-- The following setting is equivalent to having no identity element -->
<identity impersonate="false" />

構成可能なセキュリティ

偽装を利用しない Windows 認証を使用するときは、以下の認定オプションを使用できます。

  • Windows ACL
    • クライアントが要求したリソース ASP.NET の FileAuthorizationModule は、ASP.NET ISAPI にマップされる、要求されたファイル タイプのアクセス チェックを実行します。FileAuthorizationModule は、アクセス チェックを行うために、最初の呼び出し元のアクセス トークンと要求されたリソースにアタッチされている ACL を使用します。偽装は必要ありません。

      ISAPI 拡張機能にマップされない静的なファイル タイプの場合は、IIS は呼び出し元のアクセス トークンとファイルにアタッチされている ACL を使用してアクセス チェックを行います。

    • アプリケーションによってアクセスされるリソース アプリケーションによってアクセスされるリソース (ファイル、フォルダ、レジストリ キー、Active Directory オブジェクト) の Windows ACL を、ASP.NET プロセス ID に対して構成します。

URL 認定 Web.config で URL 認定を構成します。Windows 認証では、ユーザー名には DomainName\UserName という形式が使用され、ロールは Windows のグループを使用して 1 対 1 でマップされます。

<authorization>
<deny user="DomainName\UserName" />
<allow roles="DomainName\WindowsGroup" />
</authorization>

プログラムによるセキュリティ

プログラムによるセキュリティで使用できるオプションは以下のとおりです。

  • プリンシパル アクセス許可要求
    • 強制型
	    PrincipalPermission permCheck = new PrincipalPermission(
	null, @"DomainName\WindowsGroup");
	permCheck.Demand();
	
  • 宣言型
	[PrincipalPermission(SecurityAction.Demand, 
	Role=@"DomainName\WindowsGroup")]	

明示的なロール チェック IPrincipal インターフェイスを使用して、ロール チェックを実行することができます。

IPrincipal.IsInRole(@"DomainName\WindowsGroup");

どのような場合に使用するか

偽装を利用しない Windows 認証は、以下の場合に使用します。

  • アプリケーションのユーザーが、サーバーによる認証が可能な Windows アカウントを持っている。
  • 接続プーリングをサポートするために、固定 ID を使用して下位のリソース (例 : データベース) にアクセスする必要がある。

詳細情報

  • Windows 認証の詳細については、後の「Windows 認証」を参照してください。
  • URL 認定の詳細については、後の「URL 認定の注意事項」を参照してください。
  • PrincipalPermission 要求の詳細については、このガイドの「パート I : セキュリティ モデル」にある第 2 章の「ID およびプリンシパル」を参照してください。

固定 ID を使用した Windows 認証

Web.config の <identity> 要素では、ユーザー名およびパスワードの属性を必要に応じて使用できます。このため、特定の固定 ID をアプリケーションに対して構成して、偽装することができます。以下の構成ファイルの一部は、このようにする場合を示しています。

<identity impersonate="true" userName="DomainName\UserName" 
password="ClearTextPassword" />

どのような場合に使用するか

以下の 2 つの理由により、.NET Framework の現在のバージョン (Version 1) では、セキュリティで保護された環境に対してこの方法をお勧めしません。

  • ユーザー名とパスワードは、特に仮想ディレクトリに格納される構成ファイルなど、構成ファイルにプレーン テキストで保存するべきではありません。
  • Windows 2000 では、この方法を使用するには、"オペレーティング システムの一部として動作する" 特権を ASP.NET プロセス アカウントに許可しなければなりません。このため、Web アプリケーションのセキュリティが低下し、悪意のあるユーザーによって Web アプリケーションのプロセスが突破された場合、悪用される危険性が増大します。

.NET Framework Version 1.1 では、Windows 2000 で生じるこの問題が以下のように修正されています。

  • 資格情報が暗号化されます。
  • ログオンが IIS のプロセスによって実行されるため、ASP.NET には "オペレーティング システムの一部として動作する" 特権が必要なくなります。

フォーム認証

以下の構成の要素は、フォーム認証を Web.config で宣言して有効にする方法を示しています。

<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="AuthCookie" timeout="60" path="/">
</forms>
</authentication>

構成可能なセキュリティ

フォーム認証を使用するときは、以下の認定オプションを使用できます。

  • Windows ACL
    • クライアントが要求したリソース 要求されたリソースには、匿名のインターネット ユーザー アカウントへの読み取りアクセスを許可する ACL が必要です。フォーム認証を使用するときは、匿名アクセスを許可するように IIS を構成してください。

      ASP.NET のファイル認定は、Windows 認証を必要とするため、使用することができません。

    • アプリケーションによってアクセスされるリソース アプリケーションによってアクセスされるリソース (ファイル、フォルダ、レジストリ キー、Active Directory オブジェクト) の Windows ACL を、ASP.NET プロセス ID に対して構成します。

URL 認定

URL 認定を Web.config で構成します。フォーム認証では、ユーザー名の形式は、SQL Server データベースや Active Directory などのカスタム データ ストア によって異なります。

  • データ ストアとして SQL Server を使用している場合は、以下のように記述します。
<authorization>
<deny users="?" />
<allow users="Mary,Bob,Joe" roles="Manager,Sales" />
</authorization>

  • データ ストアとして Active Directory を使用している場合は、以下のようにユーザー名およびグループ名はX.500 形式で表されます。
<authorization>
<deny users="someAccount@domain.corp.yourCompany.com" />
<allow roles ="CN=Smith James,CN=FTE_northamerica,CN=Users,
DC=domain,DC=corp,DC=yourCompany,DC=com" />
</authorization>

プログラムによるセキュリティ

プログラムによるセキュリティで使用できるオプションは以下のとおりです。

  • プリンシパル アクセス許可要求
    • 強制型
PrincipalPermission permCheck = new PrincipalPermission(
null, "Manager");
permCheck.Demand();

  • 宣言型
[PrincipalPermission(SecurityAction.Demand, Role="Manager")]

明示的なロール チェック IPrincipal インターフェイスを使用して、ロール チェックを実行することができます。

IPrincipal.IsInRole("Manager");

どのような場合に使用するか

フォーム認証は、インターネット アプリケーションに最も適しています。以下のような場合に、フォーム認証を使用します。

  • アプリケーションのユーザーが、Windows アカウントを持っていない。
  • ユーザーがアプリケーションにログオンするときに、HTML フォームで資格情報を入力するようにする必要がある。

詳細情報

  • フォーム認証の詳細については、後の「フォーム認証」を参照してください。
  • URL 認定の詳細については、後の「URL 認定の注意事項」を参照してください。

Passport 認証

以下の構成の要素は、Passport 認証を Web.config で宣言して有効にする方法を示しています。

<authentication mode="Passport" />

どのような場合に使用するか

Passport 認証をインターネットで使用するのは、アプリケーションのユーザーが Windows アカウントを持っておらず、シングル サインオン ソリューションを実装する必要がある場合です。参加している Passport サイトで、Passport アカウントを使用して以前にログオンしたことのあるユーザーは、Passport 認証を使用して構成されたサイトにログオンする必要はありません。

セキュリティの構成

ここでは、ASP.NET Web アプリケーションのセキュリティを構成するために必要な実際の手順を説明します。これを要約したのが、図 8.3 です。

図 8.3 ASP.NET アプリケーションのセキュリティの構成

IIS の設定を構成する

IIS のセキュリティを構成するには、以下の手順を実行する必要があります。

  1. SSL が必要な場合、必要に応じて、Web サーバー証明書をインストールします。

    詳細については、このガイドの「パート IV : 参照」の「Web サーバー上で SSL を設定する方法」を参照してください。

  2. IIS 認証を構成します。

  3. 証明書認証を使用する場合、必要に応じて、クライアント証明書のマップを構成します。

    クライアント証明書マッピングの詳細については、Microsoft サポート技術情報の Knowledge Base の文書 313070「[HOWTO] IIS (Internet Information Services) 5.0 でクライアント証明書のマッピングを構成する方法」を参照してください。

  4. NTFS アクセス権をファイルおよびフォルダに設定します。IIS および ASP.NET の FileAuthorizationModule は、認証されたユーザー (または匿名のインターネット ユーザー アカウント) が、要求したファイルにアクセスするのに必要な (ACL の設定に基づいた) アクセス権を持っていることをチェックします。

ASP.NET の設定を構成する

アプリケーション レベルの構成の設定は、Web.config ファイルに保存されます。このファイルは、アプリケーションの仮想ルート ディレクトリか、必要に応じてそのサブフォルダ内に置かれています。サブフォルダに置かれた設定は、親フォルダの設定よりも優先することがあります。

  1. 認証を構成する。 この設定は、Machine.config ではなく、アプリケーションの仮想ルート ディレクトリに置かれる Web.config ファイルでアプリケーションごとに行う必要があります。
<authentication mode="Windows|Forms|Passport|None" />
  1. 偽装を構成する。 既定では、ASP.NET アプリケーションは偽装を行いません。アプリケーションは、構成された ASP.NET プロセス ID (通常は ASPNET) を使用して実行され、アプリケーションがリソースにアクセスするときは、いずれもこの ID が使用されます。偽装が必要になるのは、以下の場合だけです。
    • Enterprise Services を使用していて、サービス対象のコンポーネントによって提供される機能へのアクセスを認定するために Enterprise Services (COM+) ロールを使用する必要がある。

    • 匿名認証に対応するように IIS を構成しており、リソースへのアクセスに匿名のインターネット ユーザー アカウントを使用する必要がある。この方法の詳細については、後の「ネットワーク リソースへのアクセス」を参照してください。

    • 認証されたユーザーのセキュリティ コンテキストを次の層 (データベースなど) にフローする必要がある。

    • 従来の ASP アプリケーションを ASP.NET に移植していて、同じ偽装の動作が必要である。従来の ASP は、既定で呼び出し元を偽装します。

      ASP.NET の偽装を構成するには、次の <identity> 要素をアプリケーションの Web.config で使用します。

<identity impersonate="true" /> 
  1. 認定を構成する。 URL 認定は、ユーザーまたはロールが特定の HTTP 動詞 (GET、HEAD、POST など) を特定のファイルに発行できるかどうかを決定します。URL 認定を実装するには、以下の作業を実行します。
    1. アプリケーションの仮想ルート ディレクトリに配置されている Web.config ファイルに、<authorization> 要素を追加します。

    2. allow 属性および deny 属性を使用して、ユーザーおよびロールへのアクセスを制限します。次の Web.config ファイルからの例では、Windows 認証を使用して、Bob と Mary にはアクセスを許可し、それ以外のユーザーはすべて拒否します。

	<authorization>
	<allow users="DomainName\Bob, DomainName\Mary" />
	<deny users="*" />
	</authorization>
	
    **重要** \<authorization\> 要素の最後に \<deny users="?"/\> または \<deny users="\*"/\> を追加する必要があります。追加しない場合、認証されたすべてのユーザーにアクセスが許可されてしまいます。

URL 認定の注意事項

URL 認定を構成するときは、以下の点に注意してください。

  • * は、すべての ID を意味します。

  • ? は、認証されていない ID を意味します (つまり、匿名の ID です)。

  • URL 認定を機能させるのに偽装は必要ありません。

  • Web.config 内にある認定の設定は、現在のディレクトリおよびすべてのサブディレクトリにあるファイルすべてを対象とします。ただし、<authorization> 要素のある、そのディレクトリ用の Web.config ファイルがサブディレクトリに含まれている場合を除きます。この場合、サブディレクトリの設定が親ディレクトリの設定よりも優先します。

    メモ URL 認定は、IIS によって ASP.NET ISAPI 拡張機能の aspnet_isapi.dll にマップされるファイル タイプにのみ適用されます。

    <location> タグを使用すると、認定の設定をファイルまたはディレクトリに個別に適用することができます。以下の例は、認定を Page.aspx に適用する方法を示しています。

<location path="page.aspx" />
<authorization>
<allow users="DomainName\Bob, DomainName\Mary" />
<deny users="*" />
</authorization>
</location>

  • URL 認定のユーザーとロールは、以下のように認証の設定によって決まります。

    • <authentication mode="Windows" /> が含まれている場合は、Windows のユーザーとグループのアカウントにアクセスを認定しています。

      ユーザー名には、"DomainName\WindowsUserName" という形式を使用します。

      ロールの名前には、"DomainName\WindowsGroupName" という形式を使用します。

      メモ ローカルの管理者グループの名前は、"BUILTIN\Administrators" です。ローカルのユーザー グループの名前は、"BUILTIN\Users" です。

    • <authentication mode="Forms" /> が含まれている場合は、現在の HTTP コンテキストに格納されている IPrincipal オブジェクトのユーザーおよびロールに対して認定しています。たとえば、フォームを使用し、データベースと照らし合わせてユーザーを認証する場合は、そのデータベースから取り出したロールに照らし合わせて認定することになります。

    • <authentication mode="Passport" /> が含まれている場合は、Passport User ID (PUID)、またはストアから取り出されたロールに対して認定します。たとえば、特定のアカウント、および SQL Server データベースや Active Directory に格納されている一連のロールに PUID をマップすることができます。

      メモ この機能は、Microsoft Windows Server 2003 オペレーティング システムに組み込まれる予定です。

    • <authentication mode="None" /> が含まれている場合は、認定を実行しないようにすることができます。"None" を指定すると、どの認証も使用しないか、.NET の認証モジュールを使用しないでカスタムの認証メカニズムを使用することを意味します。

      ただし、カスタム認証を使用する場合は、ロールのある IPrincipal オブジェクトを作成し、HttpContext.User に格納する必要があります。この後、URL 認定を実行するときは、IPrincipal オブジェクトに保存されているユーザーおよびロールに対して、取り出された方法に関係なく URL 認定が実行されます。

URL 認定の例

以下のリストは、いくつかの一般的な URL 認定の例の構文を示しています。

  • 匿名アカウントのアクセスを拒否します。
<deny users="?" />
  • すべてのユーザーのアクセスを拒否します。
<deny users="*" />
  • Manager ロールのアクセスを拒否します。
<deny roles="Manager"/>
  • フォーム認証の例。
<configuration>
<system.web>
<authentication mode="Forms">
<forms name=".ASPXUSERDEMO" 
loginUrl="login.aspx" 
protection="All" timeout="60" />
</authentication>
<authorization>
<deny users="jdoe@somewhere.com" />
<deny users="?" />
</authorization>
</system.web>
</configuration>

詳細情報

<authorization> 要素は、HttpContext.User および HttpContext.Request.RequestType に格納されている現在の IPrincipal オブジェクトに対して作用します。

リソースをセキュリティで保護する

  1. ファイル、フォルダ、レジストリ キーなどのリソースをセキュリティで保護するには、Windows ACL を使用します。

    偽装を行っていない場合、アプリケーションがアクセスする必要があるリソースには、最低でも読み取りアクセスを ASP.NET プロセス アカウントに許可する ACL が必要になります。

    偽装を行っている場合、ファイルおよびレジストリ キーには、認証されたユーザーに対して最低でも読み取りアクセスを許可する ACL が必要になります。匿名認証が有効になっている場合は、匿名のインターネット ユーザー アカウントに対しても同様です。

  2. Web.config および Machine.config をセキュリティで保護するには

    • 正しい ACL を使用します。ASP.NET が偽装を行っている場合は、偽装される ID には読み取りアクセスが必要です。そうでない場合は、ASP.NET プロセス ID に読み取りアクセスが必要です。以下の ACL を Web.config および Machine.config で使用します。

      System : フル コントロール
      Administrators : フル コントロール
      プロセス ID または偽装された ID : 読み取り

      匿名のインターネット ユーザー アカウント (IUSR_MACHINE) を偽装していない場合は、このアカウントへのアクセスを拒否する必要があります。

      メモ アプリケーションが UNC 共有にマップされている場合、UNC の ID も構成ファイルへの読み取りアクセスが必要です。

    • 不要な HTTP モジュールを削除します。Machine.config には、<httpModules> 要素内に既定の HTTP モジュールのセットがあります。これには、次のようなものがあります。

      • WindowsAuthenticationModule
      • FormsAuthenticationModule
      • PassportAuthenticationModule
      • UrlAuthorizationModule
      • FileAuthorizationModule
      • OutputCacheModule
      • SessionStateModule

    アプリケーションが特定のモジュールを使用しない場合は、そのモジュールを削除します。こうすると、特定のモジュールに関するセキュリティ上の問題が後で発生して、アプリケーションでその問題を利用される可能性がなくなります。

  3. 必要に応じて、以下に説明するように、<location> 要素と allowOverride="false" 属性を組み合わせて使用し、構成の設定をロックします。

構成の設定のロック

構成の設定は階層化されています。サブディレクトリ内の Web.config ファイルの設定は、親ディレクトリの Web.config の設定よりも優先されます。また、Web.config の設定は、Machine.config の設定よりも優先されます。

<location> 要素に allowOverride 属性を組み合わせて使用して、構成の設定をロックすると、設定が下位レベルの設定によって優先されないようにできます。次に、例を示します。

<location path="somepath" allowOverride="false" />
. . .  . . . arbitrary configuration settings . . .
</location>

パスは、Web サイトまたは仮想ディレクトリを指すことができます。また、指定したディレクトリとすべてのサブディレクトリに該当します。allowOverride を false に設定すると、<location> 要素で指定した設定よりも下位レベルの構成ファイルが優先されるのを防ぐことができます。下位の構成の設定をロックする機能は、すべての種類の設定に適用されます。認証モードなどのセキュリティ設定だけに限定されるものではありません。

ファイルがダウンロードされないようにする

HttpForbiddenHandler クラスを使用すると、特定の種類のファイルが Web からダウンロードされないようにすることができます。このクラスは、Web.config などの構成ファイルを含む特定のシステム レベルのファイルがダウンロードされないようにするために、ASP.NET によって内部的に使用されます。この方法で制限されるファイル タイプの完全なリストについては、Machine.config の <httpHandlers> セクションを参照してください。

アプリケーションが内部的に使用するが、ダウンロードされるのが目的ではないファイルについて、HttpForbiddenHandler を使用するかどうかを検討してください。

メモ この他、Windows ACL でセキュリティで保護して、Web サーバーにログオンするときにファイルにアクセスできるユーザーを管理する必要もあります。

■ HttpForbiddenHandler を使用して、特定の種類のファイルがダウンロードされないようにするには

  1. 指定されたファイル タイプについて、IIS でアプリケーションのマッピングを作成し、Aspnet_isapi.dll にマップされるようにします。

    1. [スタート] ボタンをクリックし、[プログラム] をポイントします。次に、[管理ツール] をポイントし、[インターネット サービス マネージャ] をクリックします。
    2. アプリケーションの仮想ディレクトリを選択し、右クリックして [プロパティ] をクリックします。
    3. [アプリケーションの設定] の [構成] をクリックします。
    4. [追加] をクリックして新しいアプリケーションのマッピングを作成します。
    5. [参照] をクリックし、c:\winnt\Microsoft.NET\Framework\v1.0.3705\aspnet_isapi.dll を選択します。
    6. ダウンロードされないようにするファイル タイプの拡張子 (.abc など) を [拡張子] ボックスに入力します。
    7. [すべての動詞] と [スクリプト エンジン] がオンになっていて、[ファイルの存在を確認する] がオフになっていることを確認します。
    8. [OK] をクリックし、[アプリケーションの拡張子マッピングの追加/編集] ダイアログ ボックスを閉じます。
    9. [OK] をクリックし、[アプリケーションの構成] ダイアログ ボックスを閉じ、もう一度 [OK] をクリックして [プロパティ] ダイアログ ボックスを閉じます。
  2. 指定したファイル タイプの <HttpHandler> マッピングを Web.config に追加します。

    ファイル タイプが .abc である場合の例を以下に示します。

<httpHandlers>
<add verb="*" path="*.abc" 
type="System.Web.HttpForbiddenHandler"/>
</httpHandlers>

通信をセキュリティで保護する

通信リンクをセキュリティで保護するには、SSL とインターネット プロトコル セキュリティ (IPSec) を組み合わせて使用します。

詳細情報

セキュリティのプログラミング

Web アプリケーションの構成可能なセキュリティ設定を設定したら、プログラムを使用してアプリケーションの認定ポリシーをさらに向上させ、より細かく調整する必要があります。これには、宣言型の .NET の属性をアセンブリ内部で使用したり、強制型の認定チェックをコード内で実行したりすることなどが含まれます。

ここでは、ASP.NET Web アプリケーションの内部で認定を実行するために必要な、主なプログラミング手順を説明します。

認定のパターン

以下は、Web アプリケーションの内部でユーザーを認定するための基本的なパターンを要約したものです。

  1. 資格情報を取得する。
  2. 資格情報を検証する。
  3. ユーザーをロールに関連付ける。
  4. IPrincipal オブジェクトを作成する。
  5. IPrincipal オブジェクトを現在の HTTP コンテキストに格納する。
  6. ユーザー ID およびロールのメンバシップに基づいて認定する。

重要 手順 1. ~ 5. は、Windows 認証を構成していると、ASP.NET によって自動的に実行されます。フォーム認証、Passport 認証、およびカスタムの認証など、その他の認証メカニズムでは、これらの手順を実行するコードを記述する必要があります。詳細については以下を参照してください。

資格情報を取得する

まず、一連の資格情報 (ユーザー名とパスワード) をユーザーから取得する必要があります。アプリケーションが Windows 認証を使用していない場合は、クリア テキストの資格情報が、SSL を使用することによってネットワーク上でセキュリティで保護されていることを確認する必要があります。

資格情報を検証する

Windows 認証が構成済みであれば、オペレーティング システムの基本的なサービスを使用して自動的に資格情報が検証されます。

別の認証メカニズムを使用している場合は、SQL Server データベースや Active Directory などのデータ ストアに照らし合わせて資格情報を検証するコードを記述する必要があります。

ユーザーの資格情報を SQL Server データベースに安全に格納する方法の詳細については、「第 12 章 データ アクセス セキュリティ」の「データベースとの照合によるユーザー認証」を参照してください。

ユーザーをロールに関連付ける

ユーザーのデータ ストアには、各ユーザーのロールのリストも含まれている必要があります。また、検証されたユーザー用のロール リストを取り出すコードの記述が必要です。

IPrincipal オブジェクトを作成する

認定は、ID とロール リストが現在の Web 要求のコンテキストにフローされる IPrincipal オブジェクト内に保持されている認証済みのユーザーに対して発生します。

Windows 認証が構成済みであれば、ASP.NET によって自動的に WindowsPrincipal オブジェクトが構築されます。これには、認証されたユーザーの ID と共に ロール リストが含まれています。このリストは、ユーザーが所属する Windows グループのリストに相当します。

フォーム認証、Passport 認証、またはカスタムの認証を使用している場合は、Global.asax のイベント ハンドラ Application_AuthenticateRequest 内にコードを記述して IPrincipal オブジェクトを作成する必要があります。GenericPrincipal クラスは、.NET Framework に用意されており、ほとんどのシナリオで使用することをお勧めします。

IPrincipal オブジェクトを現在の HTTP コンテキストに格納する

IPrincipal オブジェクトを (HttpContext.User 変数を使用して) 現在の HTTP コンテキストにアタッチします。Windows 認証を使用していると、ASP.NET はこの処理を自動的に実行します。そうでない場合は、オブジェクトを手動でアタッチする必要があります。

ユーザー ID とロール メンバシップの両方またはいずれかに基づいて認定する

アプリケーションで、さらにきめ細かい認証ロジックが必要な場合は、宣言型 (クラス レベルまたはメソッド レベルの認証を行うため) または強制型の .NET ロールをコード内で使用します。

PrincipalPermission クラスを使用して宣言型または強制型のプリンシパル アクセス許可要求を利用したり、IPrincipal.IsInRole() メソッドを呼び出して明示的なロール チェックを行ったりすることができます。

以下の例は、Windows 認証の使用を前提とした、宣言型のプリンシパル アクセス許可要求を示しています。属性の後のメソッドは、認証されたユーザーが Windows グループ Manager のメンバである場合にのみ実行されます。呼び出し元がこのグループのメンバではない場合は、SecurityException が返されます。

[PrincipalPermission(SecurityAction.Demand, 
Role=@"DomainName\Manager")]
public void SomeMethod()
{
}

以下の例は、コード内での明示的なロール チェックを示しています。この例では、Windows 認証の使用を前提としています。Windows 認証以外の認証メカニズムを使用する場合でも、コードはほとんど同じです。User オブジェクトは、WindowsPrincipal オブジェクトにキャストするのではなく、GenericPrincipal オブジェクトにキャストする必要があります。

// Extract the authenticated user from the current HTTP context.
// The User variable is equivalent to HttpContext.Current.User if you are using // an .aspx or .asmx page
WindowsPrincipal authenticatedUser = User as WindowsPrincipal;
if (null != authenticatedUser)
{
// Note: To retrieve the authenticated user's username, use the 
// following line of code
// string username = authenticatedUser.Identity.Name;

// Perform a role check
if (authenticatedUser.IsInRole(@"DomainName\Manager") )
  {
// User is authorized to perform manager functionality
  }
}
else
{
// User is not authorized to perform manager functionality
}

詳細情報

上のフォーム認証のパターンを実際に実装する方法については、後の「フォーム認証」を参照してください。

カスタムの IPrincipal クラスの作成

Windows 認証以外の認証メカニズムを使用している場合、.NET Framework に用意されている GenericPrincipal クラスをほとんどの状況で使用することをお勧めします。このクラスは、IPrincipal.IsInRole メソッドを使用してロール チェックを行います。

ときには、独自の IPrincipal クラスを実装しなければならないことがあります。独自の IPrincipal クラスを実装する理由には、以下のようなものがあります。

  • ロール チェック機能を拡張する必要がある場合。特定のユーザーが複数のロールのメンバであるかどうかをチェックできるメソッドが必要になることがあります。次に、例を示します。
CustomPrincipal.IsInAllRoles( "Role", "Role2", "Role3" )
CustomPrincipal.IsInAnyRole( "Role1", "Role2", "Role3" )

  • ロールのリストを配列で返す、追加のメソッドやプロパティを実装する必要がある場合。次に、例を示します。
string[] roles = CustomPrincipal.Roles;
  • アプリケーションにロールの階層のロジックを適用する必要がある場合。たとえば、Senior Manager の階層は Manager よりも上であると見なされます。これは、以下に示すようなメソッドを使用してテストすることができます。
CustomPrincipal.IsInHigherRole("Manager");
CustomPrincipal.IsInLowerRole("Manager");

  • ロール リストの遅延初期化を実装する必要がある場合。たとえば、ロール チェックが要求されたときにのみ、ロール リストを動的にロードすることができます。
  • IIdentity インターフェイスを実装して、X509ClientCertificate でユーザーを特定することができます。次に、例を示します。
CustomIdentity id = CustomPrincipal.Identity;
X509ClientCertificate cert = id.ClientCertificate;

詳細情報

独自の IPrincipal クラスを作成する方法の詳細については、このガイドの「パート IV : 参照」の「IPrincipal の実装方法」を参照してください。

Windows 認証

Windows 認証を使用するのは、アプリケーションのユーザーが、サーバーによって認証される Windows アカウントを持っている場合です。

Windows 認証に対応するように ASP.NET を構成している場合、IIS は、構成された IIS 認証メカニズムを使用してユーザーの認証を実行します。これを図 8.4 に示します。

図 8.4 ASP.NET の Windows 認証は IIS を使用して呼び出し元を認証

認証された呼び出し元のアクセス トークンは、ASP.NET アプリケーションが使用できるようになります。匿名認証に対応するように IIS が構成されている場合は、認証された呼び出し元が匿名のインターネット ユーザー アカウントである場合があります。以下の点に注意してください。

  • この結果、ASP.NET の FileAuthorizationModule は最初の呼び出し元のアクセス トークンを使用して、要求された ASP.NET ファイルに対してアクセス チェックを実行することができます。

    重要 ASP.NET のファイル認定では、Aspnet_isapi.dll にマップされるファイル タイプに対してのみ、アクセス チェックが実行されます。

  • ファイル認定には、偽装は必要ありません。偽装を有効にすると、アプリケーションによって実行されるリソースへのアクセスでは、偽装された呼び出し元の ID が使用されます。この場合は、リソースにアタッチされた ACL に、最初の呼び出し元の ID に最低でも読み取りアクセスを許可する アクセス制御エントリ (ACE) が含まれていることを確認してください。

認証されるユーザーの特定

ASP.NET によって、WindowsPrincipal オブジェクトは現在の Web 要求に関連付けられます。これには、認証された Windows ユーザーの ID に加えて、そのユーザーが属するロールのリストが含まれています。Windows 認証では、ロール リストはユーザーが所属する一連の Windows グループで構成されています。

以下のコードは、認証された Windows ユーザーの ID を取得し、認定のための単純なロール テストを実行する方法を示しています。

WindowsPrincipal user = User as WindowsPrincipal;
if (null != user)
{
string username = user.Identity.Name;
// Perform a role check
if ( user.IsInRole(@"DomainName\Manager") )
  {
// User is authorized to perform manager functionality
  }
}
else
{
// Throw security exception as we don't have a WindowsPrincipal
}  

フォーム認証

フォーム認証を使用しているとき、セキュリティで保護されたファイルやリソースにアクセスしようとする未認証のユーザーによってトリガされるイベント、つまり、URL 認定によってユーザーのアクセスが拒否される順序を図 8.5 に示します。

図 8.5 フォーム認証でのイベントの順序

以下で、図 8.5 に示されているイベントの順序を説明します。

  1. ユーザーが、Default.aspx の Web 要求を発行します。

    匿名アクセスが有効になっているので、IIS は要求を許可します。ASP.NET は <authorization> 要素をチェックし、<deny users=?" /> 要素を検出します。

  2. ユーザーは、<forms> 要素の LoginUrl 属性での指定に従って、ログイン ページ (Login.aspx) にリダイレクトされます。

  3. ユーザーは資格情報を入力し、ログイン フォームを送信します。

  4. 資格情報は、SQL Server または Active Directoryのストアと照らし合わせて検証され、必要に応じてロールが取り出されます。ロール ベースの認証を使用する場合は、ロール リストを取得する必要があります。

  5. FormsAuthenticationTicket を使用して Cookie が作成され、クライアントに送信されます。ロールは、必要に応じてチケットに格納されます。ロール リストをチケットに格納すると、引き続き同じユーザーから Web 要求があるたびにデータベースにアクセスしてリストを取得し直す必要がなくなります。

  6. ユーザーは、クライアント側のリダイレクトにより、最初に要求したページ Default.aspx にリダイレクトされます。

  7. Global.asax 内のイベント ハンドラ Application_AuthenticateRequest では、チケットを使用して IPrincipal オブジェクトが作成され、HttpContext.User に格納されます。

    ASP.NET は <authorization> 要素をチェックし、<deny users=?" /> 要素を検出します。ただし、このときはユーザーが認証されます。

    ASP.NET は <authorization> 要素をチェックして、そのユーザーが <allow> 要素内に存在することを確認します。

    ユーザーは、Default.aspx へのアクセスを許可されます。

フォーム認証の開発手順

以下のリストは、フォーム認証を実装するために行う必要がある主な手順を説明したものです。

  1. 匿名アクセスに対応するように IIS を構成します。
  2. フォーム認証に対応するように ASP.NET を構成します。
  3. ログオン用の Web フォームを作成し、提供された資格情報を検証します。
  4. ロール リストをカスタムのデータ ストアから取り出します。
  5. フォーム認証のチケットを作成して、ロールをチケット内に格納します。
  6. IPrincipal オブジェクトを作成します。
  7. IPrincipal オブジェクトを現在の HTTP コンテキストに格納します。
  8. ユーザー名およびロール メンバシップに基づいてユーザーを認定します。

匿名アクセスに対応するように IIS を構成する

アプリケーションの仮想ディレクトリは、匿名アクセスに対応するように IIS で構成されている必要があります。

■ 匿名アクセスに対応するように IIS を構成するには

  1. インターネット インフォメーション サービスの管理ツールを起動します。
  2. アプリケーションの仮想ディレクトリを選択し、右クリックして [プロパティ] をクリックします。
  3. [ディレクトリ セキュリティ] をクリックします。
  4. [匿名アクセスおよび認証コントロール] の [編集] をクリックします。
  5. [匿名アクセス] チェック ボックスをオンにします。

フォーム認証に対応するように ASP.NET を構成する

サンプルの構成を以下に示します。

<authentication mode="Forms">
<forms name="MyAppFormsAuth" 
loginUrl="login.aspx" 
protection="Encryption"
timeout="20" 
path="/" >
</forms>
</authentication>

ログオン用の Web フォームを作成し、提供された資格情報を検証する

SQL Server データベースまたは Active Directory に照らし合わせて資格情報を検証します。

詳細情報

ロール リストをカスタムのデータ ストアから取り出す

SQL Server データベース内部のテーブル、または Active Directory 内部で構成されているグループおよび配布リストから、ロールを取得します。詳細については、前の「詳細情報」を参照してください。

フォーム認証チケットを作成する

取り出したロールをチケットに格納します。以下のコードは、この処理を示したものです。

// This event handler executes when the user clicks the Logon button
// having supplied a set of credentials
private void Logon_Click(object sender, System.EventArgs e)
{
// Validate credentials against either a SQL Server database
// or Active Directory
bool isAuthenticated = IsAuthenticated( txtUserName.Text, 
txtPassword.Text );
if (isAuthenticated == true )
  {
// Retrieve the set of roles for this user from the SQL Server
// database or Active Directory.The roles are returned as a
// string that contains pipe separated role names
// for example "Manager|Employee|Sales|"
// This makes it easy to store them in the authentication ticket

string roles = RetrieveRoles( txtUserName.Text, txtPassword.Text );

// Create the authentication ticket and store the roles in the
// custom UserData property of the authentication ticket
FormsAuthenticationTicket authTicket = new 
FormsAuthenticationTicket(
1,                          // version
txtUserName.Text,           // user name
DateTime.Now,               // creation
DateTime.Now.AddMinutes(20),// Expiration
false,                      // Persistent
roles );                    // User data
// Encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// Create a cookie and add the encrypted ticket to the 
// cookie as data.
HttpCookie authCookie = 
new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket);

// Add the cookie to the outgoing cookies collection. 
Response.Cookies.Add(authCookie); 
// Redirect the user to the originally requested page
Response.Redirect( FormsAuthentication.GetRedirectUrl(
txtUserName.Text, 
false}"false ));
  }
}

IPrincipal オブジェクトを作成する

Global.asax 内のイベント ハンドラ Application_AuthenticationRequest で IPrincipal オブジェクトを作成します。ロールベースの拡張機能が必要な場合を除き、GenericPrincipal クラスを使用してください。その機能が必要な場合は、IPrincipal を実装するカスタム クラスを作成します。

IPrincipal オブジェクトを現在の HTTP コンテキストに格納する

GenericPrincipal オブジェクトの作成方法を以下に示します。

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if(null == authCookie)
  {
// There is no authentication cookie.
return;
  } 
FormsAuthenticationTicket authTicket = null;
try
  {
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
  }
catch(Exception ex)
  {
// Log exception details (omitted for simplicity)
return;
  }
if (null == authTicket)
  {
// Cookie failed to decrypt.
return;
  }
// When the ticket was created, the UserData property was assigned a
// pipe delimited string of role names.
string[] roles = authTicket.UserData.Split(new char[]{'|'});

// Create an Identity object
FormsIdentity id = new FormsIdentity( authTicket ); 
// This principal will flow throughout the request.
GenericPrincipal principal = new GenericPrincipal(id, roles);
// Attach the new principal object to the current HttpContext object
Context.User = principal;
}

ユーザー名およびロール メンバシップに基づいてユーザーを認定する

メソッドへのアクセスを制限するには、宣言型のプリンシパル アクセス許可要求を使用します。きめ細かな認定をメソッド内部で実行するには、強制型のプリンシパル アクセス許可要求と明示的なロール チェック (IPrincipal.IsInRole) の両方またはいずれかを使用します。

フォームの実装に関するガイドライン

  • HTML フォームを使用して資格情報を取得するときは、SSL を使用します。

    ログイン ページでの SSL の使用に加えて、ネットワーク上で資格情報または認証 Cookie が送信されるときは、その他のページでも必ず SSL を使用する必要があります。これは、Cookie のリプレイ攻撃の脅威を軽減するためです。

  • カスタムのデータ ストアに照らし合わせてユーザーを認証します。SQL Server または Active Directory を使用します。

  • ロール リストをカスタムのデータ ストアから取り出し、区切られたロールのリストを FormsAuthenticationTicket クラスの UserData プロパティに格納します。これにより、各 Web 要求でデータ ストアに何度もアクセスすることがなくなり、パフォーマンスが向上するほか、ユーザーの資格情報を認証 Cookie に格納せずにすみます。

  • ロールのリストのサイズが大きく、Cookie のサイズ制限を超える危険性がある場合は、ロールの詳細を ASP.NET のキャッシュ オブジェクトまたはデータベースに格納し、その後に要求が行われるたびに取り出します。

  • 最初に認証した後の各要求については、以下の処理を行います。

    • イベント ハンドラ Application_AuthenticateRequest で、チケットからロールを取り出します。
    • IPrincipal オブジェクトを作成し、HTTP コンテキスト HttpContext.User に格納します。また、.NET Framework も、このオブジェクトを現在の .NET スレッド Thread.CurrentPrincipal に関連付けます。
    • 拡張されたロールベースの操作をサポートするなど、カスタムの IPrincipal を実装する特別な必要性がない限り、GenericPrincipal クラスを使用します。

2 つの Cookie を使用します。1 つはユーザーの識別に、もう 1 つは認証および認定に使用されます。ユーザーを識別する Cookie を永続化します。ただし、サイトのセキュリティで保護された部分で注文を出すなどの、制限されている操作を実行するための要求を許可する情報が Cookie に含まれないようにしてください。

Web アプリケーションごとに、<forms> 要素の Forms 属性を使用して、別々の Cookie 名およびパスを使用します。これにより、1 つのアプリケーションに対して認証されたユーザーが、同じ Web サーバーによってホストされる別のアプリケーションを使用するときに、不意に認証済みとして処理されることを防ぎます。

クライアントのブラウザで Cookies が有効になっていることを確認します。Cookie を必要としないフォーム認証を使用する方法については、後の「Cookie を使用しないフォーム認証」を参照してください。

詳細情報

フォーム認証を使用した複数のアプリケーションのホスティング

同じ Web サーバーでフォーム認証を使用する複数の Web アプリケーションを運用している場合は、1 つのアプリケーションで認証されたユーザーは、アプリケーションのログオン ページにリダイレクトされることなく、別のアプリケーションに要求を行うことができます。2 番目のアプリケーションの URL 認定の規則によって、ユーザーのアクセスが拒否されることがあります。この場合、ログオン フォームを使用してログオン資格情報を入力する機会は用意されません。

この状態が発生するのは、<forms> 要素の名前とパスの属性が複数のアプリケーションで同一であり、各アプリケーションが Web.config の共通の <machineKey> 要素を使用している場合だけです。

詳細情報

この問題とその解決方法の詳細については、以下の Microsoft サポート技術情報の Knowledge Base の文書を参照してください。

Cookie を使用しないフォーム認証ソリューションが必要な場合は、Microsoft Mobile Internet Toolkit によって使用される方法を採用することを検討してください。モバイル フォーム認証は、フォーム認証に基づいていますが、Cookie ではなくクエリ文字列を使用して認証チケットを伝達します。

詳細情報

モバイル フォーム認証の詳細については、Microsoft サポート技術情報の Knowledge Base の文書 311568 「INFO: How To Use Mobile Forms Authentication with Microsoft Mobile Internet Toolkit」(英語情報) を参照してください。

Passport 認証

Passport 認証を使用するのは、アプリケーションのユーザーが Passport アカウントを持っており、Passport が有効な別のサイトと統一したシングル サインオン ソリューションを実装する必要がある場合です。

Passport 認証に対応するように ASP.NET を構成すると、ユーザーにはログインを求めるメッセージが表示され、Passport サイトにリダイレクトされます。資格情報が正しく検証された後、ユーザーは最初のサイトにリダイレクトされます。

Passport 認証に対応するように ASP.NET を構成する

Passport 認証に対応するように ASP.NET を構成するには、Web.config の以下の設定を使用します。

<authentication mode="Passport">
<passport redirectUrl="internal" />
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>

Passport ID を Global.asax のロールにマップする

Passport ID をロールにマップするには、以下に示すように、Global.asax でイベント ハンドラ PassportAuthentication_OnAuthentication を実装します。

void PassportAuthentication_OnAuthenticate(Object sender, 
PassportAuthenticationEventArgs e)
{
if(e.Identity.Name == "0000000000000001")
  {
string[] roles = new String[]{"Developer", "Admin", "Tester"};
Context.User = new GenericPrincipal(e.Identity, roles);
  }
}

ロール メンバシップをテストする

以下のコードは、認証された Passport ID を取り出し、aspx ページでロール メンバシップをチェックする方法を示しています。

PassportIdentity passportId = Context.User.Identity as PassportIdentity;
if (null == passportId)
{
Response.Write("Not a PassportIdentity<br>");
return;
}
Response.Write("IsInRole: Develeoper?" + Context.User.IsInRole("Developer"));

カスタム認証

.NET Framework に付属する認証モジュールが、自分が必要とする認証方法に合わない場合は、カスタム認証を使用し、独自の認証メカニズムを実装することができます。たとえば、所属する企業が、他のアプリケーションで広く使用されているカスタムの認証方法を既に採用していることがあります。

ASP.NET で、カスタムの認証を実装するには、以下の手順に従います。

  • 以下に示すように、Web.config で認証モードを構成します。これにより、組み込みの認証スキーム モジュールを呼び出す必要がないことが ASP.NET に通知されます。
<authentication mode="None" />
  • System.Web.IHttpModule インターフェイスを実装するクラスを作成して、カスタムの HTTP モジュールを作成します。このモジュールは、HttpApplication.AuthenticateRequest イベントにフックし、認証が必要なときにアプリケーションへの各要求で呼び出されるデリゲートを提供する必要があります。

    認証モジュールは、以下の処理を行う必要があります。

    • 呼び出し元から資格情報を取得する。
    • ストアに照らし合わせて資格情報を検証する。
    • IPrincipal オブジェクトを作成し、HttpContext.User に格納する。
    • 認証トークンを作成および保護し、クエリ文字列、Cookie、または隠しフォーム フィールドでユーザーに送信する。
    • その後の要求で認証トークンを取得、検証して再度発行する。

詳細情報

カスタムの HTTP モジュールを実装する方法の詳細については、Microsoft サポート技術情報の Knowledge Base の文書 307996「[HOW TO] Visual C# .NET を使用して ASP.NET HTTP モジュールを作成する方法」を参照してください。

ASP.NET のプロセス ID

最低限の特権を付与したアカウントを使用して、ASP.NET (特に、ワーカー プロセス Aspnet_wp.exe) を実行します。

最低限の特権のアカウントを使用する

最低限の特権のアカウントを使用すると、プロセスが悪用される脅威を軽減できます。悪意のあるユーザーが、Web アプリケーションを実行する ASP.NET プロセスを突破した場合、そのプロセス アカウントに付与された特権やアクセス権を簡単に継承し、利用することができます。アカウントを最低限の特権で構成すると、発生する可能性のある損害が限定されます。

SYSTEM として実行しない

高度な特権が付与されている SYSTEM アカウントを使用して ASP.NET を実行したり、ASP.NET プロセス アカウントに "オペレーティング システムの一部として動作する" 特権を付与したりしないでください。このいずれかを実行し、コードから LogonUser API を呼び出して固定 ID を取得できるようにしたいと思うことがあります。これを実行する別の方法については、後の「ネットワーク リソースへのアクセス」を参照してください。

SYSTEM として実行しない理由、および "オペレーティング システムの一部として動作する" 特権を付与しない理由には、以下のものがあります。

  • システムが突破されたときに、悪意のあるユーザーによって引き起こされる被害が著しく増大する可能性があります。ただし、脆弱性が増すことはありません。
  • 最低限の特権の原則が無視されることになります。ASP.NET アカウントは、特に、ASP.NET Web アプリケーションを実行するために設計された最低限の特権のアカウントとして構成されています。

詳細情報

オペレーティング システムの一部として動作する 特権の詳細については、1999 年 8 月発行の「Microsoft Systems Journal」の「Security Briefs」(英語情報) を参照してください。

ドメイン コントローラと ASP.NET プロセス アカウント

ほとんどの場合、Web サーバーをドメイン コントローラ上で実行することはお勧めできません。これは、サーバーへの脅威がドメインの脅威につながるためです。ASP.NET をドメイン コントローラ上で実行する必要がある場合は、ASP.NET プロセス アカウントに適切な特権を付与しなければなりません。これについては、Microsoft サポート技術情報の Knowledge Base の文書 315158「ドメイン コントローラで管理者以外のドメイン アカウントを使用すると ASP.NET が動作しない」を参照してください。

既定の ASPNET アカウントの使用方法

ローカルの ASPNET アカウントは、最低限の特権で ASP.NET Web アプリケーションを実行することを目的として構成されています。できるだけ ASPNET アカウントを使用してください。

既定では、ASP.NET Web アプリケーションは、Machine.config 内の <processModel> 要素での構成に従って、このアカウントを使用して実行されます。

<processModel userName="machine" password="AutoGenerate" />

メモ "machine" というユーザー名は、ASPNET アカウントを示しています。このアカウントは、.NET Framework をインストールするときに暗号強度の高いパスワードを使用して作成されます。セキュリティ アカウント マネージャ (SAM) データベースの内部で構成されることに加え、このパスワードはローカル コンピュータの LSA (Local System Authority) に格納されます。システムは、ASP.NET ワーカー プロセスを起動するときに、パスワードを LSA から取り出します。

アプリケーションがネットワーク リソースにアクセスする場合、ASPNET アカウントはリモート コンピュータによって認証されることが可能である必要があります。これには、2 つの方法があります。

  • ASPNET アカウントのパスワードを既知の値に再設定し、同じ名前とパスワードを使用して、重複するアカウントをリモート コンピュータで作成します。この方法は、以下の場合にのみ使用することができます。
    • Web サーバーとリモート コンピュータが、別々のドメインに存在し、信頼関係がない。
    • Web サーバーとリモート コンピュータがファイアウォールで区切られており、Windows 認証をサポートするために必要なポートを開きたくない。

管理の簡略化が主な問題である場合は、最低限の特権のドメイン アカウントを使用します。

パスワードを手動で更新し、同期する必要をなくすため、最低限の特権のドメイン アカウントを使用して ASP.NET を実行することができます。プロセスを悪用される危険性を軽減するためにドメイン アカウントを完全にロックするのは非常に重要です。悪意のあるユーザーが ASP.NET のワーカー プロセスを突破した場合、アカウントが完全にロックされていなければ、ドメインのリソースにアクセスすることが可能です。

メモ ローカルのアカウントを使用していて、このアカウントが悪用された場合でも、攻撃を受けるコンピュータは重複したアカウントを作成したコンピュータだけです。ドメイン アカウントを使用している場合は、このアカウントはドメイン内の各コンピュータで表示できます。ただし、このアカウントは、これらのコンピュータにアクセスするための権限を持つ必要があります。

<processModel> 要素

Machine.config ファイルの <processModel> 要素には、userName 属性と password 属性が含まれており、ASP.NET のワーカー プロセス (Aspnet_wp.exe) を実行するのに使用されるアカウントが指定されています。この設定を構成するための多数のオプションが用意されています。次に、例を示します。

  • "machine" ワーカー プロセスは、既定の最低限の特権の ASPNET アカウントとして実行されます。このアカウントは、ネットワークにアクセスできますが、ネットワークのその他のコンピュータに対して認証することはできません。これは、アカウントがコンピュータでローカルであり、アカウントを保証する権限がないためです。ネットワークでは、このアカウントは "MachineName\ASPNET" と表されます。

  • "system" ワーカー プロセスは、ローカルの SYSTEM アカウントとして実行されます。このアカウントには、ローカル コンピュータの多数の権限があります。また、このアカウントは、コンピュータの資格情報を使用してネットワークにアクセスすることもできます。ネットワークでは、このアカウントは "DomainName\MachineName$" と表されます。

  • 特定の資格情報 資格情報を userName および password に指定するときは、最低限の特権の原則を意識してください。ローカル アカウントを指定する場合、重複するアカウントをリモート コンピュータに作成しない限り、ネットワークで Web アプリケーションを認証することができません。最低限の特権のドメイン アカウントを使用することを選んだ場合は、必要なもの以外はネットワークのコンピュータにアクセスする権限がアカウントにないことを確認します。

    .NET Framework Version 1.1 では、userName 属性と password 属性を暗号化してレジストリに格納することができます。

メモ 従来の ASP アプリケーションを実行する方法とは対照的に、アプリケーションの保護レベルが High (Isolated) に設定されていても、ASP.NET のコードは dllhost.exe プロセスでは実行されませんし、IWAM_MACHINENAME アカウントとしても実行されません。

IIS に送信される ASP.NET の要求は、ASP.NET のワーカー プロセス (Aspnet_wp.exe) に直接ルーティングされます。ASP.NET ISAPI 拡張機能の Aspnet_isapi.dll は、IIS (Inetinfo.exe) プロセスのアドレス空間で実行されます。これは、InProcessIsapiApps メタベース エントリによって指定されています。このエントリは変更しないでください。ISAPI 拡張機能は、要求を ASP.NET のワーカー プロセスにルーティングする役割を担っています。このとき、ASP.NET アプリケーションは、アプリケーション ドメインによって分離境界が確立されている ASP.NET ワーカー プロセスで実行されます。

IIS 6 では、各プールが独自のアプリケーションのインスタンスを持つアプリケーション プールを構成することによって ASP.NET アプリケーションを隔離することが可能です。

詳細情報

ASP.NET Web アプリケーションからネットワーク リソースにアクセスする方法の詳細については、後の「ネットワーク リソースへのアクセス」を参照してください。

ASP.NET を実行するためのカスタムのアカウントを作成する方法については、このガイドの「パート IV : 参照」の「ASP.NET の実行に使用するカスタム アカウントの作成方法」を参照してください。

偽装

FileAuthorizationModule を採用し、ゲートキーパーと信頼の境界を効果的に使用した状態でも、ASP.NET での偽装は利点よりも欠点が多いことがわかります。

偽装およびローカルのリソース

偽装を使用し、Web アプリケーションのコードからローカルのリソースにアクセスする場合は、セキュリティで保護された各リソースにアタッチされた ACL を構成して、認証されたユーザーに最低でも読み取りアクセスを許可する ACE が含まれるようにする必要があります。

これよりも良い方法は、偽装を使用せず、ASP.NET プロセス アカウントにアクセス許可を付与し、URL 認定、ファイル認定、および宣言型と強制型のロールベース チェックの組み合わせを使用することです。

偽装およびリモートのリソース

偽装を使用し、リモートのリソースに Web アプリケーションのコードからアクセスする場合は、基本認証、フォーム認証、または Kerberos 認証を使用していない限り、アクセスに失敗します。Kerberos 認証を使用する場合は、ユーザー アカウントが委任に対応するように適切に構成されている必要があります。Active Directory 内で、ユーザー アカウントは "機密性が高く、委任できない" とマークされている必要があります。

詳細情報

Kerberos での委任の構成方法の詳細については、以下を参照してください。

偽装およびスレッド

偽装を実行しているスレッドが新しいスレッドを作成すると、新しいスレッドは ASP.NET プロセス アカウントのセキュリティ コンテキストを継承しますが、偽装されたアカウントは継承しません。

システム リソースへのアクセス

ASP.NET は、既定では偽装を行いません。結果として、Web アプリケーションはローカルのシステム リソースにアクセスする場合、ワーカー プロセス Aspnet_wp.exe に関連付けられたセキュリティ コンテキストを使用してアクセスします。このセキュリティ コンテキストは、ワーカー プロセスの実行に使用されたアカウントによって決まります。

イベント ログへのアクセス

最低限の特権のアカウントには、既存のイベント ソースを使用してイベント ログにレコードを書き込むことが可能な十分なアクセス許可があります。ただし、新しいイベント ソースを作成するための十分な権限はありません。作成するには、以下のレジストリの下に配置される新しいエントリが必要です。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\<log>

この問題を回避するため、管理者特権が使用可能なインストール時に、アプリケーションによって使用されるイベント ソースを作成します。良い方法としては、msi での導入を行っている場合は Windows インストーラまた msi での導入を行っていない場合は InstallUtil.exe システム ユーティリティでインスタンス化することが可能な .NET のインストーラ クラスを使用することがあります。

イベント ソースをインストール時に作成することができない場合は、以下のレジストリ キーにアクセス許可を追加し、ASP.NET プロセス アカウント (アプリケーションが偽装を使用する場合は、偽装されたアカウント) にアクセスを許可します。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog

アカウントには、以下の最低限のアクセス許可が必要です。

  • キー値の照会
  • キー値の設定
  • サブキーの作成
  • サブキーの列挙
  • 通知
  • 読み取り

アクセス許可をレジストリに適用すると、以下のコードを使用して ASP.NET からアプリケーション イベント ログに書き込みを行うことができます。

string source = "Your Application Source";
string logToWriteTo = "Application";
string eventText = "Sample Event";

if (!EventLog.SourceExists(source))
{
EventLog.CreateEventSource(source, logToWriteTo);
}
EventLog.WriteEntry(source, eventText, EventLogEntryType.Warning, 234);

レジストリへのアクセス

アプリケーションによってアクセスされるレジストリ キーには、いずれも ASP.NET プロセス アカウントに読み取りアクセスを許可する ACL に ACE が含まれている必要があります。

詳細情報

インストーラ クラスおよびインストーラ ツール (Installutil.exe) の詳細については、MSDN ライブラリの「.NET Framework ツール」を参照してください。

COM オブジェクトへのアクセス

従来の ASP では、要求は STA (Single Threaded Apartment) スレッド プールからのスレッドを使用して処理されます。ASP.NET では、要求は MTA (Multithreaded Apartment) スレッド プールからのスレッドを使用して処理されます。これは、アパートメント モデル オブジェクトを呼び出す ASP.NET Web アプリケーションに深く関係しています。

アパートメント モデル オブジェクト

ASP.NET Web アプリケーションが Visual Basic 6 の COM オブジェクトなどのアパートメント モデル オブジェクトを呼び出すときには、注意の必要な問題が 2 つあります。

  • 以下のように、ASP.NET ページを AspCompat ディレクティブでマークする必要があります。
<%@ Page Language="C#" AspCompat="True" %>
  • 特定の Page イベント ハンドラ外で COM オブジェクトを作成しないでください。COM オブジェクトは、Page_Load や Page_Init など、必ず Page イベント ハンドラ内に作成します。ページのコンストラクタ内に COM オブジェクトを作成しないでください。

AspCompat ディレクティブが必要

既定では、ASP.NET は MTA スレッドを使用して要求を処理します。この結果、アパートメント モデル オブジェクトが ASP.NET から呼び出されるときにスレッド切り替えが行われます。これは、Apartment モデル オブジェクトには、MTA スレッドは直接アクセスできないためです (COM は STA スレッドを使用します)。

AspCompat を指定すると、STA スレッドによってページが処理されます。これにより、MTA から STA へのスレッド切り替えが行われなくなります。スレッド切り替えが発生すると、結果として偽装トークンが失われるため、Web アプリケーションが偽装を行っている場合、スレッド切り替えの発生を防止するのはセキュリティ面から見ても重要なことです。新しいスレッドは、偽装トークンが関連付けされません。

AspCompat ディレクティブは、ASP.NET Web サービスではサポートされていません。つまり、アパートメント モデル オブジェクトを Web サービスのコードから呼び出しても、スレッド切り替えが発生し、スレッドの偽装トークンは失われることになります。この結果、ほとんどの場合 "アクセスが拒否されました" という例外が発生します。

詳細情報

特定の Page イベントの外部で COM オブジェクトを作成しない

特定の Page イベント ハンドラ外で COM オブジェクトを作成しないでください。以下のコードは、実行してはいけない処理を示しています。

<%@ Page Language="C#" AspCompat="True" %>
<script runat="server">
// COM object created outside of Page events
YourComObject obj = new apartmentObject();
public void Page_Load()
  {
obj.Foo()
  }
</script>

アパートメント モデル オブジェクトを使用するときは、Page_Load などの特定の Page イベント内でオブジェクトを作成することが重要です。この例を以下に示します。

<%@ Page Language="C#" AspCompat="True" %>
<script runat="server">
public void Page_Load()
{
YourComObject obj = new apartmentObject();
obj.Foo()
}
</script>

詳細情報

詳細については、Microsoft サポート技術情報の Knowledge Base の文書 308095「[PRB] ASP.NET ASPCOMPAT モードでコンストラクタの中で STA コンポーネントを作成するとパフォーマンスが低下する」を参照してください。

COM+ での C# および VB .NET のオブジェクト

Microsoft C#® 開発ツールおよび Microsoft Visual Basic® .NET 開発システムでは、フリー スレッド、Neutral、Both、および Apartment など、すべてのスレッド モデルがサポートされています。既定では、COM+ 内でホストされているとき、C# および Visual Basic .NET のオブジェクトは Both とマークされています。その結果、オブジェクトが ASP.NET によって呼び出されると、アクセスは直接行われ、スレッド切り替えは発生しません。

ネットワーク リソースへのアクセス

アプリケーションは、ネットワーク リソースにアクセスしなければならないことがあります。この場合、以下を特定できることが重要です。

  • アプリケーションがアクセスする必要があるリソース。

    たとえば、ファイル共有のファイル、データベース、DCOM サーバー、Active Directory オブジェクトなどです。

  • リソースへのアクセスを実行するのに使用される ID。

    アプリケーションがリモートのリソースにアクセスする場合、ID はリモート コンピュータによって認証されることが可能でなければなりません。

    メモ リモートの SQL Server データベースへのアクセスについての詳細は、「第 12 章 データ アクセス セキュリティ」を参照してください。

リモートのリソースに ASP.NET アプリケーションからアクセスするには、以下のいずれかの方法を使用します。

  • ASP.NET プロセス ID を使用する。
  • サービス対象のコンポーネントを使用する。
  • IUSR_MACHINE など、匿名のインターネット ユーザー アカウントを使用する。
  • LogonUser API を使用し、特定の Windows ID を偽装する。
  • 最初の呼び出し元を使用する。

ASP.NET プロセス ID の使用方法

アプリケーションが偽装に対応するように構成されていないと、ASP.NET プロセス ID は、アプリケーションがリモートのリソースにアクセスするときに既定の ID を提供します。リモートのリソースにアクセスするために ASP.NET プロセス アカウントを使用する必要がある場合は、以下の 3 つの選択肢があります。

  • ミラー化されたアカウントを使用します。

    これは、最も簡単な方法です。同じユーザー名とパスワードのローカル アカウントをリモート コンピュータに作成します。ユーザー マネージャで ASPNET アカウントのパスワードを既知の値に変更する必要があります。パスワードは、強力なものを指定します。次に、これを Machine.config の <processModel> 要素で明示的に設定し、既存の値 "AutoGenerate" を置き換えます。

    重要 ASPNET のパスワードを既知の値に変更すると、LSA のパスワードは SAM アカウントのパスワードと一致しなくなります。既定値の "AutoGenerate" に戻す必要がある場合は、以下のいずれかを実行しなければなりません。

    Aspnet_regiis.exe を実行して、ASP.NET を既定の構成にリセットします。詳細については、Microsoft サポート技術情報の Knowledge Base の文書 306005[HOWTO] IIS を削除して再インストールした後、IIS マッピングを修復する方法」を参照してください。

  • 最低限の特権のカスタムのローカル アカウントを作成して ASP.NET を実行し、重複するアカウントをリモートのコンピュータに作成します。

  • 最低限の特権のドメイン アカウントを使用して ASP.NET を実行します。これは、クライアントおよびサーバーのコンピュータが同じドメインまたは信頼関係のあるドメイン内にあることを前提としています。

詳細情報

ASP.NET プロセス アカウントの構成の詳細については、このガイドの「パート IV : 参照」の「ASP.NET の実行に使用するカスタム アカウントの作成方法」を参照してください。

サービス対象のコンポーネントの使用方法

ネットワーク リソースにアクセスするために固定 ID として実行されるように構成された、サービス対象のアウト プロセス コンポーネントを使用することができます。この方法を、図 8.6 に示します。

図 8.6 サービス対象のアウト プロセス コンポーネントを使用して、ネットワーク リソースにアクセスするための固定 ID を提供

Enterprise Services サーバー アプリケーションでサービス対象のアウト プロセス コンポーネントを使用すると、以下の利点が得られます。

  • 使用される ID についての柔軟性。ASP.NET の ID だけを使用しなくて済みます。

  • 信頼されたコードまたは高度な特権のコードを、メインの Web アプリケーションから隔離することができます。

  • プロセス ホップを追加すると、セキュリティのレベルが上がります。これにより、悪意のあるユーザーがプロセス境界を超え、特権のあるプロセスに達することが難しくなります。

  • LogonUser API 呼び出しを使用して独自の偽装を行う必要がある場合、メインの Web アプリケーションから分離されたプロセスでこれを実行できます。

    メモ LogonUser を呼び出すには、Enterprise Services のプロセス アカウントに "オペレーティング システムの一部として動作する" 特権を付与する必要があります。Web アプリケーションから分離されたプロセスの特権を生成すると、セキュリティの問題が少なくなります。

匿名のインターネット ユーザー アカウントの使用方法

IIS が匿名認証に対応するように構成されていれば、匿名のインターネット ユーザー アカウントを使用してネットワーク リソースにアクセスすることができます。これは、以下のいずれかに該当する場合に実行可能です。

  • アプリケーションが匿名アクセスをサポートしている。
  • アプリケーションが、フォーム認証、Passport 認証、またはカスタム認証を使用している。つまり、IIS が匿名アクセスに対応するように構成されている場合。

■ リモートのリソースにアクセスするために匿名アカウントを使用するには

  1. 匿名認証に対応するように IIS を構成します。ASP.NET の認証モードは、アプリケーションの認証の要件に従って、Windows、Forms、Passport、または None に設定することができます。

  2. ASP.NET を偽装に対応するように構成します。Web.config で、以下の設定を使用します。

<identity impersonate="true" />
  1. 匿名アカウントを最低限の特権のドメイン アカウントとして構成します。または

    リモート コンピュータで同じユーザー名とパスワードを使用して、匿名アカウントを複製します。この方法が必要になるのは、Windows 統合認証のサポートに必要なポートが開いていない場合に、信頼されていないドメイン間で呼び出しを行ったり、ファイアウォールを通じて呼び出しを行ったりするときです。

    この方法を使用できるようにするには、以下の作業を実行する必要もあります。

    1. インターネット サービス マネージャを使用して、匿名アカウントの [IIS によるパスワードの管理を許可する] チェック ボックスをオフにします。

      このオプションをオンにすると、指定された匿名アカウントを使用して作成されたログオン セッションはネットワーク資格情報が NULL になります。このため、ネットワーク リソースへのアクセスに使用することができません。このオプションをオフにすると、ログオンセッションはネットワーク資格情報を持つ、インタラクティブなログオン セッションになります。

    2. アカウントの資格情報をユーザー マネージャおよびインターネット サービス マネージャの両方で設定します。

    重要 匿名アカウント (IUSR_MACHINE など) を偽装する場合は、このアカウントに対して (適切に構成された ACL を使用して) リソースをセキュリティで保護する必要があります。アプリケーションがアクセスする必要があるリソースでは、最低でも読み取りアクセスを匿名アカウントに許可する必要があります。その他のすべてのリソースでは、匿名アカウントにアクセスを許可しないでください。

複数の Web アプリケーションのホスティング

Web サイト内の各仮想ルートには、別々の匿名のインターネット ユーザー アカウントを使用することができます。ホストされた環境では、こうすることによって別々の Web アプリケーションから発信された要求を個別に認定、追跡管理、および監査することができます。この方法を、図 8.7 に示します。

図 8.7 別々の匿名のインターネット ユーザー アカウントをアプリケーション (仮想ディレクトリ) ごとに偽装する

■ 特定の仮想ディレクトリに対して匿名のインターネット ユーザー アカウントを構成するには

  1. [管理ツール] プログラム グループの [インターネット サービス マネージャ] を起動します。
  2. 構成する仮想ディレクトリを選択し、右クリックして [プロパティ] をクリックします。
  3. [ディレクトリ セキュリティ] タブをクリックします。
  4. [匿名アクセスおよび認証コントロール] の [編集] をクリックします。
  5. [匿名アクセス] チェック ボックスをオンにし、[編集] をクリックします。
  6. 匿名ユーザーがサイトに接続するときに IIS によって使用されるアカウントのユーザー名とパスワードを入力します。
  7. [IIS によるパスワードの管理を許可する] がオフになっていることを確認します。

LogonUser の使用方法および特定の Windows ID を偽装する方法

Web.config の <identity> 要素でユーザー名とパスワードの属性を構成するか、アプリケーションのコードで Win32® の LogonUser API を呼び出すと、特定の ID を偽装することができます。

重要 これらの方法はお勧めしません。Windows 2000 サーバーでは、どちらの方法も使用しないでください。これらの方法では "オペレーティング システムの一部として動作する" 特権を ASP.NET プロセス アカウントに許可する必要があるためです。その結果、Web アプリケーションのセキュリティが著しく低下します。

Windows Server 2003 では、この制限が改善される予定です。

最初の呼び出し元の使用方法

最初の呼び出し元の ID を使用してリモートのリソースにアクセスするには、呼び出し元のセキュリティ コンテキストを Web サーバーからリモート コンピュータに委任できるようになっている必要があります。

拡張性に関する警告 最初の呼び出し元の偽装された ID を使用して、アプリケーションのデータ サービス層にアクセスすると、アプリケーションの拡張性に重大な影響を及ぼします。これは、データベース接続プールが無効になるためです。データベース接続のセキュリティ コンテキストは、ユーザーごとに異なります。

以下の認証スキームは、委任をサポートしています。

  • Kerberos 認証 詳細については、このガイドの「パート IV : 参照」の「Windows 2000 での Kerberos 委任の構成方法」を参照してください。

  • Windows アカウントにマップされるクライアント証明書 マッピングは、IIS によって実行される必要があります。

  • 基本認証 基本認証では、Web サーバーで最初の呼び出し元の資格情報をクリア テキストで使用できるため、リモートのリソースへのアクセスがサポートされています。これらは、リモート コンピュータからの認証要求に応答するために使用することができます。

    基本認証は、インタラクティブなログオンまたはバッチ ログオンのセッションと組み合わせて使用する必要があります。基本認証の結果として生じるログオン セッションの種類は、IIS メタベースで構成することができます。詳細については、MSDN ライブラリの「Platform SDK: Internet Information Services 5.1」(英語情報) を参照してください。

    重要 基本認証は、委任をサポートしていますが、安全性が最も低い方法です。この理由は、クリア テキストのユーザー名とパスワードが、ネットワークを通じてブラウザからサーバーに渡され、Web サーバーでメモリにキャッシュされるためです。SSL を使用して転送中に資格情報を保護することはできますが、Web サーバーでクリア テキストの資格情報をキャッシュするのはできるだけ避けてください。

■ リモートのリソースにアクセスするために最初の呼び出し元を使用するには

  1. 統合 Windows (Kerberos) 認証、証明書認証 (IIS の証明書マッピングを使用)、または基本認証に対応するように IIS を構成します。
  2. ASP.NETを Windows 認証および偽装に対応するように構成します。
<authentication mode="Window" />
<identity impersonate="true" /> 

  1. Kerberos の委任を使用する場合は、Active Directory のアカウントを委任に対応するように構成します。

詳細情報

UNC ファイル共有のファイルへのアクセス

アプリケーションが、ASP.NET を使用して UNC (汎用名前付け規則) 共有のファイルにアクセスする必要がある場合は、共有のフォルダに NTFS アクセス権を追加することが重要です。また、共有のアクセス許可を設定して、ASP.NET プロセス アカウントまたは偽装された ID (アプリケーションが偽装に対応するように構成されている場合) に最低でも読み取りアクセスを許可する必要もあります。

Windows 以外のネットワーク リソースへのアクセス

Windows 以外のプラットフォームに置かれているデータベースなどの、Windows 以外のリソースにアプリケーションがアクセスする必要がある場合は、以下の点について考慮する必要があります。

  • リソースに関連付けられているゲートキーパーおよび信頼の境界はどれか。
  • どの資格情報が、認証に必要であるか。
  • リソースが最初の呼び出し元の ID を認識する必要があるか。または、呼び出したアプリケーションを (プロセスまたはサービスの固定 ID を使用して) 信頼するか。
  • 接続の確立に関するパフォーマンス上の代償はあるか。パフォーマンス上の代償が甚大である場合は、Enterprise Services のオブジェクト プーリングなどの接続プールを実装する必要があります。

Windows 認証を使用できない状況で、リソースが最初の呼び出し元を認証できるようにする必要がある場合は、以下の方法を選択できます。

  • メソッド呼び出しパラメータを使用して資格情報を渡します。

  • 接続文字列で資格情報を渡します。SSL または IPSec を使用して、ネットワークを通じて渡されるクリア テキストの資格情報をセキュリティで保護します。

    DPAPI などを使用して、資格情報をアプリケーションに安全に格納します。データベース接続文字列を安全に格納する方法の詳細については、「第 12 章 データ アクセス セキュリティ」の「データベース接続文字列をセキュリティで保護して保存する」を参照してください。

  • LDAP ディレクトリなどの、両方のプラットフォームによるアクセスが可能な一元化されたデータ ストアを認証に使用します。

セキュリティで保護された通信

ブラウザと Web サーバーとの間の通信リンクをセキュリティで保護するには、SSL を使用します。SSL によって、メッセージの機密性と整合性が確保されます。Web サーバーから、アプリケーション サーバーまたはデータベース サーバーへのチャネルをセキュリティで保護するには、SSL と IPSec の両方またはいずれかを使用します。

詳細情報

セキュリティで保護された通信の詳細については、「第 4 章 セキュリティで保護された通信」参照してください。

機密情報の格納

Web アプリケーションは、機密事項を格納しなければならないことが多くあります。機密事項は、以下のような無責任な管理者や悪意のある Web ユーザーから保護する必要があります。

  • 無責任な管理者 無関係な管理者とその他の不道徳なユーザーには、機密性の高い情報が表示されないようにする必要があります。たとえば、ネットワークの向こう側に配置された SQL Server コンピュータにある SQL Server のログイン アカウントのパスワードを、Web サーバーの管理者が読める状態になっていてはなりません。
  • 悪意のある Web ユーザー 悪意のあるユーザーが構成ファイルへのアクセスを確保することを考慮し、機密性の高いファイルにユーザーがアクセスできないようにする FileAuthorizationModule などのコンポーネントがあっても、ファイル内の機密事項はプレーン テキストにしておくことはお勧めできません。

機密事項の一般的な例を以下に示します。

SQL のアプリケーション ロールの資格情報 SQL のアプリケーション ロールは、ロール名と関連付けられたパスワードを必要とするストアド プロシージャを使用してアクティブ化する必要があります。詳細については、「第 12 章 データ アクセス セキュリティ」の「認定」を参照してください。

Web.config の固定 ID 以下に例を示します。

<identity impersonate="true" userName="bob" password="inClearText"/>

.NET Framework Version 1.1 の ASP.NET には、ユーザー名とパスワードを暗号化し、レジストリ キーに安全に格納する機能があります。

Machine.config のプロセス ID 以下に例を示します。

<process userName="cUsTuMUzerName" password="kUsTumPazzWerD" >

既定では、"Machine" というユーザー名と "AutoGenerate" というパスワードを使用した場合は、ASP.NET によって機密事項が管理されます。

.NET Framework Version 1.1 の ASP.NET には、ユーザー名とパスワードを暗号化し、レジストリ キーに安全に格納する機能があります。

データを安全に格納するために使用されるキー ソフトウェアにキーを安全に格納することはできません。ただし、特定のタスクを行うことで、このリスクを軽減することができます。たとえば、非対称暗号化を使用してセッション キーを暗号化する、カスタムの構成セクション ハンドラを作成します。セッション キーは構成ファイルに格納します。

SQL Server のセッション状態 SQL Server を使用して、ASP.NET Web アプリケーションのセッション状態を管理するには、Web.config の以下の設定を使用します。

<sessionState … stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;
user id=UserName;password=MyPassword" />

.NET Framework 1.1 の ASP.NET では、この情報を暗号化することができます。

データベースと照らし合わせるフォーム認証に使用されるパスワード

アプリケーションが、データベースと照らし合わせて認証資格情報を検証する場合、パスワードをデータベースに格納しないでください。salt 値を使用して、パスワードのハッシュを作成し、ハッシュを比較します。

詳細については、「第 12 章 データ アクセス セキュリティ」の「データベースとの照合によるユーザー認証」を参照してください。

ASP.NET で機密事項を格納するためのオプション

.NET Web アプリケーションの開発者には、機密事項を格納するための多数の方法が用意されています。これには、次のものがあります。

  • .NET 暗号化クラス .NET Framework には、暗号化および解読に使用できるクラスがあります。この方法では、暗号化キーを安全に格納する必要があります。
  • データ保護 API (DPAPI) DPAPI は、ユーザーのパスワードから派生したキーを使用して、データの暗号化および解読を行う Win32 API のペアです。DPAPI を使用するときは、管理者はキー管理を行う必要がありません。オペレーティング システムによって、ユーザーのパスワードであるキーが管理されます。
  • COM+ のコンストラクタ文字列 アプリケーションが、サービス対象のコンポーネントを使用する場合は、機密事項をオブジェクトのコンストラクション文字列に格納することができます。この文字列は、COM+ カタログにクリア テキスト形式で格納されます。
  • CAPICOM これは、COM ベースのアクセスを Crypto API に提供する Microsoft COM オブジェクトです。
  • Crypto API これは、暗号化および解読を実行する下位の Win32 API です。

詳細情報

詳細については、MSDN ライブラリの Platform SDK にある「Cryptography, CryptoAPI and CAPICOM」(英語情報) を参照してください。

機密事項を別の論理ボリュームのファイルに保存することを検討する

Web アプリケーションのディレクトリを C ドライブではなく、E ドライブなど、オペレーティング システムとは別の論理ボリュームに配置することを検討してください。つまり、Machine.config ファイル (C:\WINNT\Microsoft.NET に置かれます) と、場合によってはユニバーサル データ リンク (UDL) ファイルなどの機密事項が格納されるその他のファイルを、Web アプリケーションのディレクトリとは別の論理ボリュームに置きます。

この方法を使用する根本的な理由は、ファイルの正規化のバグやディレクトリ トラバーサルのバグに対処することです。これらのバグには、以下の問題があります。

  • ファイルの正規化のバグにより、Web アプリケーションのフォルダにあるファイルにアクセスできる状態になることがあります。

    メモ ファイルの正規化のルーチンは、正規の形式のファイル パスを返します。これは、ほとんどの場合、すべての相対参照および現在のディレクトリへの参照が完全に解決されている絶対パス名です。

  • ディレクトリ トラバーサルのバグにより、同じ論理ボリュームのその他のファイルにアクセスできる状態になることがあります。

以上のようなバグで、別の論理ボリュームのファイルへのアクセスが可能になるようなものは現時点では発表されていません。

セッション状態および ViewState のセキュリティ保護

Web アプリケーションは、ViewState およびセッション状態などのさまざまな種類の状態を管理する必要があります。ここでは、ASP.NET Web アプリケーションのセキュリティで保護された状態管理について説明します。

ViewState のセキュリティ保護

ASP.NET Web アプリケーションが ViewState を使用する場合は、以下の作業を行います。

  • 以下に示すように enableViewStateMac を true に設定して、ViewState の完全性を確保します (転送中に変更されることをなくするためです)。こうすると、ページがクライアントにポストされたときに、ASP.NET は、メッセージ認証コード (MAC) をページの ViewState で生成します。
<% @ Page enableViewStateMac=true >
  • Machine.config の <machineKey> 要素で validation 属性を構成して、データの検証に使用する暗号化の種類を指定します。次のことについて考慮してください。
    • SHA 1 (Secure Hash Algorithm 1) は、MD 5 (Message Digest 5) よりもサイズの大きいハッシュを生成するため、より安全性が高いと見なされています。ただし、SHA1 または MD5 で保護された ViewState は、転送中またはクライアント側で解読されたり、場合によってはプレーン テキストで表示されたりすることがあります。
    • 3DES (3 Data Encryption Standard) を使用すると、ViewState の変更を検出したり、転送中に ViewState を暗号化したりすることができます。この状態になっていると、ViewState が解読されても、プレーン テキストで表示されることはありません。

認証データや認定データ、またはその他の機密度の高いデータが含まれている Cookie は、SSL を使用して転送時のセキュリティを保護する必要があります。フォーム認証の場合、FormsAuthentication.Encrypt メソッドを使用して、クライアントとサーバーとの間で Cookie に格納されて渡される認証チケットを暗号化することができます。

SQL セッション状態のセキュリティ保護

既定のイン プロセスの ASP.NET セッション状態のハンドラには、一定の制限があります。たとえば、このハンドラは Web ファームのコンピュータ間で動作することはできません。この制限をなくすため、ASP.NET ではセッション状態を SQL Server データベースに格納することができます。

SQL のセッション状態は、Machine.config または Web.config で構成することができます。Machine.config の既定の設定を以下に示します。

<sessionState mode="InProc" 
stateConnectionString="tcpip=127.0.0.1:42424" 
stateNetworkTimeout="10"
sqlConnectionString="data source=127.0.0.1;user id=sa;password="
cookieless="false" timeout="20"/>

既定では、SQL のセッション状態に使用されるデータベースを構築するために利用される SQL スクリプト InstallSqlState.sql は、以下の場所にインストールされます。

C:\WINNT\Microsoft.NET\Framework\v1.0.3705

SQL のセッション状態を使用するときは、以下の 2 つの問題を考慮してください。

  • データベース接続文字列をセキュリティで保護する必要があります。
  • セッション状態はネットワークを通過するため、セキュリティで保護する必要があります。

データベース接続文字列のセキュリティ保護

SQL 認証を使用してサーバーに接続している場合は、以下に示すように、ユーザー ID とパスワードの情報はプレーン テキストで Web.config ファイルに保存されます。

<sessionState
        cookieless="false"
        timeout="20"
        mode="InProc"
        stateConnectionString="tcpip=127.0.0.1:42424"
        sqlConnectionString=
data source=127.0.0.1;user id=UserName;password=ClearTxtPassword />

既定では、HttpForbiddenHandler は構成ファイルがダウンロードされないように保護します。ただし、構成ファイルが格納されているフォルダに直接アクセスすることが可能なユーザーは、ユーザー名およびパスワードを見ることができます。Windows 認証を SQL Server に使用することをお勧めします。

■ Windows 認証を使用するため、ASP.NET プロセス ID (通常は ASPNET) を使用することができます。

  1. 同じ名前とパスワードを使用した重複するアカウントをデータベース サーバーに作成します。

  2. このアカウントの SQL ログインを作成します。

  3. データベース ユーザーを ASPState データベースで作成し、SQL ログインを新しいユーザーにマップします。

    ASPState データベースは、InstallSQLState.sql スクリプトによって作成されます。

  4. ユーザー定義のデータベース ロールを作成し、データベース ユーザーをロールに追加します。

  5. データベース ロールのアクセス許可をデータベースで構成します。

これで、以下に示すように接続文字列を変更して、信頼関係接続を使用することができます。

sqlConnectionString="server=127.0.0.1;
database=StateDatabase;
Integrated Security=SSPI;"

ネットワーク全体のセッション状態のセキュリティ保護

セッション状態がネットワークを通過して SQL Server データベースに達する間を保護しなければならないことがあります。これは、Web サーバーとデータ サーバーをホストしているネットワークがどの程度セキュリティで保護されているのかによって異なります。データベースが、信頼された環境で物理的にセキュリティで保護されていれば、このようなセキュリティ対策を特に講じなくてもよい場合があります。

IPSec を使用して、Web サーバーと SQL Server との間の IP トラフィックをすべて保護することができます。または、SSL を使用して、SQL Server へのリンクをセキュリティで保護することも可能です。この方法では、コンピュータ間を通過するすべてのトラフィックを暗号化するのではなく、セッション状態のために使用される接続だけを暗号化することも可能です。

詳細情報

  • SQL のセッション状態を設定する方法の詳細については、Microsoft サポート技術情報の Knowledge Base の文書 「[HOWTO] SQL Server で ASP.NET セッション状態管理を構成する方法」を参照してください。
  • SSL を SQL Server に使用する方法の詳細については、このガイドの「パート IV : 参照」の「SQL Server 2000 との通信を SSL で保護する方法」を参照してください。
  • IPSec の使用方法の詳細については、このガイドの「パート IV : 参照」の「2 つのサーバー間の通信を IPSec で保護する方法」を参照してください。

Web ファームについての考慮事項

Web ファームを使用する場合、同じクライアントから連続して送られる要求を、同じ Web サーバーが処理するという保証はありません。これは、状態管理と、Machine.config の <machineKey> 要素によって保持されている属性に依存する暗号化に深く関係しています。

セッション状態

従来の ASP 機能に置き換わる既定の ASP.NET のイン プロセス セッション状態の処理は、サーバーへの依存性が必要となるため、Web ファームには使用できません。上述したように、Web ファーム開発では、セッション状態は ASP.NET 状態サービスまたは SQL Server データベースにアウトプロセスで格納する必要があります。

メモ 複数のサーバーで実行されるように構成された Web アプリケーションを実行する Web ファームまたは複数のプロセッサで実行されるように構成された Web アプリケーションを実行する Web ガーデンを使用する場合は、グローバル カウンタや一意の値を保持するためにアプリケーション状態を使用することはできません。この理由は、アプリケーション状態は、プロセス間またはコンピュータ間で共有されないためです。

DPAPI

DPAPI は、コンピュータ ストアまたはユーザー ストアと連動して動作することができます。DPAPI をユーザー ストアと使用する場合、ユーザー プロファイルをロードする必要があります。DPAPI をコンピュータ ストアで使用した場合は、暗号化した文字列がそのコンピュータ固有のものになります。したがって、それぞれのコンピュータでデータを暗号化する必要があります。あるコンピュータで暗号化したデータを、ファームまたはクラスタ内の別のコンピュータにコピーして使用することはできません。

DPAPI をユーザー ストアで使用した場合は、ローミング ユーザー プロファイルに基づいてすべてのコンピュータでデータを解読できます。

詳細情報

DPAPI の詳細については、「第 12 章 データ アクセス セキュリティ」を参照してください。

Web ファームでのフォーム認証の使用方法

フォーム認証を使用している場合は、Web ファームのすべてのサーバーが共通のコンピュータ キーを共有していることが重要です。コンピュータ キーは、暗号化、解読、および認証チケットの検証に使用されます。

コンピュータ キーは、Machine.config の <machineKey> 要素によって保持されています。既定の設定を以下に示します。

<machineKey validationKey="AutoGenerate" 
decryptionKey="AutoGenerate" 
validation="SHA1"/> 

この設定により、各コンピュータで別の検証キーおよび復号キーが生成されます。<machineKey> 要素を変更し、Web ファームのすべてのサーバー間で共通のキー値を配置する必要があります。

<machineKey> 要素

Machine.config にある <machineKey> 要素は、フォーム認証の Cookie のデータや ViewState の暗号化および解読に使用されるキーを構成するために使用します。

FormsAuthentication.Encrypt メソッドまたは FormsAuthentication.Decrypt メソッドが呼び出されたとき、および ViewState が作成または取得されたときは、<machineKey> 要素の値が参照されます。

<machineKey validationKey="autogenerate|value"
decryptionKey="autogenerate|value"
validation="SHA1|MD5|3DES" />

validationKey 属性

validationKey 属性の値は、ViewState およびフォーム認証チケットの MAC コードを作成および検証するために使用されます。この validation 属性は、MAC の生成を実行するときに使用するアルゴリズムを表しています。以下の点に注意してください。

  • フォーム認証では、このキーは <forms> protection 属性と共に使用します。protection 属性が Validation に設定されているとき、FormsAuthentication.Encrypt メソッドが呼び出されると、Cookie に追加される MAC を計算するためにチケットの値と validationKey が使用されます。FormsAuthentication.Decrypt メソッドが呼び出されると、MAC が計算され、チケットに追加された MAC と比較されます。
  • ViewState では、コントロールの ViewState と validationKey の値が使用され、ViewState に追加される MAC が計算されます。ViewState がクライアントにポストされると、MAC は再度計算され、ViewState に追加された MAC と比較されます。

decryptionKey 属性

decryptionKey 属性の値は、フォーム認証チケットと ViewState の暗号化および解読に使用されます。これには、DES または 3DES (Triple DES) のアルゴリズムが使用されます。最適なアルゴリズムは、Windows 2000 高度暗号化パックがサーバーにインストールされているかどうかによって異なります。これがインストールされていると 3DES が使用されますが、そうでない場合は DES が使用されます。以下の点に注意してください。

  • フォーム認証では、このキーは <forms> protection 属性と共に使用します。protection 属性が Encryption に設定されているとき、FormsAuthentication.Encrypt メソッドまたは FormsAuthentication.Decrypt メソッドが呼び出されると、指定された decryptionKey の値を使用してチケットの値が暗号化または解読されます。
  • ViewState では、コントロールの ViewState の値は、decryptionKey の値を使用してクライアントに送信されるときに暗号化され、クライアントがサーバーにデータをポストしたときに解読されます。

validation 属性

この属性は、検証、暗号化、または解読を行うときに使用されるアルゴリズムを表しています。この属性が取り得る値は、SHA1、MD5、または 3DES です。以下で、これらの値を説明します。

  • SHA1設定が SHA1 である場合、実際には アルゴリズム HMACSHA1 が使用されます。これは、160 ビット (20 バイト) のハッシュまたは入力のダイジェストを生成します。HMACSHA1 は、キー付きハッシュ アルゴリズムです。このアルゴリズムの入力として使用されるキーは、validationKey 属性によって指定されます。

    その他のアルゴリズムと比較してダイジェストのサイズが大きいため、SHA1 は一般的なアルゴリズムです。

  • MD5MD5 アルゴリズムを使用して、20 バイトのハッシュを生成します。

  • 3DES3DES (Triple DES) アルゴリズムを使用してデータを暗号化します。

    メモ validation 属性が 3DES に設定されていても、3DES は実際にはフォーム認証で使用されません。その代わりに SHA1 が使用されます。

詳細情報

  • Machine.config に配置するのに最適なキーを作成する方法の詳細については、Microsoft サポート技術情報の Knowledge Base の文書 312906「[HOWTO] フォーム認証で使用するキーを Visual C# .NET で作成する方法」を参照してください。
  • Windows 2000 高度暗号化パックの詳細については、「高度暗号化パック」を参照してください。

まとめ

この章では、ASP.NET Web アプリケーションのセキュリティを保護するためのさまざまな技術や方法を説明しました。この章に記載されている説明と推奨事項の多くは、ASP.NET Web サービス、および ASP.NET によってホストされる .NET リモート処理オブジェクトの開発にも当てはまります。この章で説明した内容を以下にまとめます。

  • アプリケーションがフォーム認証を使用しており、ユーザーを認証するときのパフォーマンスが問題である場合は、ロールのリストを取得し、認証チケットに格納します。
  • フォーム認証を使用する場合は、必ずプリンシパルを作成し、各要求のコンテキストに格納します。
  • 認証 Cookie に格納するロールが多すぎる場合は、グローバル アプリケーション キャッシュを使用してロールを格納します。
  • カスタムの最低限の特権のアカウントを作成して ASP.NET を実行しないでください。その代わりに、ASP.NET アカウントのパスワードを変更し、アプリケーションがアクセスする必要があるリモートの Windows サーバーに重複するアカウントを作成します。
  • カスタムのアカウントを作成して ASP.NET を実行する場合は、最低限の特権の原則を守ってください。次に、例を示します。
    • 管理が主な問題である場合は、最低限の特権のドメイン アカウントを使用します。
    • ローカルのアカウントを使用する場合は、Web アプリケーションがアクセスする必要があるリモート コンピュータに重複するアカウントを作成する必要があります。アプリケーションが、信頼関係のないドメインのリソースにアクセスする必要があるとき、またはファイアウォールが原因で Windows 認証が使用できないときは、ローカルのアカウントを使用してください。
    • ローカルの SYSTEM アカウントを使用して ASP.NET を実行しないでください。
    • ASPNET アカウントには、"オペレーティング システムの一部として動作する" 特権を付与しないでください。

SSL は、以下の場合に使用します。

  • ブラウザと Web サーバーとの間で、セキュリティ上機密性の高い情報が渡される。
  • 資格情報を保護するため、基本認証を使用する。
  • 識別ではなく、認証にフォーム認証を使用する。

機密事項をプレーン テキストで保存しないでください。

patterns and practices home