我正在尝试冒充用户将其他用户日历显示在网络应用上。
我使用以下代码执行此操作。
...
private const string aliasUserName = "vader@mydomain.com";
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 :(得分: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");
}
}
答案 1 :(得分:0)
生产中的应用程序池需要使用您在本地拥有的凭据运行,通常只是域用户。
答案 2 :(得分:0)
使用AutodiscoverUrl的电子邮件地址并不意味着您冒充该用户。您还必须设置凭据,还必须设置要模拟的用户的ID。例如,如果您希望以当前用户身份登录EWS,并且您希望模拟“vader@mydomain.com”,那么您可以这样做:
ExchangeService service = ...;
service.Credentials = CredentialCache.DefaultNetworkCredentials;
service.AutodiscoverUrl("vader@mydomain.com");
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "vader@mydomain.com");
另请参阅MSDN on impersonation与EWS。