使用 WebApi 自托管超过 SSL/TLS
Consuming WebApi Self Host over SSL/TLS
我有一个基于 SSL 的 WebApi 自托管控制台服务器。
服务器负责创建 SSL 证书,将它们添加到证书存储区,并使用 netsh 将证书绑定到端口。
服务器有一个简单的控制器,可以通过 HTTP GET returns 字符串 "Hello World"。
我可以通过浏览器毫无问题地访问它,而且我很确定服务器代码没有任何问题,所以我只去post这里有问题的客户端代码。
private static string url = @"https://localhost:4443/WebApi/Service/HelloWorld;
private static async Task GetHelloWorldRequest(string url)
{
using (HttpClient httpClient = new HttpClient(GetSSLHandler()))
{
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(url);
await httpClient
.SendAsync(request)
.ContinueWith((response)
=>
{
try
{
ProcessResponse(response);
}
catch (AggregateException agException)
{
throw new Exception("Error getting response: " + agException.Message);
}
}).ConfigureAwait(false);
}
}
private static void ProcessResponse(Task<HttpResponseMessage> response)
{
Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
}
private static void ProcessResponseHeaders(Task<HttpResponseMessage> response)
{
Console.WriteLine(response.Result.Headers.ToString());
}
private static WebRequestHandler GetSSLHandler()
{
WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 certificate = GetMyX509Certificate();
handler.ClientCertificates.Add(certificate);
return handler;
}
现在在我的主要例程中我简单地调用这个:
Console.WriteLine("Response headers:");
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Task task = GetHelloWorldRequest(url);
task.Wait();
现在我的问题是,如果我尝试读取应该给我 "Hello World" 的响应内容,它会给我一个空字符串。
所以我试着查看响应 headers,这就是我得到的:
好像是在谈判阶段,不知道接下来要做什么。
请指教。提前谢谢你。
编辑:
抱歉,问题出在服务器代码上。只需取消注释调用 httpBinding.ConfigureTransportBindingElement.
的部分
class SslHttpsSelfHostConfiguration : HttpSelfHostConfiguration
{
public SslHttpsSelfHostConfiguration(string baseAddress) : base(baseAddress) { }
public SslHttpsSelfHostConfiguration(Uri baseAddress) : base(baseAddress) { }
protected override BindingParameterCollection OnConfigureBinding(HttpBinding httpBinding)
{
httpBinding.Security.Mode = HttpBindingSecurityMode.Transport;
/*
httpBinding.ConfigureTransportBindingElement = (element =>
element.AuthenticationScheme =
AuthenticationSchemes.Negotiate);
*/
return base.OnConfigureBinding(httpBinding);
}
}
请尝试运行这个:
var client = new HttpClient
{
BaseAddress = new Uri("https://localhost:4443/")
};
var result = await client.GetAsync("WebApi/Service/HelloWorld").ConfigureAwait(false);
var data = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
return data;
作为您的请求任务。
并尝试更改
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
至
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
我有一个基于 SSL 的 WebApi 自托管控制台服务器。
服务器负责创建 SSL 证书,将它们添加到证书存储区,并使用 netsh 将证书绑定到端口。
服务器有一个简单的控制器,可以通过 HTTP GET returns 字符串 "Hello World"。
我可以通过浏览器毫无问题地访问它,而且我很确定服务器代码没有任何问题,所以我只去post这里有问题的客户端代码。
private static string url = @"https://localhost:4443/WebApi/Service/HelloWorld;
private static async Task GetHelloWorldRequest(string url)
{
using (HttpClient httpClient = new HttpClient(GetSSLHandler()))
{
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(url);
await httpClient
.SendAsync(request)
.ContinueWith((response)
=>
{
try
{
ProcessResponse(response);
}
catch (AggregateException agException)
{
throw new Exception("Error getting response: " + agException.Message);
}
}).ConfigureAwait(false);
}
}
private static void ProcessResponse(Task<HttpResponseMessage> response)
{
Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
}
private static void ProcessResponseHeaders(Task<HttpResponseMessage> response)
{
Console.WriteLine(response.Result.Headers.ToString());
}
private static WebRequestHandler GetSSLHandler()
{
WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 certificate = GetMyX509Certificate();
handler.ClientCertificates.Add(certificate);
return handler;
}
现在在我的主要例程中我简单地调用这个:
Console.WriteLine("Response headers:");
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Task task = GetHelloWorldRequest(url);
task.Wait();
现在我的问题是,如果我尝试读取应该给我 "Hello World" 的响应内容,它会给我一个空字符串。
所以我试着查看响应 headers,这就是我得到的:
好像是在谈判阶段,不知道接下来要做什么。
请指教。提前谢谢你。
编辑:
抱歉,问题出在服务器代码上。只需取消注释调用 httpBinding.ConfigureTransportBindingElement.
的部分class SslHttpsSelfHostConfiguration : HttpSelfHostConfiguration
{
public SslHttpsSelfHostConfiguration(string baseAddress) : base(baseAddress) { }
public SslHttpsSelfHostConfiguration(Uri baseAddress) : base(baseAddress) { }
protected override BindingParameterCollection OnConfigureBinding(HttpBinding httpBinding)
{
httpBinding.Security.Mode = HttpBindingSecurityMode.Transport;
/*
httpBinding.ConfigureTransportBindingElement = (element =>
element.AuthenticationScheme =
AuthenticationSchemes.Negotiate);
*/
return base.OnConfigureBinding(httpBinding);
}
}
请尝试运行这个:
var client = new HttpClient
{
BaseAddress = new Uri("https://localhost:4443/")
};
var result = await client.GetAsync("WebApi/Service/HelloWorld").ConfigureAwait(false);
var data = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
return data;
作为您的请求任务。
并尝试更改
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
至
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;