使用代理PAC与EWS API

10

我有一个Web应用程序,调用EWS Managed API连接到Office365。

我已经按照MSDN上的开始使用EWS Managed API 2.0客户端应用程序文档进行了操作。

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

以下方法摘自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");

然后添加 Autodiscover:

service.AutodiscoverUrl(username);

设置代理或不设置,将该行注释:

Set the proxy or not, comment out the line:
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

但是看起来ExchangeService直接调用服务器而不经过代理......我错了吗?

谢谢

Translated version:

然而,似乎ExchangeService直接调用了服务器而没有通过代理... 我漏掉了什么吗?

谢谢。

1个回答

3
尝试从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默认代理配置应足够,因此您可以在代码中删除任何代理设置。
也许这就是这里的情况。
更新:在proxyaddress中指定pac脚本位置而不是web.config中的scriptLocation属性应该解决此问题。

抱歉,但它仍然无法工作...我收到了相同的错误:连接尝试失败,因为连接方在一段时间后没有正确响应,或者已建立的连接失败,因为连接的主机未能响应40.xxx.xx.x:443 - Alessandro
@Alessandro,你尝试在Internet Explorer -> Internet Options -> Conncections -> Lan Settings中设置“使用自动配置脚本”了吗? - arekzyla
1
@Alessandro 直接指定代理地址,例如 proxyaddress="http://127.0.0.1:8888",而不是使用 scriptLocation,这样行吗?如果可以的话,问题可能出在脚本本身。 - arekzyla
是的,它有效...我已经看到在ExchangeService中直接设置WebProxy可以工作,但我没有尝试在web.config中直接设置代理。谢谢...所以错误应该在pac文件中,但我仍然不明白为什么它可以在Chrome中工作。 - Alessandro
它也可以与代理PAC一起使用,但我必须使用属性proxyaddress而不是scriptLocation。请编辑您的答案,以便我可以接受它。 - Alessandro
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接