1

我正在尋找一些有關特定於客戶端/服務器解決方案的體系結構建議。保護敏感實體數據

客戶端是一個相當厚的客戶端,主要是服務器保持持久性,併發性和基礎設施問題。 服務器包含許多包含敏感信息和公共信息的實體。例如,假設實體是人,假定社會安全號碼和姓名是敏感的,並且年齡是公開可見的。

啓動客戶端時,會向用戶呈現多個實體,而不會泄露任何敏感信息。在任何時候,用戶都可以選擇登錄並對服務器進行身份驗證,但鑑於身份驗證成功,用戶可以訪問敏感信息。

客戶端正在託管一個域模型,並且我正在考慮將其實現爲某種「延遲加載」,從而使第一個請求實例化實體,然後使用敏感數據刷新它們。還沒有被披露時,他們的實體干將會拋出敏感信息出現異常,f.e:

class PersonImpl : PersonEntity 
{ 
    private bool undisclosed; 

    public override string SocialSecurityNumber { 
     get { 
      if (undisclosed) 
       throw new UndisclosedDataException(); 

      return base.SocialSecurityNumber; 
     } 
    } 
} 

另一種更友好的方式可能是具有指示值是未公開的值對象。

​​

有些擔憂:

  • 如果什麼,然後出來在用戶登錄時,敏感數據被加載,但必須再次披露。
  • 有人可能會爭辯說,這種類型的功能屬於域內,而不屬於某些基礎設施實現(即存儲庫實現)。
  • 按照一貫的特性較大數量的問題時有這種類型的功能雜波的代碼

任何見解或討論表示讚賞的危險!

回答

2

我認爲這實際上是使用視圖模型的一個很好的例子。由於它們包含的數據,您的擔心似乎與實體的消費直接相關。與其將實體一直傳遞到用戶界面,您可以將它們限制爲僅在域內生存 - 即根本不會將實體傳入或傳出域,而大部分/所有活動都是通過命令/查詢方式完成的在存儲庫上。然後存儲庫會返回一個視圖模型而不是實體。

那麼如何/爲什麼這適用?你實際上可以有兩種不同的視圖模型。一個用於身份驗證,一個用於未經身份驗證的用戶。您公開驗證視圖模型中敏感數據的實際值,而不是未驗證的值。您可以讓它們從一個通用接口派生,然後針對接口而不是對象類型進行編碼。對於未經身份驗證的用戶的具體實現,您可以填充不敏感的數據,讓敏感的獲取者執行您希望他們執行的操作。

上幾個百分點的我意見

  • 我不是延遲加載的實體風扇。延遲加載是數據訪問責任,並不是模型的一部分。對我而言,它是我在域中強烈避免的事情中的頭等成員,以及分頁和排序。至於如何將這些項目聯繫在一起,我寧願通過ID指針鬆散地將對象耦合到其他實體。如果我想要/需要其中一個實體包含的數據,那麼我可以加載它。這種方式有點像延遲加載,但我強制要求它在域模型本身中不會發生這種情況。
  • 我不喜歡在getter上拋出異常。另一方面,安裝者很好。我是這樣看的。實體應始終處於有效狀態。吸氣者不會影響實體的狀態 - 設定者會。投入二傳手是爲了強化模型的完整性。使用兩種視圖模型方法可以讓我將邏輯轉移給演示者。所以,我基本上可以做一些事情,如「如果用戶是非授權類型的,那麼做,否則做別的事情」。因爲你所指的最終將是數據如何呈現給用戶,對模型不重要的情況,我認爲它很合適。一般來說,我使用可爲空的類型作爲我的屬性,它們可以爲null,並且不會對getter執行任何操作,因爲它通常不是其職責的一部分。相反,我使用角色來確定要使用的視圖模型。

顯而易見的缺點是,使用視圖模型需要更多的編碼,但它具有將表示和視圖從域中解耦的顯而易見的好處。它還將有助於單元/集成測試,您可以驗證某個視圖模型無法返回某種類型的數據。

但是,您可以使用與AutoMapper類似的東西(取決於您的平臺)以幫助從實體填充視圖模型。

0

我犯了一個錯誤發佈的問題,而不創建一個OpenId,所以它看起來我必須在這裏發表評論(?)。

首先,感謝您花時間回答 - 它肯定與數據的呈現方式有關,而不是模型的工作方式。不過,我覺得有必要澄清一些事情。 域模型/實體不會直接從UI中引用。我正在使用用於UI /業務模型分離的DM-V-VM模式的變體。對於一般的懶惰加載和存儲庫實現,我在基礎結構層實現了一些實現,比如序列化,髒跟蹤和延遲加載。

因此域層實體,如:

class Entity { 
    virtual string SocialSecurityNumber { get; } 
} 

,基礎設施層增加了一些其他功能,以便能夠隨時更新和服務器恢復的entites:

class EntityImpl : Entity { 
    bool isDirty; 
    bool isLoaded; 
    // Provide the means to set value on deserialization 
    override string SocialSecurityNumber; 
} 

所以延遲加載行爲將在基礎設施層實施,域層從未見過。

我同意扔getter不會很好,但我的擔心是關於匿名視圖模型如何檢索數據。到目前爲止,爲了檢索實體列表,視圖模型將持有對域存儲庫的引用,我應該有兩個存儲庫,一個用於已認證(因此已公開)的實體,另一個用於未認證的用戶 - 可能甚至包括兩個不同的實體?