Exchange Online 開発 : 自動検出 (Autodiscover) と EWS Managed API


環境 : Microsoft Online Services, Visual Studio 2008, Exchange Web Services (EWS) Managed API 1.0

Exchange Online 開発

こんにちは。

今回は、自動検出 (Autodiscover) と、Managed API のすばらしさについて説明します。

例えば、第 1 回 で作成したアプリケーションを全世界にリリースしたと仮定しましょう。この第 1 回の app.config をもう 1 度見て頂いくと分かりますが、今は、日本の利用者を想定しているため、下記の接続先のアドレスが埋め込まれています。

https://red003.mail.apac.microsoftonline.com/EWS/Exchange.asmx

このため、米国でこのアプリケーションを使う人は、そのままでは動作しません。(Exchange Online の EWS では、米国領域、欧州領域、アジア領域で、接続先のアドレスが異なります。)

アプリケーションの起動時に、「どこの国籍ですか ?」と聞いて接続先を変更するのもどうも パッ としませんし、そのための分岐処理なども構築したくはありません。また、On-Premise の Exchange と Exchange Online の共存環境 (Co-existence) で使用している場合も、こうした接続ポイントの課題をクリアしないといけません。

このような場合に使用するのが、今日ご紹介する Exchange の「自動検出」 (Autodiscover) と呼ばれる仕組みです。

Exchange の自動検出 (Autodiscover) の概要

皆さんも経験があるかと思いますが、Outlook を最初に起動して、メールアドレスとパスワードなどを入力すると、下図のように、接続ポイントを自動検出します。

Active Directory が入っている企業内の環境では、Outlook の初回起動時に、Active Directory の設定情報を見て、何も聞かれることなく自動的に Exchange Server に接続をおこなう場面に出くわしたことがある方も多いでしょう。

Exchange Online でも、この Autodiscover は使用できます。
Exchange Online で独自にドメインを作成したら、ドメイン登録をしたドメイン レジストラーのサイトで、下記に記載されている CNAME と SPF を登録しておくことで、Autodiscover が使用できます。(日本の場合は、AutoDiscoverRedirect-Red003.Mail.apac.MicrosoftOnline.com の FQDN を登録します。) この作業は、開発者ではなく、Microsoft Online Services でドメインを作成した管理者がおこないます。

TechNet : Enable Autodiscover and Add a Sender Policy Framework

http://technet.microsoft.com/en-us/library/cc742638.aspx

注記 : Autodiscover は、こうしたアドレス (URL) の検出以外に、Outlook 予定表の Free / Busy の検出など、他の場面でも使用されています。

Autodiscover を使用した EWS のアプリケーション構築概要

まず、残念なお話をして、それから明るい話をしましょう。

まず、現状の Exchange 2007 ベースのEWS (Exchange Web Services) では、残念なことに、Autodiscover をおこなうための専用のメソッドなどはありません。考えて頂けると すぐわかると思いますが、「接続先のサーバーを探しに行く」ことが Autodiscover ですから、サーバー側にそのようなメソッドが無くて当然です。
このため、Web サービスをそのまま使う場合は、Autodiscover の手続きを 開発者自らがプログラム コードで実装する必要があります。

Autodiscover の処理を作成するには、その流れを理解しておく必要があります。Autodiscover の大まかな処理の流れを記載すると、以下の順序になります。(開発者は、この手順に沿って、コードを記述します。)

  1. まず、Active Directory (AD) に問い合わせて、登録されている SCP (サービス接続ポイント) の一覧を取得します。そして、そのユーザーの設定情報が取得可能か、これらのアドレスすべてに順番に問い合わせます。(なお、Exchange Server の CAS のインストール時に、接続先の情報が Active Directory に書き込まれます。複数インストールした場合は、接続ポイントの一覧が AD に書き込まれます。)
    ただし、Exchange Online の場合、無論、この手続きは必要ありません。
  2. 上記で情報を取得できない場合、つぎに、入力されたメールアドレスのドメイン名をもとに、以下に接続して情報の取得を試みます。(SSL ですから、証明書も正しく設定する必要があります。)
    • https://<ドメイン名>/autodiscover/autodiscover.xml
    • https://autodiscover.<ドメイン名>/autodiscover/autodiscover.xml
  3. さらに、これでも確認できない場合には、Non-SSL で上記のアドレスに接続をおこない、リダイレクト先の URL を取得します。そして、そのリダイレクト先の URL からデータ (情報) の取得を試みます。

