https 사이트에 연결해야하는 프로젝트를 진행 중입니다. 연결할 때마다 해당 사이트의 인증서가 신뢰할 수없는 사이트에서 온 것이므로 코드에서 예외가 발생합니다. .net core http에서 인증서 확인을 우회하는 방법이 있습니까?
이전 버전의 .NET에서이 코드를 보았습니다. 이런 게 필요한 것 같아요.
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
답변
ServicePointManager.ServerCertificateValidationCallback은 .Net Core에서 지원되지 않습니다.
현재 상황은 곧 출시 될 4.1. * System.Net.Http 계약 (HttpClient)에 대한 새로운 ServerCertificateCustomValidationCallback 메서드 가 될 것입니다 . .NET Core 팀은 현재 4.1 계약을 마무리하고 있습니다. 여기 github 에서 이에 대해 읽을 수 있습니다.
CoreFx 또는 MYGET 피드 ( https://dotnet.myget.org/gallery/dotnet-core) 에서 직접 소스를 사용하여 System.Net.Http 4.1의 시험판 버전을 사용해 볼 수 있습니다.
Github의 현재 WinHttpHandler.ServerCertificateCustomValidationCallback 정의
답변
최신 정보:
아래에서 언급했듯이 모든 구현이이 콜백을 지원하는 것은 아닙니다 (예 : iOS와 같은 플랫폼). 이 경우 문서에서 말했듯이 유효성 검사기를 명시 적으로 설정할 수 있습니다.
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
.NET Core 2.2, 3.0 및 3.1에서도 작동합니다.
더 많은 제어권을 가진 오래된 대답 이지만 던질 수 있습니다 PlatformNotSupportedException
.
다음과 같은 익명 콜백 함수를 사용하여 HTTP 호출에서 SSL 인증서 검사를 재정의 할 수 있습니다.
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
// Make your request...
}
}
또한 HttpClient
즉시 삭제되지 않고 연결이 열린 상태로 유지 되는 공유 객체이기 때문에 팩토리 패턴을 사용하는 것이 좋습니다 .
답변
나는 이것으로 해결한다.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("HttpClientWithSSLUntrusted").ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true;
}
});
YourService.cs
public UserService(IHttpClientFactory clientFactory, IOptions<AppSettings> appSettings)
{
_appSettings = appSettings.Value;
_clientFactory = clientFactory;
}
var request = new HttpRequestMessage(...
var client = _clientFactory.CreateClient("HttpClientWithSSLUntrusted");
HttpResponseMessage response = await client.SendAsync(request);
답변
동일한 문제에 대한 답을 찾기 위해 여기에 왔지만 NET Core 용 WCF를 사용하고 있습니다. 같은 보트에있는 경우 다음을 사용하십시오.
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.None,
RevocationMode = X509RevocationMode.NoCheck
};
답변
.NetCore에서 services configure method에서 다음 코드 조각을 추가 할 수 있습니다. 개발 환경에서만 SSL 인증서를 통과하는지 확인하는 검사를 추가했습니다.
services.AddHttpClient("HttpClientName", client => {
// code to configure headers etc..
}).ConfigurePrimaryHttpMessageHandler(() => {
var handler = new HttpClientHandler();
if (hostingEnvironment.IsDevelopment())
{
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
}
return handler;
});
답변
.NET Core 2.2 및 Docker Linux 컨테이너에서 자체 서명 된 인증서 및 클라이언트 인증서 인증으로 작업 할 때 동일한 문제에 직면했습니다. 내 dev Windows 시스템에서는 모든 것이 잘 작동했지만 Docker에서는 다음과 같은 오류가 발생했습니다.
System.Security.Authentication.AuthenticationException : 유효성 검사 절차에 따라 원격 인증서가 잘못되었습니다.
다행히 인증서는 체인을 사용하여 생성되었습니다. 물론이 솔루션을 항상 무시하고 위의 솔루션을 사용할 수 있습니다.
그래서 여기 내 해결책이 있습니다.
-
내 컴퓨터에서 Chrome을 사용하여 인증서를 P7B 형식으로 저장했습니다.
-
다음 명령을 사용하여 인증서를 PEM 형식으로 변환합니다.
openssl pkcs7 -inform DER -outform PEM -in <cert>.p7b -print_certs > ca_bundle.crt
-
ca_bundle.crt 파일을 열고 모든 주제 녹음을 삭제하고 깨끗한 파일을 남깁니다. 아래 예 :
-----BEGIN CERTIFICATE-----
_BASE64 DATA_
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
_BASE64 DATA_
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
_BASE64 DATA_
-----END CERTIFICATE-----
- 다음 줄을 Dockerfile에 넣습니다 (마지막 단계에서).
# Update system and install curl and ca-certificates
RUN apt-get update && apt-get install -y curl && apt-get install -y ca-certificates
# Copy your bundle file to the system trusted storage
COPY ./ca_bundle.crt /usr/local/share/ca-certificates/ca_bundle.crt
# During docker build, after this line you will get such output: 1 added, 0 removed; done.
RUN update-ca-certificates
- 앱에서 :
var address = new EndpointAddress("https://serviceUrl");
var binding = new BasicHttpsBinding
{
CloseTimeout = new TimeSpan(0, 1, 0),
OpenTimeout = new TimeSpan(0, 1, 0),
ReceiveTimeout = new TimeSpan(0, 1, 0),
SendTimeout = new TimeSpan(0, 1, 0),
MaxBufferPoolSize = 524288,
MaxBufferSize = 65536,
MaxReceivedMessageSize = 65536,
TextEncoding = Encoding.UTF8,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true,
AllowCookies = false,
BypassProxyOnLocal = false,
ReaderQuotas = XmlDictionaryReaderQuotas.Max,
Security =
{
Mode = BasicHttpsSecurityMode.Transport,
Transport = new HttpTransportSecurity
{
ClientCredentialType = HttpClientCredentialType.Certificate,
ProxyCredentialType = HttpProxyCredentialType.None
}
}
};
var client = new MyWSClient(binding, address);
client.ClientCredentials.ClientCertificate.Certificate = GetClientCertificate("clientCert.pfx", "passwordForClientCert");
// Client certs must be installed
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
{
CertificateValidationMode = X509CertificateValidationMode.ChainTrust,
TrustedStoreLocation = StoreLocation.LocalMachine,
RevocationMode = X509RevocationMode.NoCheck
};
GetClientCertificate 메서드 :
private static X509Certificate2 GetClientCertificate(string clientCertName, string password)
{
//Create X509Certificate2 object from .pfx file
byte[] rawData = null;
using (var f = new FileStream(Path.Combine(AppContext.BaseDirectory, clientCertName), FileMode.Open, FileAccess.Read))
{
var size = (int)f.Length;
var rawData = new byte[size];
f.Read(rawData, 0, size);
f.Close();
}
return new X509Certificate2(rawData, password);
}
답변
첫째, 생산에 사용하지 마십시오.
AddHttpClient 미들웨어를 사용하는 경우 유용합니다. 프로덕션이 아닌 개발 목적으로 필요하다고 생각합니다. 유효한 인증서를 만들 때까지이 Func를 사용할 수 있습니다.
Func<HttpMessageHandler> configureHandler = () =>
{
var bypassCertValidation = Configuration.GetValue<bool>("BypassRemoteCertificateValidation");
var handler = new HttpClientHandler();
//!DO NOT DO IT IN PRODUCTION!! GO AND CREATE VALID CERTIFICATE!
if (bypassCertValidation)
{
handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, x509Certificate2, x509Chain, sslPolicyErrors) =>
{
return true;
};
}
return handler;
};
그리고 그것을 같이 적용하십시오
services.AddHttpClient<IMyClient, MyClient>(x => { x.BaseAddress = new Uri("https://localhost:5005"); })
.ConfigurePrimaryHttpMessageHandler(configureHandler);