将代理 PAC 与 EWS 结合使用 API
Using Proxy PAC with EWS API
我有一个 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
直接调用服务器而不通过代理......我错过了什么?
谢谢
尝试从 web.config 中的代理配置中完全删除 bypassonlocal 属性。将此属性与 scriptLocation 一起设置存在问题。
此外,web.config 默认代理配置应该足够了,因此您可以删除代码中的任何代理设置。
也许这里就是这种情况。
更新:在 proxyaddress
中指定 pac 脚本位置而不是在 web.config 中指定 scriptLocation
属性应该可以解决此问题。
我有一个 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
直接调用服务器而不通过代理......我错过了什么?
谢谢
尝试从 web.config 中的代理配置中完全删除 bypassonlocal 属性。将此属性与 scriptLocation 一起设置存在问题。
此外,web.config 默认代理配置应该足够了,因此您可以删除代码中的任何代理设置。
也许这里就是这种情况。
更新:在 proxyaddress
中指定 pac 脚本位置而不是在 web.config 中指定 scriptLocation
属性应该可以解决此问题。