部分信頼のベスト プラクティス
この記事では、部分信頼環境で Windows Communication Foundation (WCF) を実行する場合のベスト プラクティスについて説明します。
シリアル化
部分信頼アプリケーションで DataContractSerializer を使用する場合は、これらの方法を適用します。
すべてのシリアル化可能な型は、[DataContract]
属性で明示的にマークする必要があります。 次の手法は、部分信頼環境ではサポートされていません。
- シリアル化するクラスを SerializableAttribute でマークする。
- クラスでシリアル化プロセスを制御できるように ISerializable インターフェイスを実装する。
DataContractSerializer の使用
[DataContract]
属性でマークされたすべての型は、パブリックである必要があります。 部分信頼環境では、非パブリック型はシリアル化できません。シリアル化できる
[DataContract]
型のすべての[DataContract]
メンバーは、パブリックである必要があります。 部分信頼環境では、非パブリック[DataMember]
型はシリアル化できません。OnSerializing
、OnSerialized
、OnDeserializing
、OnDeserialized
などのシリアル化イベントを処理するメソッドは、パブリックとして宣言する必要があります。 ただし、明示的および暗黙的な OnDeserialization(Object) の実装は、いずれもサポートされています。[DataContract]
は、逆シリアル化の間に新しくインスタンス化されたオブジェクトのコンストラクターを呼び出さないため、AllowPartiallyTrustedCallersAttribute でマークされて、アセンブリで実装された DataContractSerializer 型は、型コンストラクターでセキュリティ関連の操作を実行することはできません。 特に、[DataContract]
型では、次の一般的なセキュリティ手法の使用を避ける必要があります。型のコンストラクターを内部またはプライベートにすることにより、部分信頼アクセスを制限する。
型のコンストラクターに
[LinkDemand]
を追加することにより、型へのアクセスを制限する。オブジェクトが正常にインスタンス化されたため、コンストラクターが強制するチェックがすべて正常に終了したと仮定する。
IXmlSerializable の使用
IXmlSerializable を実装し、DataContractSerializer を使用してシリアル化される型に適用されるベスト プラクティスを次に示します。
静的 GetSchema メソッドの実装は、
public
とする必要があります。IXmlSerializable インターフェイスを実装するインスタンス メソッドは、
public
とする必要があります。
部分信頼の呼び出し元から呼び出せる完全信頼のプラットフォーム コードで WCF を使用する
WCF の部分信頼セキュリティ モデルでは、WCF パブリック メソッドまたはプロパティのすべての呼び出し元は、ホスト アプリケーションのコード アクセス セキュリティ (CAS: Code Access Security) コンテキストで実行されていることを前提としています。 また、WCF は、各 AppDomain に対して存在するアプリケーション セキュリティ コンテキストが 1 つのみであり、このコンテキストが CreateDomain への呼び出しや ASP.NET アプリケーション マネージャーなどの信頼されているホストにより、AppDomain の作成時に確立されることを前提としています。
Note
コード アクセス セキュリティ (CAS) は、.NET Framework と .NET のすべてのバージョンで非推奨になりました。 最近のバージョンの .NET では、CAS 関連の API が使われている場合、CAS の注釈は使われず、エラーが発生します。 開発者は、代わりの手段を見つけてセキュリティ タスクを実現する必要があります。
このセキュリティ モデルは、信頼性が "中" の ASP.NET アプリケーションで実行されているユーザー コードなど、追加の CAS アクセス許可をアサートできないユーザー記述のアプリケーションに適用されます。 ただし、完全信頼のプラットフォーム コード (たとえば、グローバル アセンブリ キャッシュにインストールされている、または部分信頼コードからの呼び出しを受け入れるサードパーティ アセンブリなど) では、アプリケーション レベルのセキュリティの脆弱性が発生しないよう、部分信頼アプリケーションに代わって WCF を呼び出す場合に、明示的な注意を行う必要があります。
完全信頼コードでは、部分信頼コードに代わって WCF API を呼び出す前に、Assert、PermitOnly、または Deny を呼び出して、現在のスレッドの CAS アクセス許可セットを変更しないようにする必要があります。 アプリケーション レベルのセキュリティ コンテキストに依存しないスレッド固有のアクセス許可コンテキストのアサート、拒否、または作成により、予期しない動作が発生することがあります。 アプリケーションによっては、この動作がアプリケーション レベルのセキュリティの脆弱性となることがあります。
次のような状況の発生に対処するには、スレッド固有のアクセス許可コンテキストを使用して WCF を呼び出すコードを準備する必要があります。
スレッド固有のセキュリティ コンテキストを処理の期間全体にわたっては保持できない場合があり、このときセキュリティの例外が発生する可能性があります。
内部 WCF コードとユーザーが指定したコールバックが、呼び出しが開始された元のものとは異なるセキュリティ コンテキストで実行される場合があります。 次のようなコンテキストが含まれます。
アプリケーションのアクセス許可コンテキスト。
現在実行している AppDomain の有効期間中に、WCF の呼び出しに使用される他のユーザー スレッドによって以前に作成されたスレッド固有のアクセス許可コンテキスト。
WCF パブリック API の呼び出しの前に、完全信頼コンポーネントによってこのようなアクセス許可がアサートされない限り、WCF では、部分信頼コードで完全信頼アクセス許可を取得できないことが保証されます。 ただし、完全信頼をアサートした効果が特定のスレッド、操作、またはユーザー操作として隔離されることは保証されません。
Assert、PermitOnly、または Deny を呼び出すことにより、スレッド固有のアクセス許可コンテキストを作成しないことをお勧めします。 代わりに、Assert、Deny、または PermitOnly が不要となるように、アプリケーション自体に特権を付与するか、特権を拒否します。