共用方式為


部分信任最佳做法

本主題說明在部分信任環境中執行 Windows Communication Foundation (WCF) 時的最佳做法。

序列化

在部分信任的應用程式中使用 DataContractSerializer 時,請套用下列做法。

  • 所有可序列化的型別必須明確地加上 [DataContract] 屬性標記。部分信任環境不支援下列技巧:
  • 使用 SerializableAttribute 來標示要序列化的類別。
  • 實作 ISerializable 介面以允許類別控制自己的序列化處理序。

使用 DataContractSerializer

  • 所有加上 [DataContract] 屬性標記的型別必須是公用型別。非公用型別無法在部分信任環境中進行序列化。
  • 可序列化之 [DataContract] 型別中的所有 [DataContract] 成員必須是公用的。具有非公用 [DataMember] 的型別無法在部分信任環境中進行序列化。
  • 負責處理序列化事件 (例如,OnSerializing, OnSerializedOnDeserializing,和 OnDeserialized) 的方法必須宣告為公用。但是,同時支援 OnDeserialization 的明確與隱含實作。
  • 在標示為 AllowPartiallyTrustedCallersAttribute 的組件中實作的 [DataContract] 型別不可以在型別建構函式中執行安全性相關動作,因為 DataContractSerializer 不會在還原序列化期間呼叫新產生物件的建構函式。具體來說,[DataContract] 型別必須避免使用下列常見的安全性技巧:
  • 藉由將型別建構函式標示為內部或私用來嘗試限制部分信任存取。
  • 藉由新增 [LinkDemand] 至型別建構函式來限制型別的存取。
  • 假定因為物件已經成功產生,任何由建構函式所強制執行的驗證檢查也已通過。

使用 IXmlSerializable

下列最佳做法適用於可實作 IXmlSerializable 且可透過 DataContractSerializer 進行序列化的型別:

  • GetSchema 靜態方法實作必須是 public
  • 實作 IXmlSerializable 介面的執行個體方法必須是 public

使用來自充分信任平台程式碼 (允許部分信任呼叫端的呼叫) 的 WCF

WCF 部分信任安全性模型會假定 WCF 公用方法或屬性的任何呼叫者都是在裝載應用程式的程式碼存取安全性 (CAS) 內容中執行。WCF 同時假定每一個 AppDomain 只會有一個對應的應用程式安全性內容,而且此內容會在 AppDomain 的建立期間由信任的主機建立 (例如,透過對 CreateDomain 的呼叫或是由 ASP.NET Application Manager 建立)。

這個安全性模型適用於由使用者撰寫且無法判斷提示其他 CAS 權限的應用程式,例如在中度信任 ASP.NET 應用程式中執行的使用者程式碼。然而,充分信任的平台程式碼 (例如,安裝在全域組件快取中且接受來自部分信任程式碼的呼叫的協力廠商組件) 在代表部分信任應用程式呼叫 WCF 時必須特別小心,避免帶入應用程式層級的安全性弱點。

完全信任程式碼應該避免在呼叫代表部分信任程式碼的 WCF API 之前,更改目前執行緒的 CAS 權限集 (透過呼叫 AssertPermitOnlyDeny)。判斷提示、拒絕或以其他方式建立無關應用程式層級安全性內容的執行緒特定權限內容可能會導致未預期的行為。根據所使用的應用程式,這項行為可能會導致應用程式層級的安全性弱點。

使用執行緒特定權限內容來呼叫 WCF 的程式碼必須準備好處理下列可能發生的情況:

  • 作業期間可能無法維護執行緒特定的安全性內容,進而導致可能發生的安全性例外狀況。
  • 內部 WCF 程式碼以及任何使用者提供的回呼可能會在原始啟始呼叫之安全性內容以外的其他安全性內容中執行。這些內容包括:
    • 應用程式權限內容。
    • 先前由其他使用者執行緒建立的執行緒特定權限內容,用於在目前執行中 AppDomain 的存留期間呼叫 WCF。

WCF 會保證部分信任的程式碼無法取得完全信任權限,除非此類權限在呼叫 WCF 公用 API 之前已由完全信任的元件加以判斷提示。但是,它不保證將完全信任的判斷提示影響隔離在特定執行緒、作業或使用者動作之外。

最佳做法是,避免呼叫 AssertPermitOnlyDeny 來建立執行緒特定權限內容。反之,應該針對應用程式本身授與或拒絕權限,這樣就不會需要 AssertDenyPermitOnly

請參閱

參考

DataContractSerializer
IXmlSerializable