审计线索:Web应用程序
问题描述:
我的工作,我们已被告知以下内容的审计跟踪项目。审计线索:Web应用程序
跟踪所有的在我们与就像休眠Envers确实影子表数据库表(200+)。接下来我们为每个涉及CUD的交易创建快照。
在过去,我实现审计解决方案,为有限集的每一个我的客户的重要数据。对于目前的工作,我的问题是:
- 是否有意义审计数据库中的每个表?
- 它会像Envers那样跟踪数据的价值多少?任何应用程序都希望为特定数据点提供增量。查询大量的数据来发现增量似乎是不现实的。
- 的Envers像解决方案需要与交易有效排除触发占用CUD行动。这是因为触发器在自己的事务中运行,因此在应用程序事务回滚的情况下,影子表中的数据可能不同步。我在这里失踪的任何东西?
- 有人建议使用NoSQL DB进行审计跟踪吗?
答
NoSQL数据库的一个选项是RavenDB,使用其“versioning bundle”。
虽然在这一点上它可能太早了,我最近听的羊群代码,他们talk with Eric Sink on about Veracity一个有趣的小插曲。据我所知,Veracity是部分分布式版本控制系统,并且是部分NoSQL数据库。它被设计成从源代码管理系统到wiki的后端。它已经开发了几年,但仍然处于预测阶段(截至2010年11月)。
答
完全实现,并且可以更加改善。我希望这可以帮助某人:
public partial class Entity:DbContext
{
public enum AuditActions {I,U,D}
public override int SaveChanges()
{
ChangeTracker.DetectChanges();
ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext;
// string UserName = WindowsIdentity.GetCurrent().Name;
IPrincipal principal = Thread.CurrentPrincipal;
IIdentity identity = principal == null ? null : principal.Identity;
string name = identity == null ? "" : identity.Name;
//Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity((userName), roles);
List<ObjectStateEntry> objectStateEntryList =
ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added
| EntityState.Modified
| EntityState.Deleted)
.ToList();
List<DBAudit> AuditList = new List<DBAudit>();
string Audittable = string.Empty;
foreach (ObjectStateEntry entry in objectStateEntryList)
{
Audittable = entry.EntitySet.ToString();
if (!entry.IsRelationship && Audittable!="Audit table name")
{
//sIsAuditTble =entry.EntitySet="DBAudit"? true:false;
switch (entry.State)
{
case EntityState.Added:
AuditList= LogDetails(entry, name, AuditActions.I);
break;
case EntityState.Deleted:
AuditList= LogDetails(entry, name, AuditActions.D);
break;
case EntityState.Modified:
AuditList= LogDetails(entry, name, AuditActions.U);
break;
}
}
}
using (var context = new ProjectTrackerEntities())
{
for (int i = 0; i < AuditList.Count; i++)
{
context.DBAudits.Add(AuditList[i]);
context.SaveChanges();
}
}
return base.SaveChanges();
}
public List<DBAudit> LogDetails(ObjectStateEntry entry, string UserName, AuditActions action)
{
List<DBAudit> dbAuditList = new List<DBAudit>();
if (action == AuditActions.I)
{
var keyValues = new Dictionary<string, object>();
var currentValues = entry.CurrentValues;
// entry.Entity key = new EntityKey();
DBAudit audit = new DBAudit();
audit.AuditId = Guid.NewGuid().ToString();
audit.RevisionStamp = DateTime.Now;
audit.TableName = entry.EntitySet.Name;
audit.UserName = UserName;
audit.OldData = "";
audit.Actions = action.ToString();
for (int i = 0; i < currentValues.FieldCount; i++)
{
audit.ChangedColumns = audit.ChangedColumns + currentValues.GetName(i);
audit.NewData = audit.NewData + currentValues.GetValue(i);
audit.ChangedColumns = audit.ChangedColumns + ", ";
audit.NewData = audit.NewData + ", ";
}
dbAuditList.Add(audit);
//LogSave(audit);
}
else if (action == AuditActions.D)
{
var keyValues = new Dictionary<string, object>();
var DeletedValues = entry.OriginalValues;
// entry.Entity key = new EntityKey();
DBAudit audit = new DBAudit();
audit.AuditId = Guid.NewGuid().ToString();
audit.RevisionStamp = DateTime.Now;
audit.TableName = entry.EntitySet.Name;
audit.UserName = UserName;
audit.NewData = "";
audit.Actions = action.ToString();
for (int i = 0; i < DeletedValues.FieldCount; i++)
{
audit.ChangedColumns = audit.ChangedColumns + DeletedValues.GetName(i);
audit.OldData = audit.OldData + DeletedValues.GetValue(i);
audit.ChangedColumns = audit.ChangedColumns + ", ";
audit.OldData = audit.OldData + ", ";
}
dbAuditList.Add(audit);
}
else
{
foreach (string propertyName in entry.GetModifiedProperties())
{
DBAudit audit = new DBAudit();
DbDataRecord original = entry.OriginalValues;
string oldValue = original.GetValue(original.GetOrdinal(propertyName)).ToString();
CurrentValueRecord current = entry.CurrentValues;
string newValue = current.GetValue(current.GetOrdinal(propertyName)).ToString();
audit.AuditId = Guid.NewGuid().ToString();
audit.RevisionStamp = DateTime.Now;
audit.TableName = entry.EntitySet.Name;
audit.UserName = UserName;
audit.ChangedColumns = propertyName;
audit.OldData = oldValue;
audit.NewData = newValue;
audit.Actions = action.ToString();
dbAuditList.Add(audit);
//LogSave(audit);
}
}
return dbAuditList;
}
}
+0
欢迎来到SO,在这里,解释为什么要使用您的解决方案,而不仅仅是如何,这是一个很好的做法。这会让你的答案更有价值,并有助于读者更好地理解你是如何做到的。我还建议你看看我们的FAQ:http://*.com/faq。 – ForceMagic 2012-12-19 16:53:30
为了准确性,我不确定它是可能的:http://veracity-scm.com/qa/questions/545/how-to-version-database-data -with-veracity – gpasse 2012-01-09 17:55:04