.Net Framework裡面的處理方式
基本上有個
全域
的事件叫做
ServicePointManager.ServerCertificateValidationCallback
會在ssl憑證驗證的時候被觸發,因此假設不管檢查結果是如何,
都要通過
的情況下,可以再
系統啟動的時候
呼叫:
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
不過這個有點太大,因此建議還是
針對性
的去通過比較好,舉例來說,假設有ssl憑證的host是:
problem.com
,那麼可以只當host是
problem.com
的情況下有驗證錯誤在過,範例如下:
ServicePointManager
.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) =>
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
var request = sender as HttpWebRequest;
if (request != null)
var result = request.RequestUri.Host == "problem.com";
return result;
return false;
};
程式應該還蠻好理解:
-
如果ssl驗證沒有錯誤,直接回傳過(true)
-
判斷request的host是不是符合我們已知有問題憑證的host - 如果是就回傳過(true)
-
要不然都不過(false)
或許你會說幹嘛這麼麻煩,何不都過就好?這個其實是為了明確定義那些是特例可以通過,那些不可以。 要記得,這個修改是
全域
都有作用,換句話說所有送出的request,包含像是Xml Web Service這種reference都會吃,因此明確一點比較好。
.Net Core裡面的處理方式
在.Net Core裡面會發現沒有
ServicePointManager
,只有在
HTTPClient 4.1
的版本以上有支援可以再request裡面設定(其實.Net Framework如果用的也是HttpClient 4.1 以上也可以用這種方式):
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) =>
return true;
var client = new HttpClient(handler);
因為這個設定是和某一個client有關,因此直接全部return true比較不會有問題 - 不像上面是一個全域的事件。