NHibernate和SqlServer中的数据审计

15

我正在一个项目中使用NHibernate,并且需要进行数据审计。 我在这篇文章中发现了关于IInterceptor接口的讨论。

你更喜欢哪种审计数据的方式? 你使用数据库触发器吗? 还是类似文章中讨论的方式?

6个回答

14

针对 NHibernate 2.0 版本,您还应查看事件监听器。 这些是 IInterceptor 接口的进化,我们已成功地将其用于审计。


5
< p >【编辑】

请在NH2.0版本发布后查看下面建议的事件监听器。我的答案已经过时了。


IInterceptor是nhibernate中推荐的一种非侵入式修改任何数据的方式。它还可以用于加密/解密数据,而无需您的应用程序代码知道。

数据库触发器将日志记录的责任(一个应用程序关注点)移动到DBMS层,这实际上将您的日志记录解决方案与数据库平台绑定在一起。通过封装持久层中的审计机制,您保留了平台独立性和代码可移植性。

我在几个大型系统的生产代码中使用拦截器来提供审计功能。


我认为IInterceptor解决方案有点问题的是,例如“LastUpdated”日期设置为客户端工作站设置的日期,而不是使用的DB服务器的日期。 - Frederik Gheysels

3

3
我更喜欢你提到的CodeProject方法。
数据库触发器的一个问题是,它只能与ActiveDirectory集成的Integrated Security一起使用来访问SQL Server。原因是您的连接应该继承触发连接的用户的身份;如果您的应用程序使用命名的“sa”帐户或其他用户帐户,“user”字段将只反映“sa”。
这可以通过为应用程序的每个用户创建一个命名的SQL Server帐户来覆盖,但对于非内部网和面向公众的Web应用程序,这将是不切实际的。

1
有办法绕过/替代为每个用户提供SQL帐户或使用集成身份验证。您可以在正在审核的表上拥有“LastUpdatedByUser”列,并在更新记录时从应用程序发送它。触发器可以使用该列的值来填充审核记录。 - David Archer

3

我很喜欢提到的拦截器方法,并在我目前正在处理的项目中使用它。

然而,这种方法的一个明显劣势值得强调的是,这种方法只会审计通过你的应用程序进行的数据更改。任何直接的数据修改,例如不定期需要执行的ad-hoc SQL脚本(这总是会发生的!),除非你同时记得执行审计表插入操作,否则将不会被审计。


2
作为一种完全不同的方法,您可以在存储库中使用装饰器模式。假设我有:
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),您可以构建所有内容,而不需要您的其余代码知道您正在进行审计。

当然,如何审计级联集合的元素是另一个完全不同的问题...


我认为这不是正确的解决方案,除非你显式地调用save方法并且已经禁用了NH的Flush行为。也就是说,实体的更改甚至可以在不调用save方法的情况下被持久化! - Rashack
你正在使用 session.FlushMode = FlushMode.CommitOnly 吗? - kͩeͣmͮpͥ ͩ
如果您使用这种方法,最终会导致数据库中发生没有更改的更新。 - Alan Christensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接