Skip to content

Deprecate service point for server certificate #4731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

class HttpClientHandler_SecureExample
{
// <Snippet1>
static async Task Main()
{
// Create an HttpClientHandler object and set to use default credentials
HttpClientHandler handler = new HttpClientHandler();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HttpClientHandler handler = new HttpClientHandler();
var handler = new HttpClientHandler();


// Set custom server validation callback
handler.ServerCertificateCustomValidationCallback = ServerCertificateCustomValidation;

// Create an HttpClient object
HttpClient client = new HttpClient(handler);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HttpClient client = new HttpClient(handler);
var client = new HttpClient(handler);


// Call asynchronous network methods in a try/catch block to handle exceptions
try
{
HttpResponseMessage response = await client.GetAsync("https://docs.microsoft.com/");

response.EnsureSuccessStatusCode();

string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Read {responseBody.Length} characters");
}
catch (HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine($"Message: {e.Message} ");
}

// Need to call dispose on the HttpClient and HttpClientHandler objects
// when done using them, so the app doesn't leak resources
handler.Dispose();
client.Dispose();
}

private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors)
{
// It is possible inpect the certificate provided by server
Console.WriteLine($"Requested URI: {requestMessage.RequestUri}");
Console.WriteLine($"Effective date: {certificate.GetEffectiveDateString()}");
Console.WriteLine($"Exp date: {certificate.GetExpirationDateString()}");
Console.WriteLine($"Issuer: {certificate.Issuer}");
Console.WriteLine($"Subject: {certificate.Subject}");

// Based on the custom logic it is possible to decide whether the client considers certificate valid or not
Console.WriteLine($"Errors: {sslErrors}");
return sslErrors == SslPolicyErrors.None;
}
// </Snippet1>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>dotnet_api_docs</RootNamespace>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

class HttpClientHandler_Example
{
Expand All @@ -16,7 +17,7 @@ static async Task Main()
HttpClient client = new HttpClient(handler);

// Call asynchronous network methods in a try/catch block to handle exceptions
try
try
{
HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");

Expand All @@ -27,14 +28,14 @@ static async Task Main()
}
catch(HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ",e.Message);
}

// Need to call dispose on the HttpClient and HttpClientHandler objects
// when done using them, so the app doesn't leak resources
handler.Dispose(true);
client.Dispose(true);
handler.Dispose();
client.Dispose();
}
// </Snippet1>
// </Snippet1>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>dotnet_api_docs</RootNamespace>
</PropertyGroup>

</Project>
14 changes: 13 additions & 1 deletion xml/System.Net.Http/HttpClientHandler.xml
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,19 @@ handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousA
<Docs>
<summary>Gets or sets a callback method to validate the server certificate.</summary>
<value>A callback method to validate the server certificate.</value>
<remarks>To be added.</remarks>
<remarks>
<format type="text/markdown"><![CDATA[

## Remarks
The <xref:System.Net.Http.HttpClientHandler.ServerCertificateCustomValidationCallback%2A> can be used to obtain and validate the server certificate.

## Examples
The following code example displays the server certificate.

[!code-csharp[System.Net.Http.HttpClientHandler#5](~/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/program.cs#1)]

]]></format>
</remarks>
</Docs>
</Member>
<Member MemberName="SslProtocols">
Expand Down
7 changes: 5 additions & 2 deletions xml/System.Net/ServicePoint.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
> [!NOTE]
> In high load conditions, some applications may run out of free threads in the ThreadPool, which may lead to poor system performance (such as high and variable transaction times).


> [!IMPORTANT]
> We don't recommend that you use the `ServicePoint` class for new development. Instead, use the <xref:System.Net.Http.HttpClient?displayProperty=nameWithType> class.

## Examples
The following code example creates a <xref:System.Net.ServicePoint> object that connects to the URI `www.contoso.com`.
Expand Down Expand Up @@ -204,7 +205,9 @@
## Remarks
Although a <xref:System.Net.ServicePoint> object can make multiple connections to an Internet resource, it can maintain only one certificate.


> [!NOTE]
> Starting in .NET Core 1.0 and later including .NET 5.0 and later, the <xref:System.Net.ServicePoint.Certificate%2A> property always returns null. The <xref:System.Net.Http.HttpClientHandler.ServerCertificateCustomValidationCallback%2A> is the recomendded way to access the server certificate.


## Examples
The following code example displays the value of this property.
Expand Down
3 changes: 2 additions & 1 deletion xml/System.Net/ServicePointManager.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@

Developers may want to opt out of this behavior in order to maintain interoperability with their existing SSL3 services or TLS w/ RC4 services. [This article](https://support.microsoft.com/kb/3069494) explains how to modify your code so that the new behavior is disabled.


> [!IMPORTANT]
> We don't recommend that you use the `ServicePointManager` class for new development. Instead, use the <xref:System.Net.Http.HttpClient?displayProperty=nameWithType> class.

## Examples
The following code example creates a <xref:System.Net.ServicePoint> object for connections to the URI `www.contoso.com`.
Expand Down