1

ユーザーになりすまして、他のユーザーのカレンダーをWebアプリに表示させようとしています。

私はこれを行うために次のコードを使用しています。

 ...
  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);
                }
            }
        }

これは、カレンダーを表示しているすべてのユーザーの開発マシンで完全に機能します。同じドメインの本番マシンに公開する場合。アポイントメントの時間を取り戻しますが、アポイントメントの件名や場所などの詳細はありません。繰り返しますが、本番マシンではなく、開発マシンで動作します。どんな助けでも素晴らしいでしょう。ありがとう!

4

3 に答える 3

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");
    }
}
于 2012-04-16T17:27:40.583 に答える
0

本番環境のアプリプールは、ローカルにある資格情報(通常はドメインユーザーのみ)で実行する必要があります。

于 2012-04-16T17:54:38.527 に答える
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");

EWSによる偽装についてはMSDNも参照してください。

于 2012-04-18T09:37:30.833 に答える