Exchange の偽装を使用して予定を追加する

Exchange の EWS マネージ API または EWS で偽造を使用し、ユーザーの予定表に予定を追加する方法について説明します。

ApplicationImpersonation ロールが有効になっているサービス アカウントを使用して、Exchange の予定表に予定を直接挿入するサービス アプリケーションを作成することができます。偽装を使用すると、アプリケーションがユーザーとして動作し、ユーザーが Outlook などのクライアントを使用して予定表に予定を追加しているように動作します。

偽装を使用する場合は、次のことに注意してください。

  • ExchangeService オブジェクトは、サービス アカウントにバインドする必要があります。同じ ExchangeService オブジェクトを使用して、複数のアカウントを偽装できます。その場合、偽装する各アカウント用に ImpersonatedUserId プロパティを変更します。
  • 偽装されたアカウントに保存するアイテムは、1 回だけ使用できます。たとえば、複数のアカウントで同じ予定を保存する場合は、アカウントごとに予定オブジェクトを作成する必要があります。

前提条件

アプリケーションでは、偽装を使用する前に、Exchange サーバーへの接続に使用するアカウントが必要です。 アクセスするアカウントのアプリケーション偽装の役割が付与されているアプリケーションのサービス アカウントを使用することをお勧めします。 詳細については、「偽装を構成する」を参照してください。

EWS マネージ API で偽装を使用して予定を追加する

次の例では、1 つ以上の Exchange アカウントの予定表に予定または会議を追加します。この方法では、 3 つのパラメーターが必要です。

  • service — Exchange Server のサービス アプリケーションのアカウントにバインドされる ExchangeService オブジェクト。
  • emailAddresses — SMTP メール アドレスの文字列のリストを含む System.List オブジェクト。
  • ファクトリIAppointmentFactory インターフェイスを実装するオブジェクト。このインターフェイスには、ExchangeService オブジェクトをパラメーターとして取得し、予定 オブジェクトを返す GetAppointment という 1 つのメソッドがあります。IAppointmentFactory インターフェイスは、IAppointmentFactory インターフェイスとして定義されています。
private static void CreateAppointments(ExchangeService service, List<string> emailAddresses, IAppointmentFactory factory)
{
  // Loop through the list of email addresses to add the appointment.
  foreach (var emailAddress in emailAddresses)
  {
    Console.WriteLine(string.Format("  Placing appointment in calendar for {0}.", emailAddress));
    // Set the email address of the account to get the appointment.
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, emailAddress);
    // Get the appointment to add.
    Appointment appointment = factory.GetAppointment(service);
    // Save the appointment.
    try
    {
      if (appointment.RequiredAttendees.Count > 0)
      {
        // The appointment has attendees so send them the meeting request.
        appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);
      }
      else
      {
        // The appointment does not have attendees, so just save to calendar.
        appointment.Save(SendInvitationsMode.SendToNone);
      }
    }
    catch (ServiceResponseException ex)
    {
      Console.WriteLine(string.Format("Could not create appointment for {0}", emailAddress));
      Console.WriteLine(ex.Message);
    }
  }
}

予定を保存するときに、コードは出席者が RequiredAttendees プロパティに追加されているかどうかを確認します。追加されている場合は、SendToAllAndSaveCopy 列挙値を使用して Appointment.Save メソッドが呼び出され、出席者は会議出席依頼を受信します。それ以外の場合、Appointment.Save メソッドが SendToNone列挙値を使用して呼び出され、Appointment.IsMeeting プロパティが false に設定されて偽装ユーザーの予定表に予定が保存されます。

IAppointmentFactory インターフェイス

偽装されたユーザーの予定表に予定を保存する場合は毎回新しい Appointment オブジェクトが必要なため、IAppointmentFactory インターフェイスはそれぞれの Appointment オブジェクトの設定に使用されるオブジェクトを抽象化します。このバージョンは、1 つのメソッド GetAppointment のみを含む単純なインターフェイスであり、ExchangeService オブジェクトをパラメーターとして取得し、その ExchangeService オブジェクトにバインドされている新しい Appointment オブジェクトを返します。

interface IAppointmentFactory
{
  Appointment GetAppointment(ExchangeService service);
}

次の AppointmentFactory クラスの例は、今から 3 日の間に発生する単純な予定を返す IAppointmentFactory インターフェイスの実装を示しています。 appointment.RequiredAttendees.Add 行のコメントを解除すると、GetAppointment メソッドは会議を返し、その行に指定されたメール アドレスに、偽装されたユーザーを開催者とする会議出席依頼が届きます。

class AppointmentFactory : IAppointmentFactory
{
  public Appointment GetAppointment(ExchangeService service)
  {
    // First create the appointment to add.
    Appointment appointment = new Appointment(service);
    // Set the properties on the appointment.
    appointment.Subject = "Tennis lesson";
    appointment.Body = "Focus on backhand this week.";
    appointment.Start = DateTime.Now.AddDays(3);
    appointment.End = appointment.Start.AddHours(1);
    appointment.Location = "Tennis club";
    // appointment.RequiredAttendees.Add(new Attendee("sonyaf@contoso1000.onmicrosoft.com"));
    return appointment;
  }
}

EWS で偽装を使用して予定を追加する

EWS では、予定表の所有者の代わりにアプリケーションでカレンダーにアイテムを追加するために偽装を使用できます。次の例は、CreateItem 操作を使用して、偽装されたアカウントの予定表に予定を追加する方法を示します。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
       xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
       xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013" />
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="Pacific Standard Time" />
    </t:TimeZoneContext>
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:SmtpAddress>alfred@contoso.com</t:SmtpAddress>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
  </soap:Header>
  <soap:Body>
    <m:CreateItem SendMeetingInvitations="SendToNone">
      <m:Items>
        <t:CalendarItem>
          <t:Subject>Tennis lesson</t:Subject>
          <t:Body BodyType="HTML">Focus on backhand this week.</t:Body>
          <t:ReminderDueBy>2013-09-19T14:37:10.732-07:00</t:ReminderDueBy>
          <t:Start>2013-09-21T19:00:00.000Z</t:Start>
          <t:End>2013-09-21T20:00:00.000Z</t:End>
          <t:Location>Tennis club</t:Location>
          <t:MeetingTimeZone TimeZoneName="Pacific Standard Time" />
        </t:CalendarItem>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

偽装しているアカウントを指定するための SOAP ヘッダーの ExchangeImpersonation 要素の追加以外は、偽装を使用しないで予定を作成するための XML 要求と同じものを使用します。

次の例は、CreateItem 操作で返される応答 XML を表しています。

注意

ItemId 属性と ChangeKey 属性は読みやすいように短縮されています。

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="775" MinorBuildNumber="7" Version="V2_4" 
 xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types" 
 xmlns="https://schemas.microsoft.com/exchange/services/2006/types" 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:CreateItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
  xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:CreateItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:Items>
            <t:CalendarItem>
              <t:ItemId Id="AAMkA" ChangeKey="DwAAA" />
            </t:CalendarItem>
          </m:Items>
        </m:CreateItemResponseMessage>
      </m:ResponseMessages>
    </m:CreateItemResponse>
  </s:Body>
</s:Envelope>

この場合も、偽装を使用せずに CreateItem 操作をするときに戻される XML と同じものが使用されます。

関連項目