上記のいずれかでデータ (情報) の取得が可能な場合、取得したデータは POX 形式で返ってきますので、これをパースして、必要な情報 (EWS の接続先の情報 など) を取得します。
この Autodiscover の大まかな流れは、以下に記載されていますので、軽く見ておいてください。Exchange Online の場合、Active Directory による SCP (サービス接続ポイント) は関係ありませんので、下記 (リンク先) の 2 番目の図に掲載されているインターネット シナリオのケースになります。

TechNet : 自動検出サービスについて

http://technet.microsoft.com/ja-jp/library/bb124251(EXCHG.140).aspx

この処理をプログラム コードを使って記述することになりますが、ご想像いただける通り、これは結構退屈な作業になります。このサンプル コードは下記に記載されています。

Microsoft Exchange Online Standard 開発者ガイド :

http://www.microsoft.com/downloads/details.aspx?FamilyID=0ffa787d-79cd-43fd-b528-b47d45c7ea0d&displaylang=ja

Autodiscover Sample Application :

http://msdn.microsoft.com/en-us/library/bb204057.aspx

さて、当然、こんな面倒な実装 (プログラミング) は、できれば避けたいものです。
そこで、第 1 回 のさいごに紹介した、Managed API の出番になります。このクライアント側の API を使うと、これまで見てきた処理の記述が簡素化されるほか、今回の Autodiscover のようなクライアント サイド特有の処理においては、さらに絶大な効果を発揮することになります !

Managed API を使用した Autodiscover のサンプル構築

EWS (Exchange Web Service) をラッピングしたこの SDK を使うと、上述した Autodiscover の仕組みもメソッド 1 つで解決します。

では、そろそろ、この便利な Managed API を使用してみましょう。この Managed API に慣れてしまうと、あまりに便利すぎて、もう EWS をそのまま使う手法には戻れなくなってしまうでしょう。

ここでは、Managed API を使って、第 1 回 で構築したメール送信アプリケーションと同じものを作成します。(申し訳ありませんが、第 1 回 で作成したプロジェクトはまったく使用せず、最初から作り直します。)

まずは、EWS (Exchange Web Services) Managed API をダウンロードして、開発環境にインストールしてください。

補足 : Office 365 を使用している方は、Managed API version 1.1 以降を使用してください。

Visual Studio を起動し、Windows フォーム アプリケーション、WPF アプリケーションなど、プロジェクトを新規作成します。

ソリューション エクスプローラーでプロジェクトを右クリックして、[参照の追加] を選択し、以下のアセンブリ参照を追加してください。

%programfiles%\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll

さいごに、以下の通り、コードを記述します。

using Microsoft.Exchange.WebServices.Data;

private void SendMailButton_Click(object sender, EventArgs e)
{
    string emailAddress = @demouser1@tsmatsuzdemo.com;

    ExchangeVersion ver = new ExchangeVersion();
    ver = ExchangeVersion.Exchange2007_SP1;
    ExchangeService sv = new ExchangeService(ver);
    sv.TraceEnabled = true; // デバッグ用
    sv.Credentials = new System.Net.NetworkCredential(emailAddress, "XXXXXXX");
    //sv.EnableScpLookup = false; // Managed API 1.1 以降で使用可能
    sv.AutodiscoverUrl(emailAddress, MyCallback);
    //sv.Url = new Uri(@"https://red003.mail.apac.microsoftonline.com/EWS/Exchange.asmx");
    EmailMessage msg = new EmailMessage(sv);
    msg.Subject = "トマト";
    msg.Body = new MessageBody(BodyType.Text, "松崎惨状");
    msg.ToRecipients.Add("demouser2@tsmatsuz.apac.microsoftonline.com");
    msg.SendAndSaveCopy();

    MessageBox.Show("送信完了 !");
}

// AutodiscoverRedirectionUrlValidationCallback
private static bool MyCallback(string url)
{
    // リダイレクトの検証をおこない、OK なら true !
    return true;
}

まず、この連載の 第 1 回 を読まれた方は、上記のプログラムの短さに驚くことでしょう。面倒な構成ファイル (.config) の記述も必要ありません。
ここでは簡単にメールを送信しているだけですが、プログラミングの方法は、EWS Managed API のインストール ディレクトリに入っている GettingStarted.doc にさまざまなサンプルが載っていますので、是非参考にしてください。

