2012-04-16 134 views
1

我想模拟用户以获取其他用户日历以显示在Web应用程序上。Exchange模拟不显示详细信息

我正在使用下面的代码来执行此操作。

... 
    private const string aliasUserName = "[email protected]"; 

public CalendarItem[] GetCalendarItemsForUser(string userEmail, DateTime startDate, DateTime endDate) 
    { 
     _exchangeService.AutodiscoverUrl(aliasUserName); 


     List<AttendeeInfo>userList = new List<AttendeeInfo> {new AttendeeInfo(userEmail)}; 
     List<CalendarItem> itemList = new List<CalendarItem>(); 

     GetUserAvailabilityResults availabilityResults = _exchangeService.GetUserAvailability(userList, new TimeWindow(startDate, endDate), AvailabilityData.FreeBusy); 
     foreach (var item in availabilityResults.AttendeesAvailability) 
     { 
      foreach (var e in item.CalendarEvents) 
      { 
       if (e.FreeBusyStatus == LegacyFreeBusyStatus.Busy) 
       { 
        CalendarItem i = new CalendarItem {Id = DateTime.Now.Millisecond}; 
        if (e.Details != null) 
        { 
         i.Title = e.Details.Subject; 
         i.Location = e.Details.Location; 
        } 
        i.StartTime = e.StartTime; 
        i.EndTime = e.EndTime; 
        itemList.Add(i); 
       } 
      } 
     } 

这对我的开发机器完美适用于所有查看日历的用户。 在同一个域上发布到我的生产机器时。我找回约会的时间,但没有任何细节,如约会的主题或地点。它再次在我的开发机器上工作,而不是在生产机器上。 任何帮助将是伟大的。 谢谢!

回答

0

这是我创建的一个类,它利用WinAPI来允许基于实例的模拟。给这一个镜头,看看它是否帮助:

/// <summary> 
/// Leverages the Windows API (advapi32.dll) to programmatically impersonate a user. 
/// </summary> 
public class ImpersonationContext : IDisposable 
{ 
    #region constants 

    private const int LOGON32_LOGON_INTERACTIVE = 2; 
    private const int LOGON32_PROVIDER_DEFAULT = 0; 

    #endregion 

    #region global variables 

    private WindowsImpersonationContext impersonationContext; 
    private bool impersonating; 

    #endregion 

    #region unmanaged code 

    [DllImport("advapi32.dll")] 
    private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern bool RevertToSelf(); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    private static extern bool CloseHandle(IntPtr handle); 

    #endregion 

    #region constructors 

    public ImpersonationContext() 
    { 
     impersonating = false; 
    } 

    /// <summary> 
    /// Overloaded constructor and begins impersonating. 
    /// </summary> 
    public ImpersonationContext(string userName, string password, string domain) 
    { 
     this.BeginImpersonationContext(userName, password, domain); 
    } 

    #endregion 

    #region impersonation methods 

    /// <summary> 
    /// Begins the impersonation context for the specified user. 
    /// </summary> 
    /// <remarks>Don't call this method if you used the overloaded constructor.</remarks> 
    public void BeginImpersonationContext(string userName, string password, string domain) 
    { 
     //initialize token and duplicate variables 
     IntPtr token = IntPtr.Zero; 
     IntPtr tokenDuplicate = IntPtr.Zero; 

     if (RevertToSelf()) 
     { 
      if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
      { 
       if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
       { 
        using (WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate)) 
        { 
         //begin the impersonation context and mark impersonating true 
         impersonationContext = tempWindowsIdentity.Impersonate(); 
         impersonating = true; 
        } 
       } 
      } 
     } 

     //close the handle to the account token 
     if (token != IntPtr.Zero) 
      CloseHandle(token); 

     //close the handle to the duplicated account token 
     if (tokenDuplicate != IntPtr.Zero) 
      CloseHandle(tokenDuplicate); 
    } 

    /// <summary> 
    /// Ends the current impersonation context. 
    /// </summary> 
    public void EndImpersonationContext() 
    { 
     //if the context exists undo it and dispose of the object 
     if (impersonationContext != null) 
     { 
      //end the impersonation context and dispose of the object 
      impersonationContext.Undo(); 
      impersonationContext.Dispose(); 
     } 

     //mark the impersonation flag false 
     impersonating = false; 
    } 

    #endregion 

    #region properties 

    /// <summary> 
    /// Gets a value indicating whether the impersonation is currently active. 
    /// </summary> 
    public bool Impersonating 
    { 
     get 
     { 
      return impersonating; 
     } 
    } 

    #endregion 

    #region IDisposable implementation 

    ~ImpersonationContext() 
    { 
     Dispose(false); 
    } 

    public void Dispose() 
    { 
     Dispose(true);    
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (impersonationContext != null) 
      { 
       impersonationContext.Undo(); 
       impersonationContext.Dispose(); 
      } 
     } 
    } 

    #endregion  
} 

这里是你将如何使用类:

using (ImpersonationContext context = new ImpersonationContext("user", "password", "domain")) 
{ 
    if (context.Impersonating) 
    { 
     Process.Start(@"/Support/SendFax/SendFax.exe"); 
    } 
} 
0

你在生产应用程序池需要与你有本地凭据运行,通常只是一个域用户。

0

在AutodiscoverUrl中使用电子邮件地址并不意味着您冒充该用户。您还必须设置凭据,并且还必须设置要模拟的用户的ID。例如,如果你想登录到EWS作为当前用户,并希望模仿“[email protected]”这是你会怎么做:

ExchangeService service = ...; 
    service.Credentials = CredentialCache.DefaultNetworkCredentials; 
    service.AutodiscoverUrl("[email protected]"); 
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "[email protected]"); 

另见MSDN on impersonation与EWS。