问题
I use a WebClient to get data from an external website from my MVC5 project:
using (var client = new WebClient())
{
var result = client.DownloadString(url);
return this.Content(result);
}
However, the requested URL uses TLS, but we are in development phase, so they use their own certificate which is obviously not legit. Therefore, I receive this exception:
[IOException: Authentication failed because the remote party has closed the transport stream.]
System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) +6587998
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) +132
System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) +59
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) +247
System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) +137
System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) +119
System.Net.TlsStream.CallProcessAuthentication(Object state) +38
System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) +166
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) +21
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) +64
System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) +797
System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) +52
System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) +19
System.Net.ConnectStream.WriteHeaders(Boolean async) +142
I have read many other articles, so I add these code in my Global.asax
Application_Start
method:
System.Net.ServicePointManager.ServerCertificateValidationCallback =
(s, cert, chain, sslPolicyErrors) =>
{
return true;
};
However, the result stays the same. I even tried to put breakpoint at the Callback set line, and 1 at the return true
line. At the start, the breakpoint is hit as intented. However, when the WebClient calls, the breakpoint at return true
line is never hit.
Does WebClient
uses another CallBack method? How can I solve this problem?
回答1:
The thing is that you have to add something like this
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12;
But it depends which protocols it supports. You can check it here https://www.ssllabs.com
This results are for me from this website Protocols
TLS 1.2 Yes TLS 1.1 Yes TLS 1.0 No SSL 3 No SSL 2 No
来源:https://stackoverflow.com/questions/27225263/webclient-ignores-servicepointmanager-servercertificatevalidationcallback