そして、自動検出は、上記の通り、AutodiscoverUrl メソッド 1 つ (上記太字) ですべて実施してくれます。
開発時は、上記のように、TraceEnabled を true にしておくと、出力結果 (Visual Studio の出力ウィンドウ など) に、どのようなパスで検出したか出力されますので、自動検出の際には、デバッグ目的で使用できます。うまく行くと、この出力結果には、以下のような感じに出力されているはずです。

... 前半省略

<EwsLogEntry ...>Trying to call Autodiscover for demouser1@tsmatsuzdemo.com on https://internal.microsoft.com/autodiscover/autodiscover.xml.</EwsLogEntry>
... ここに、サーバーが返してくるエンベロープを出力
<EwsLogEntry ...> failed: WebException (リモート サーバーがエラーを返しました: (401) 許可されていません)</EwsLogEntry>

<EwsLogEntry ...>Trying to call Autodiscover for demouser1@tsmatsuzdemo.com on https://mail.microsoft.com/autodiscover/autodiscover.xml.</EwsLogEntry>
... ここに、サーバーが返してくるエンベロープを出力
<EwsLogEntry ...> failed: WebException (リモート サーバーがエラーを返しました: (401) 許可されていません)</EwsLogEntry>

... といった具合に、以降、しばらく、Active Directory に登録されている社内環境などのサーバーを検出します

<EwsLogEntry ...>Trying to call Autodiscover for demouser1@tsmatsuzdemo.com on https://tsmatsuzdemo.com/autodiscover/autodiscover.xml.</EwsLogEntry>
<EwsLogEntry ...> failed: WebException (リモート名を解決できませんでした。: 'tsmatsuzdemo.com')</EwsLogEntry>

<EwsLogEntry ...>Trying to call Autodiscover for demouser1@tsmatsuzdemo.com on https://autodiscover.tsmatsuzdemo.com/autodiscover/autodiscover.xml.</EwsLogEntry>
<EwsLogEntry ...> failed: WebException (リモート サーバーに接続できません。)</EwsLogEntry>

<EwsLogEntry ...>Trying to get Autodiscover redirection URL from http://autodiscover.tsmatsuzdemo.com/autodiscover/autodiscover.xml.</EwsLogEntry>
<EwsLogEntry ...>Redirection URL found: 'https://autodiscover-red003.mail.apac.microsoftonline.com/autodiscover/autodiscover.xml'</EwsLogEntry>

<EwsLogEntry ...>Trying to call Autodiscover for demouser1@tsmatsuzdemo.com on https://autodiscover-red003.mail.apac.microsoftonline.com/autodiscover/autodiscover.xml.</EwsLogEntry>

... ここで、サーバーが返してくる POX のデータを取得して接続処理 !!

... 以降、省略

この通り、上記で説明した 1 - 3 のステップに従って、検出をおこなっていることがお分かり頂けるでしょう。
Exchange Online で検出に失敗する場合には、特に、上記の太字の箇所に注意してください。ここで Redirection URL が見つからなかったり、誤った Redirection URL などが返ってきていないか確認してみてください。(また、ブラウザで該当の Url を入力して、ちゃんとリダイレクトされるか確認してみましょう。)
もしエラーになる場合には、上述した CNAME、SPF などの設定がおこなわれていないということになります。

また、上記の例のように、皆さんの企業のメール環境 (AD に登録されている Exchange 環境) の数によっては、非常に多くのサーバーに問い合わせに行くため、かなり遅くなります。
そのため、実際のプログラミングでは、一度検出した URL を取得してキャッシュしておき、次回からは、そのキャッシュされた URL を使用して接続するようにプログラミングしておくと良いでしょう。(上記の場合、sv.Url.ToString() で、検出された Url を取得できます。) なお、検出に失敗した場合は、ユーザーに手入力してもらうなど、リカバリ用の処理も構築しておきましょう。

なお、Microsoft Online Services が既定で作成する *****.*****.microsoftonline.com のドメインを使用しても、ちゃんと Autodiscovery は設定されていますが、上記のプログラムで動かしてみたところ、タイミングよって検出できるときと、うまくいかない時 (Redirection URL が検出できないとき) がありましたので注意してください。(できるだけ、Microsoft Online Services のマニュアルに従って、ドメインを新規作成し、ドメイン レジストラーに必要な設定を実施しておきましょう。)

ここでは、Autodiscover に注目して Managed API の良さを説明しましたが、例えば、個人配布リストの操作など、この他にもさまざまな恩恵を受けることができます。
これから Exchange の開発をされる方は、是非、この Managed API を活用してみてください。

 

Comments (0)

Skip to main content