保护敏感实体数据

我正在寻找一些关于具有一些特性的客户端/服务器解决方案的架构建议。 客户端相当厚,使服务器主要关注持久性,并发性和基础架构问题。 服务器包含许多包含敏感信息和公共信息的实体。例如,假设实体是人,假设社会安全号码和名称是敏感的,并且年龄是公众可见的。 启动客户端时,会向用户显示许多实体,而不会泄露任何敏感信息。用户可以随时选择登录并对服务器进行身份验证,如果身份验证成功,则授予用户访问敏感信息的权限。 客户端正在托管域模型,我正在考虑将其实现为某种“延迟加载”,使第一个请求实例化实体,然后使用敏感数据刷新它们。实体获取者在未被披露时会对敏感信息抛出异常,例如:
class PersonImpl : PersonEntity
{
    private bool undisclosed;

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

            return base.SocialSecurityNumber;
        }
    }
}
另一种更友好的方法可能是使用一个值对象来指示该值未公开。
get {
    if (undisclosed)
        return undisclosedValue;

    return base.SocialSecurityNumber;
}
一些问题: 如果用户登录然后退出,敏感数据已加载但必须再次公开。 有人可能会争辩说,这种类型的功能属于域而不是某些基础结构实现(即存储库实现)。 与处理大量属性一样,这种类型的功能可能会使代码混乱 任何见解或讨论表示赞赏!     
已邀请:
我认为这实际上是使用View Models的一个很好的例子。您的关注似乎与实体的消耗直接相关,因为它们包含的数据。您可以将它们限制为仅在域内生存,而不是将实体限制在域内 - 即根本不会将任何实体传入或传出域,而大多数/所有活动都使用命令/查询方法完成,而不是将您的实体一直传递到UI。在存储库上。然后,存储库将返回视图模型而不是实体。 那么这是如何/为什么适用?你实际上可以有两种不同的视图模型。一个用于认证用户,一个用于未经认证的用户。您在经过身份验证的视图模型中公开了敏感数据的实际值,而不是在未经过身份验证的模型中公开。您可以从公共接口派生它们,然后针对接口而不是对象类型进行编码。对于未经身份验证的用户的具体实现,您可以只填充非敏感数据,让敏感的getter执行您希望他们执行的操作。 我的观点有两点: 我不是实体中延迟加载的粉丝。延迟加载是数据访问的责任,而不是模型的一部分。对我来说,它是我在我的领域中强烈避免的事情的一流成员,以及分页和排序。至于如何将这些项目联系在一起,我宁愿通过ID指针将对象松散地耦合到其他实体。如果我想要/需要其中一个实体包含的数据,那么我可以加载它。它有点像在某种程度上的延迟加载,但我强制说它通常不会在域模型本身中发生。 我不喜欢在getter上抛出异常。另一方面,塞特斯很好。我是这样看的。实体应始终处于有效状态。 Getters不会影响实体的状态 - setters会。投掷一个setter是强制模型的完整性。使用两种视图模型方法将允许我将逻辑移动到演示者。所以,我基本上可以做一些事情,比如“如果用户是非授权类型,请执行此操作;否则执行其他操作”。由于您所指的最终将是数据如何呈现给用户的情况,并且对模型不重要,我认为它非常适合。一般来说,我对我的属性使用可空类型可以为null并且不对getter强制执行任何操作,因为它通常不是其职责的一部分。相反,我使用角色来确定要使用的视图模型。 显而易见的缺点是使用视图模型需要更多编码,但它具有将表示和视图与域分离的明显优势。它还有助于单元/集成测试,您可以在其中验证某个视图模型无法返回某种类型的数据。 但是,您可以使用类似于AutoMapper的内容(取决于您的平台)来帮助您从实体填充视图模型。     
我错误地发布了问题而没有创建OpenId所以看起来我必须在这里发表评论(?)。 首先,感谢您抽出时间回答 - 这肯定与数据的呈现方式有关,而不是模型的工作原理。但是,我觉得有必要澄清一些事情。 域模型/实体永远不会直接从UI引用。我正在使用DM-V-VM模式的变体进行UI /业务模型分离。对于延迟加载和存储库实现,我在基础结构层中有实体实现,其中处理序列化,脏跟踪和延迟加载等事情。 所以域层有如下实体:
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并不好,但我关注的是匿名视图模型将如何检索数据。截至目前,要检索视图模型将保存对域存储库的引用的实体列表,我应该有两个存储库,一个用于经过身份验证(因此已公开)的实体,另一个用于未经身份验证的用户 - 甚至可能是两个不同的实体?     

要回复问题请先登录注册