5

Mono (バージョン 2.10.8.1 & 3.0.6) を介して debian で Exchange EWS 2 を使用して実験しようとしています。vs2012 を使用して Windows 8 で開発しています。

プログラムは Windows で問題なく動作し、期待どおりの出力が得られます。

ただし、モノラルでは、次の出力と例外が発生し続けます。

<Trace Tag="AutodiscoverConfiguration" Tid="1" Time="2013-03-07 19:09:05Z">
Starting SCP lookup for domainName='example.com', root path=''
</Trace>
Connect Error

Unhandled Exception: LdapException: (91) Connect Error
System.Net.Sockets.SocketException: No such host is known
  at System.Net.Dns.hostent_to_IPHostEntry (System.String h_name, System.String[]          h_aliases, System.String[] h_addrlist) [0x00000] in <filename unknown>:0
  at System.Net.Dns.GetHostByName (System.String hostName) [0x00000] in <filename unknown>:0
  at System.Net.Dns.GetHostEntry (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
  at System.Net.Dns.GetHostAddresses (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
  at System.Net.Sockets.TcpClient.Connect (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
  at System.Net.Sockets.TcpClient..ctor (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
  at Novell.Directory.Ldap.Connection.connect (System.String host, Int32 port, Int32 semaphoreId) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: LdapException: (91) Connect Error
System.Net.Sockets.SocketException: No such host is known
  at System.Net.Dns.hostent_to_IPHostEntry (System.String h_name, System.String[] h_aliases, System.String[] h_addrlist) [0x00000] in <filename unknown>:0
  at System.Net.Dns.GetHostByName (System.String hostName) [0x00000] in <filename unknown>:0
  at System.Net.Dns.GetHostEntry (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
  at System.Net.Dns.GetHostAddresses (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
  at System.Net.Sockets.TcpClient.Connect (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
  at System.Net.Sockets.TcpClient..ctor (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
  at Novell.Directory.Ldap.Connection.connect (System.String host, Int32 port, Int32 semaphoreId) [0x00000] in <filename unknown>:0

どうやら、見つからないホストを検索しようとしています。Windows システムと Linux システムの両方が同じ DNS サーバーを使用しているため、問題の原因ではありません。

機能するときにWindowsでトレースを読みました-トレースは、ルックアップが数回失敗し、自動検出メソッドが機能するURLにヒットするまでいくつかの異なるURLを試行することを示しています-モノでは、最初の後にフォールオーバーするようです失敗して終わりです。

モノラルで ews を使用するためにグーグルを試してみましたが、それを行っている人を見つけられなかったので、他に何を試したらよいかわかりません。

使用されているコードは以下のとおりです。ほぼすべて、http://msdn.microsoft.com/en-us/library/exchange/dd633709(v= exchg.80 ).aspx のコード例から取得したものです。

class Program
{
    private static int verbose = 10;
    private static string loginEmail = "email@example.com";
    private static string password = "#############";

    static void Main(string[] args)
    {
        try
        {

            ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);

            service.Credentials = new WebCredentials(loginEmail, password);

            if (verbose >= 10)
            {

                service.TraceEnabled = true;
                service.TraceFlags = TraceFlags.All;

            }

            service.AutodiscoverUrl(loginEmail, RedirectionUrlValidationCallback);

            Console.WriteLine("AutoDiscover Completed");

            getContacts(service);

            Console.ReadLine();

        }
        catch (Exception e) {
            Console.WriteLine(e.Message);
            foreach (string key in e.Data.Keys)
            {
                Console.WriteLine(String.Format("{0}: {1}",key, e.Data[key]));
            }
            throw e;
        }

    }

    private static void getContacts(ExchangeService service){


        // Get the number of items in the Contacts folder.
        ContactsFolder contactsfolder = ContactsFolder.Bind(service, WellKnownFolderName.Contacts);

        // Set the number of items to the number of items in the Contacts folder or 1000, whichever is smaller.
        int numItems = contactsfolder.TotalCount < 1000 ? contactsfolder.TotalCount : 1000;

        // Instantiate the item view with the number of items to retrieve from the Contacts folder.
        ItemView view = new ItemView(numItems);

        // To keep the request smaller, request only the display name property.
        //view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ContactSchema.DisplayName);

        // Retrieve the items in the Contacts folder that have the properties that you selected.
        FindItemsResults<Item> contactItems = service.FindItems(WellKnownFolderName.Contacts, view);

        // Display the list of contacts. 
        foreach (Item item in contactItems)
        {
            if (item is Contact)
            {
                Contact contact = item as Contact;

                Console.WriteLine();
                Console.WriteLine(contact.DisplayName);
                if (verbose >= 2)
                {
                    Console.WriteLine("    " + contact.Id);
                }

                try
                {
                    Console.WriteLine("    " + contact.EmailAddresses[EmailAddressKey.EmailAddress1].ToString());
                }
                catch (Exception e) 
                {
                    if (verbose >= 5)
                    {
                        Console.WriteLine("    " + "Email Address 1 Not Available : " + e.Message);
                    }
                }
            }
        }

    }

    #region taken from tutorial

    private static bool CertificateValidationCallBack(
        object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate certificate,
        System.Security.Cryptography.X509Certificates.X509Chain chain,
        System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        // If the certificate is a valid, signed certificate, return true.
        if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
        {
            return true;
        }

        // If there are errors in the certificate chain, look at each error to determine the cause.
        if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
        {
            if (chain != null && chain.ChainStatus != null)
            {
                foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                {
                    if ((certificate.Subject == certificate.Issuer) &&
                       (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                    {
                        // Self-signed certificates with an untrusted root are valid. 
                        continue;
                    }
                    else
                    {
                        if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                        {
                            // If there are any other errors in the certificate chain, the certificate is invalid,
                            // so the method returns false.
                            return false;
                        }
                    }
                }
            }

            // When processing reaches this line, the only errors in the certificate chain are 
            // untrusted root errors for self-signed certificates. These certificates are valid
            // for default Exchange server installations, so return true.
            return true;
        }
        else
        {
            // In all other cases, return false.
            return false;
        }
    }

    private static bool RedirectionUrlValidationCallback(string redirectionUrl)
    {
        // The default for the validation callback is to reject the URL.
        bool result = false;

        Uri redirectionUri = new Uri(redirectionUrl);

        // Validate the contents of the redirection URL. In this simple validation
        // callback, the redirection URL is considered valid if it is using HTTPS
        // to encrypt the authentication credentials. 
        if (redirectionUri.Scheme == "https")
        {
            result = true;
        }
        return result;
    }

    #endregion

}

BeepBeep からの回答は、これを解決するのに役立ちました。

BeepBeepの提案を使用した後、Monoにdnsapi.dllがないように見えるという問題がありました(例外による)。今のところ自動検出をスキップすることでこれを解決しました。

それをするために、私は交換しました

service.AutodiscoverUrl(loginEmail, RedirectionUrlValidationCallback);

service.Url = new Uri("https://blah.com/ews/exchange.asmx");

次に、証明書にエラーがありました (例外は「リクエストまたは復号化のエラー」のようなものでした) - mono にはデフォルトでルート CA 証明書が含まれていないことを知っておく必要があります。詳細はこちら: Mono FAQセキュリティについて

mozroots ツールを使用して、必要な証明書を取得するための怠惰な方法を選択しました。ただし、これは期待どおりに機能せず、エラーが持続しました。

次に、上記の FAQ からも tlstest を使用して問題を特定しました。これは、使用していた証明書チェーンに関連していました (ルートは受け入れられましたが、中間は受け入れられませんでした)。次に、FAQ に記載されている 3 番目のツール (certmgr) を使用して、証明書をインストールしました。

その後、すべてが機能します。

4

1 に答える 1

2

同じ問題で、このコードを使用して解決しました:

ExchangeService service = new ExchangeService();
service.EnableScpLookup = false;
于 2013-04-08T09:27:18.000 に答える