2014-09-11 311 views
1

我有2个共享公用数据库的MVC应用程序。一个坐在因特网服务器上,对GateKeeper数据库使用匿名身份验证,另一个坐在Intranet服务器上,并使用Active Directory的Windows身份验证。使用Windows身份验证和匿名身份验证获取用户名

我想重写EntityFramework的SaveChanges方法来实现审计跟踪。在这个覆盖中,我想记录登录用户的用户名。在外部网站上它将是电子邮件地址,在内部网站上它将是AD帐户名称。

这些应用程序都使用集成安全性连接到数据库,因此它们都运行在可访问数据库的通用应用程序池帐户上。 。

我同时使用Environment.UserName和System.Security.Principal.WindowsIdentity.GetCurrent()名称试过,但两者给我的应用程序池的用户帐户,一个简单的无域:

UserName = Environment.UserName //{ result = CAPETOWN\global-custom } 
UserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name //{ result = global-custom } 

如何我得到的用户名我的愿望

+2

你可能不应该做这种方式,给应用程序(在这种情况下, web应用程序),负责确定和设置用户名,而不是数据/存储库层,只应负责保存/检索和验证数据。 – 2014-09-11 08:58:52

回答

0

试试这个:

string UserName = HttpContext.Current.User.Identity.Name; 

虽然如果您以特定方式添加代码,将不适合您的答案。

您可以获取采取操作的屏幕的网址 string _urlOfEntity = Url = HttpContext.Current.Request.CurrentExecutionFilePath;

用于覆盖的SaveChanges()方法,你可以使用

代码审核编辑动作:

public int SaveChanges(object _olderInstance) 
    { 


     foreach (var ent in this.ChangeTracker.Entries().Where(p => p.State == System.Data.EntityState.Modified || p.State == System.Data.EntityState.Added || p.State == System.Data.EntityState.Deleted)) 
     { 
      // For each changed record, get the audit record entries and add them 
      //foreach (XmlTesst x in GetAuditRecordsForChange(ent)) 
      //{ 
      this.XmlTessts.Add(GetAuditRecordsForChange(ent)); 

      //} 
     } 



     // Call the original SaveChanges(), which will save both the changes made and the audit records 
     return base.SaveChanges(); 
    } 

    public XmlTesst GetAuditRecordsForChange(DbEntityEntry dbEntry) 
    { 
     string tableName, eventtype; 
     XmlTesst XmlForReturn; 


     if (dbEntry.State == System.Data.EntityState.Modified) 
     { 
      TableAttribute tableAttr = dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), false).SingleOrDefault() as TableAttribute; 

      // Get table name (if it has a Table attribute, use that, otherwise get the pluralized name) 
      tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name; 
      XmlDocument XmlCurrentDoc = new XmlDocument(); 
      XmlNode rootNodeCurrent = XmlCurrentDoc.CreateElement(tableName); 
      XmlCurrentDoc.AppendChild(rootNodeCurrent); 

      XmlDocument XmlOldDoc = new XmlDocument(); 
      XmlNode rootNodeOld = XmlOldDoc.CreateElement(tableName); 
      XmlOldDoc.AppendChild(rootNodeOld); 

      foreach (string propertyName in dbEntry.OriginalValues.PropertyNames) 
      { 
       object CurrentValues = dbEntry.CurrentValues.GetValue<object>(propertyName); 
       object OriginalValues = dbEntry.Entity.GetType().GetProperty(propertyName).GetValue(_olderInstancea, null); 

       if (!object.Equals(dbEntry.Entity.GetType().GetProperty(propertyName).GetValue(_olderInstancea, null), CurrentValues) && (OriginalValues != null || CurrentValues != null)) 
       { 

        XmlNode userNodeCurrent = XmlCurrentDoc.CreateElement(propertyName); 
        userNodeCurrent.InnerText = CurrentValues.ToString(); 
        rootNodeCurrent.AppendChild(userNodeCurrent); 

        XmlNode userNodeOld = XmlOldDoc.CreateElement(propertyName); 
        if (OriginalValues == null) 
        { 
         userNodeOld.InnerText = "Not Assigned "; 
         rootNodeOld.AppendChild(userNodeOld); 
        } 
        else 
        { 
         userNodeOld.InnerText = OriginalValues.ToString(); 
         rootNodeOld.AppendChild(userNodeOld); 
        } 


       } 
      } 


      XmlForReturn = new XmlTesst() { OriginalXml = GetXMLAsString(XmlOldDoc), CurrentXml = GetXMLAsString(XmlCurrentDoc), EventType = "Edited", TimeofActivity = DateTime.Now, UserName = HttpContext.Current.User.Identity.Name, Url = HttpContext.Current.Request.CurrentExecutionFilePath, Screen = tableName }; 
      return XmlForReturn; 
0

那么你可以试试这个

HttpContext.User.Identity.Name 
+2

这将是'HttpContext.Current.User.Identity.Name'这是不好的设计,以引入对HttpContext的依赖到数据/业务逻辑/存储库层,它会简单地失败,如果在另一个上下文使用,并会使它很难进行单元测试。 – 2014-09-11 08:55:30