将代理PAC与EWS API一起使用

时间:2018-03-08 09:18:54

标签: c# asp.net .net exchange-server office365api

我有一个名为EWS Managed API的网络应用程序,可以连接到office365。

我已按照MSDN上的Get started with EWS Managed API 2.0 client applications文档进行操作。

web.config我已经指定了代理pac:

<configuration>
  <system.net>
    <defaultProxy useDefaultCredentials="false">
      <proxy autoDetect="False" bypassonlocal="True" scriptLocation="http://example.com:8080/proxy.pac" usesystemdefault="False" />
    </defaultProxy>
  </system.net>
  [...]
</configuration>

我尝试以下列方式连接到Exchange:

public static ExchangeService getExchangeService(String username)
{
    ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
    service.Credentials = new WebCredentials(USER_365, PWD_365, DOMAIN_365);
    service.UseDefaultCredentials = true;

    //I've tried both WebProxy settings, this:
    service.WebProxy = WebRequest.GetSystemWebProxy();
    //And this (with no success):
    //service.WebProxy = WebRequest.DefaultWebProxy;

    //I've also tried Autodiscover...
    service.AutodiscoverUrl(USER_365, RedirectionUrlValidationCallback);
    //...and direct url
    //service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, username);

    return service;
}

以下是复制的方法&amp;从MSDN粘贴:

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

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

我试图评论这一行:

//service.Url = new Uri("https://outlook.office365.com/ews/Exchange.asmx");

并添加自动发现:

service.AutodiscoverUrl(username);

是否设置代理,注释掉该行:

ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

但似乎ExchangeService直接调用服务器而没有通过代理...我错过了什么?

由于

1 个答案:

答案 0 :(得分:1)

尝试从web.config中的代理配置中完全删除bypassonlocal属性。将此属性与scriptLocation一起设置存在问题。

了解更多信息:https://blogs.msdn.microsoft.com/rickrain/2011/03/25/why-scriptlocation-may-not-work-when-pointing-to-a-proxy-script-file-in-your-application-config-file/

此外,web.config默认代理配置应该足够,以便您可以删除代码中的任何代理设置。

也许就是这种情况。

更新:在web.config中的proxyaddress而不是scriptLocation属性中指定pac脚本位置可以解决此问题。