【问题标题】:Using Proxy PAC with EWS API将代理 PAC 与 EWS API 一起使用
【发布时间】:2018-08-16 14:08:46
【问题描述】:

我有一个 Web 应用程序,它调用 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;
}

以下是从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 直接调用服务器而不通过代理...我错过了什么?

谢谢

【问题讨论】:

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


    【解决方案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 默认代理配置应该足够了,因此您可以删除代码中的任何代理设置。

    也许这里就是这样。

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

    【讨论】:

    • 对不起,但它仍然不起作用...我得到同样的错误:A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 40.xxx.xx.x:443
    • @Alessandro 你试过在 Internet Explorer -> Internet 选项 -> 连接 -> 局域网设置中设置“使用自动配置脚本”吗?
    • 是的,我已经在“局域网设置”中设置了该设置,但 IE 无法访问 40.xxx.xx.x 而 Chrome 将我重定向到 login.microsoftonline.com
    • @Alessandro 是否直接指定代理,如 proxyaddress="127.0.0.1:8888" 而不是 scriptLocation 有效?如果是这样,问题可能出在脚本本身。
    • 是的,它有效...我已经看到直接在ExchangeService 中设置WebProxy 有效,但我没有尝试直接在web.config 中设置代理.谢谢...所以错误应该在 pac 中,但我仍然不明白为什么它适用于 Chrome。
    猜你喜欢
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2013-01-10
    • 2018-11-02
    • 2014-03-06
    相关资源
    最近更新 更多