Skip to content

Commit f3d08e7

Browse files
Jan JahodaJan JahodaYoussef1313ManickaP
authored
Deprecate service point for server certificate (#4731)
* Deprecate service point for server certificate * Unify obsoletion message with webrequest * Apply suggestions from code review Co-authored-by: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> * Update xml/System.Net.Http/HttpClientHandler.xml Co-authored-by: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> * Update xml/System.Net.Http/HttpClientHandler.xml Co-authored-by: Marie Píchová <11718369+ManickaP@users.noreply.github.com> * Fix example path Co-authored-by: Jan Jahoda <jajahoda@.microsoft.com> Co-authored-by: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Co-authored-by: Marie Píchová <11718369+ManickaP@users.noreply.github.com>
1 parent dd44286 commit f3d08e7

File tree

7 files changed

+103
-9
lines changed

7 files changed

+103
-9
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.IO;
3+
using System.Net;
4+
using System.Net.Http;
5+
using System.Net.Security;
6+
using System.Security.Cryptography.X509Certificates;
7+
using System.Threading.Tasks;
8+
9+
class HttpClientHandler_SecureExample
10+
{
11+
// <Snippet1>
12+
static async Task Main()
13+
{
14+
// Create an HttpClientHandler object and set to use default credentials
15+
HttpClientHandler handler = new HttpClientHandler();
16+
17+
// Set custom server validation callback
18+
handler.ServerCertificateCustomValidationCallback = ServerCertificateCustomValidation;
19+
20+
// Create an HttpClient object
21+
HttpClient client = new HttpClient(handler);
22+
23+
// Call asynchronous network methods in a try/catch block to handle exceptions
24+
try
25+
{
26+
HttpResponseMessage response = await client.GetAsync("https://docs.microsoft.com/");
27+
28+
response.EnsureSuccessStatusCode();
29+
30+
string responseBody = await response.Content.ReadAsStringAsync();
31+
Console.WriteLine($"Read {responseBody.Length} characters");
32+
}
33+
catch (HttpRequestException e)
34+
{
35+
Console.WriteLine("\nException Caught!");
36+
Console.WriteLine($"Message: {e.Message} ");
37+
}
38+
39+
// Need to call dispose on the HttpClient and HttpClientHandler objects
40+
// when done using them, so the app doesn't leak resources
41+
handler.Dispose();
42+
client.Dispose();
43+
}
44+
45+
private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors)
46+
{
47+
// It is possible inpect the certificate provided by server
48+
Console.WriteLine($"Requested URI: {requestMessage.RequestUri}");
49+
Console.WriteLine($"Effective date: {certificate.GetEffectiveDateString()}");
50+
Console.WriteLine($"Exp date: {certificate.GetExpirationDateString()}");
51+
Console.WriteLine($"Issuer: {certificate.Issuer}");
52+
Console.WriteLine($"Subject: {certificate.Subject}");
53+
54+
// Based on the custom logic it is possible to decide whether the client considers certificate valid or not
55+
Console.WriteLine($"Errors: {sslErrors}");
56+
return sslErrors == SslPolicyErrors.None;
57+
}
58+
// </Snippet1>
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net5.0</TargetFramework>
6+
<RootNamespace>dotnet_api_docs</RootNamespace>
7+
</PropertyGroup>
8+
9+
</Project>

samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/source.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Net;
44
using System.Net.Http;
5+
using System.Threading.Tasks;
56

67
class HttpClientHandler_Example
78
{
@@ -16,7 +17,7 @@ static async Task Main()
1617
HttpClient client = new HttpClient(handler);
1718

1819
// Call asynchronous network methods in a try/catch block to handle exceptions
19-
try
20+
try
2021
{
2122
HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
2223

@@ -27,14 +28,14 @@ static async Task Main()
2728
}
2829
catch(HttpRequestException e)
2930
{
30-
Console.WriteLine("\nException Caught!");
31+
Console.WriteLine("\nException Caught!");
3132
Console.WriteLine("Message :{0} ",e.Message);
3233
}
3334

3435
// Need to call dispose on the HttpClient and HttpClientHandler objects
3536
// when done using them, so the app doesn't leak resources
36-
handler.Dispose(true);
37-
client.Dispose(true);
37+
handler.Dispose();
38+
client.Dispose();
3839
}
39-
// </Snippet1>
40+
// </Snippet1>
4041
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net5.0</TargetFramework>
6+
<RootNamespace>dotnet_api_docs</RootNamespace>
7+
</PropertyGroup>
8+
9+
</Project>

xml/System.Net.Http/HttpClientHandler.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,19 @@ handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousA
973973
<Docs>
974974
<summary>Gets or sets a callback method to validate the server certificate.</summary>
975975
<value>A callback method to validate the server certificate.</value>
976-
<remarks>To be added.</remarks>
976+
<remarks>
977+
<format type="text/markdown"><![CDATA[
978+
979+
## Remarks
980+
The <xref:System.Net.Http.HttpClientHandler.ServerCertificateCustomValidationCallback%2A> can be used to obtain and validate the server certificate.
981+
982+
## Examples
983+
The following code example displays the server certificate.
984+
985+
[!code-csharp[System.Net.Http.HttpClientHandler#5](~/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/program.cs#1)]
986+
987+
]]></format>
988+
</remarks>
977989
</Docs>
978990
</Member>
979991
<Member MemberName="SslProtocols">

xml/System.Net/ServicePoint.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
> [!NOTE]
5555
> 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).
5656
57-
57+
> [!IMPORTANT]
58+
> We don't recommend that you use the `ServicePoint` class for new development. Instead, use the <xref:System.Net.Http.HttpClient?displayProperty=nameWithType> class.
5859
5960
## Examples
6061
The following code example creates a <xref:System.Net.ServicePoint> object that connects to the URI `www.contoso.com`.
@@ -204,7 +205,9 @@
204205
## Remarks
205206
Although a <xref:System.Net.ServicePoint> object can make multiple connections to an Internet resource, it can maintain only one certificate.
206207
207-
208+
> [!NOTE]
209+
> 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.
210+
208211
209212
## Examples
210213
The following code example displays the value of this property.

xml/System.Net/ServicePointManager.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
4747
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.
4848
49-
49+
> [!IMPORTANT]
50+
> We don't recommend that you use the `ServicePointManager` class for new development. Instead, use the <xref:System.Net.Http.HttpClient?displayProperty=nameWithType> class.
5051
5152
## Examples
5253
The following code example creates a <xref:System.Net.ServicePoint> object for connections to the URI `www.contoso.com`.

0 commit comments

Comments
 (0)