NHibernate 和 SqlServer 中的数据审计
-
08-06-2019 - |
题
我在一个项目中使用NHibernate,我需要进行数据审计。我发现 本文 在讨论 IInterceptor 接口的 codeproject 上。
您审核数据的首选方式是什么?您使用数据库触发器吗?您使用与文章中讨论的类似的东西吗?
解决方案
对于 NHibernate 2.0,您还应该看看 事件监听器. 。这些是 IInterceptor 接口的演变,我们成功地将它们用于审计。
其他提示
[编辑]
NH2.0 发布后,请查看下面建议的事件监听器。我的答案已经过时了。
IInterceptor 是以非侵入方式修改 nhibernate 中任何数据的推荐方法。它对于数据解密/加密也很有用,而您的应用程序代码不需要知道。
数据库上的触发器将日志记录(应用程序关注点)的责任转移到 DBMS 层,从而有效地将日志记录解决方案与数据库平台联系起来。通过将审核机制封装在持久层中,您可以保留平台独立性和代码可移植性。
我在生产代码中使用拦截器来在一些大型系统中提供审核。
我更喜欢你提到的 CodeProject 方法。
数据库触发器的一个问题是它让您别无选择,只能使用集成安全性和 ActiveDirectory 来访问 SQL Server。原因是您的连接应该继承触发连接的用户的身份;如果您的应用程序使用名为“sa”的帐户或其他用户帐户,则“user”字段将仅反映“sa”。
这可以通过为应用程序的每个用户创建一个命名的 SQL Server 帐户来覆盖,但这对于非 Intranet、面向公众的 Web 应用程序来说是不切实际的。
我确实喜欢提到的拦截器方法,并在我当前正在进行的项目中使用它。
然而,一个值得强调的明显缺点是,这种方法只会审核通过您的应用程序所做的数据更改。任何直接的数据修改,例如您可能需要不时执行的临时 SQL 脚本(这种情况总是会发生!),都不会被审核,除非您记得同时执行审核表插入。
我知道这是一个老问题。但我想根据 NH 2.0 中的新事件系统来回答这个问题。事件监听器比拦截器更适合类似审计的功能。Ayende 上个月在他的博客上写了一个很好的例子。这是他的博客文章的 URL -
作为一种完全不同的方法,您可以在存储库中使用装饰器模式。
说我有
public interface IRepository<EntityType> where EntityType:IAuditably
{
public void Save(EntityType entity);
}
然后,我们就有了 NHibernateRepository:
public class NHibernateRepository<EntityType>:IRepository<EntityType>
{
/*...*/
public void Save ( EntityType entity )
{
session.SaveOrUpdate(entity);
}
}
然后我们就可以拥有一个审计存储库:
public class AuditingRepository<EntityType>:IRepository<EntityType>
{
/*...*/
public void Save ( EntityType entity )
{
entity.LastUser = security.CurrentUser;
entity.LastUpdate = DateTime.UtcNow;
innerRepository.Save(entity)
}
}
然后,使用 IoC 框架(StructureMap、Castle Windsor、NInject),您可以构建全部内容,而无需其余代码知道您正在进行审核。
当然,如何审核级联集合的元素完全是另一个问题......