回答:
Windows 8.1では、無効なSSL証明書を信頼できるようになりました。Windows.Web.HttpClientを使用する必要があります。または、System.Net.Http.HttpClientを使用する場合は、私が書いたメッセージハンドラーアダプターを使用できます。http: //www.nuget.org/packages/WinRtHttpClientHandler
ドキュメントはGitHubにあります:https : //github.com/onovotny/WinRtHttpClientHandler
デリケートを使用すると、すばやく簡単に解決できますServicePointManager.ServerCertificateValidationCallback
。これにより、独自の証明書検証を提供できます。検証は、アプリドメイン全体にグローバルに適用されます。
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
私は主に、進行中のホストしているエンドポイントに対して実行したい状況でユニットテストに使用し、WCFクライアントまたはでヒットさせようとしていHttpClient
ます。
プロダクションコードの場合は、より細かい制御が必要になる場合があり、WebRequestHandler
およびそのServerCertificateValidationCallback
デリゲートプロパティを使用した方がよいでしょう(下のdtbの回答を参照)。または、を使用して答えを入力しHttpClientHandler
ます。他のフックが見つからない場合を除いて、以前の方法よりも統合テストを行った場合でも、これら2つのうちのいずれかを使用することを好みます。
WebRequestHandlerクラスとそのServerCertificateValidationCallbackプロパティを見てください。
using (var handler = new WebRequestHandler())
{
handler.ServerCertificateValidationCallback = ...
using (var client = new HttpClient(handler))
{
...
}
}
derived class
?
HttpClientHandler
?
.NET標準ライブラリでこれを実行しようとしている場合true
は、ハンドラーに戻るだけのリスクをすべて伴う、簡単な解決策を次に示します。安全はあなた次第です。
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true;
};
var client = new HttpClient(handler);
または、名前空間のHttpClientに使用できWindows.Web.Http
ます。
var filter = new HttpBaseProtocolFilter();
#if DEBUG
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
#endif
using (var httpClient = new HttpClient(filter)) {
...
}
System.Net.Http
、System.Web
そしてWindows.Web.Http
一緒に?
ここでのほとんどの回答は、典型的なパターンを使用することを提案しています:
using (var httpClient = new HttpClient())
{
// do something
}
IDisposableインターフェイスのため。しないでください!
Microsoftが理由を説明します。
そしてここでは、舞台裏で起こっている詳細な分析を見つけることができます:https : //aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
SSLの質問について、およびhttps://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problemに基づいて
ここにあなたのパターンがあります:
class HttpInterface
{
// https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem
// https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient#remarks
private static readonly HttpClient client;
// static initialize
static HttpInterface()
{
// choose one of these depending on your framework
// HttpClientHandler is an HttpMessageHandler with a common set of properties
var handler = new HttpClientHandler();
{
ServerCertificateCustomValidationCallback = delegate { return true; },
};
// derives from HttpClientHandler but adds properties that generally only are available on full .NET
var handler = new WebRequestHandler()
{
ServerCertificateValidationCallback = delegate { return true; },
ServerCertificateCustomValidationCallback = delegate { return true; },
};
client = new HttpClient(handler);
}
.....
// in your code use the static client to do your stuff
var jsonEncoded = new StringContent(someJsonString, Encoding.UTF8, "application/json");
// here in sync
using (HttpResponseMessage resultMsg = client.PostAsync(someRequestUrl, jsonEncoded).Result)
{
using (HttpContent respContent = resultMsg.Content)
{
return respContent.ReadAsStringAsync().Result;
}
}
}
これがWindowsランタイムアプリケーションの場合は、自己署名証明書をプロジェクトに追加し、appxmanifestで参照する必要があります。
ドキュメントはこちら:http : //msdn.microsoft.com/en-us/library/windows/apps/hh465031.aspx
信頼されていないCAからのものである場合も同じです(マシン自体が信頼しないプライベートCAなど)。CAの公開証明書を取得し、コンテンツとしてアプリに追加して、マニフェストに追加する必要があります。
これが完了すると、アプリはそれを正しく署名された証明書として表示します。
答えはありませんが、別の方法があります。
あなたが使用している場合はFiddler2をするトラフィックを監視し、HTTPS復号化を可能にするために、開発環境は文句を言わないだろう。Microsoft SurfaceなどのWinRTデバイスでは、標準のアプリをインストールできないため、これは機能しません。しかし、あなたの開発Win8コンピュータは大丈夫でしょう。
Fiddler2でHTTPS暗号化を有効にするには、[ツール]> [Fiddlerオプション]> [HTTPS(タブ)]> [HTTPSトラフィックの復号化]をオンにします。
私は誰かがエレガントな解決策を持っていることを期待してこのスレッドに目を離さないつもりです。
このKubernetesクライアントで、X509VerificationFlags.AllowUnknownCertificateAuthorityを使用して自己署名の自己署名ルート証明書を信頼する例を見つけました。独自のPEMエンコードされたルート証明書で動作するように、それらの例を少し修正しました。うまくいけば、これは誰かを助けます。
namespace Utils
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
/// <summary>
/// Verifies that specific self signed root certificates are trusted.
/// </summary>
public class HttpClientHandler : System.Net.Http.HttpClientHandler
{
/// <summary>
/// Initializes a new instance of the <see cref="HttpClientHandler"/> class.
/// </summary>
/// <param name="pemRootCerts">The PEM encoded root certificates to trust.</param>
public HttpClientHandler(IEnumerable<string> pemRootCerts)
{
foreach (var pemRootCert in pemRootCerts)
{
var text = pemRootCert.Trim();
text = text.Replace("-----BEGIN CERTIFICATE-----", string.Empty);
text = text.Replace("-----END CERTIFICATE-----", string.Empty);
this.rootCerts.Add(new X509Certificate2(Convert.FromBase64String(text)));
}
this.ServerCertificateCustomValidationCallback = this.VerifyServerCertificate;
}
private bool VerifyServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
// add all your extra certificate chain
foreach (var rootCert in this.rootCerts)
{
chain.ChainPolicy.ExtraStore.Add(rootCert);
}
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
var isValid = chain.Build((X509Certificate2)certificate);
var rootCertActual = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
var rootCertExpected = this.rootCerts[this.rootCerts.Count - 1];
isValid = isValid && rootCertActual.RawData.SequenceEqual(rootCertExpected.RawData);
return isValid;
}
// In all other cases, return false.
return false;
}
private readonly IList<X509Certificate2> rootCerts = new List<X509Certificate2>();
}
}
私はうまくいくように見えるオンラインの例を見つけました:
まず、新しいICertificatePolicyを作成します
using System.Security.Cryptography.X509Certificates;
using System.Net;
public class MyPolicy : ICertificatePolicy
{
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request,
int certificateProblem)
{
//Return True to force the certificate to be accepted.
return true;
}
}
次に、次のようにhttpリクエストを送信する前にこれを使用します。
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/
ServicePointManager.CertificatePolicy
廃止されました:docs.microsoft.com/en-us/dotnet/framework/whats-new/...