如何使用Windows身份验证构建https WCF服务器/客户端?
我需要使用https协议构建Windows服务/客户端。应使用客户端提供的用户名/密码在服务器上对用户进行身份验证。我使用TLS加密的传输级保护。该服务是自托管的(没有IIS)。
文档非常模糊,大多数描述只是重复变量的名称而没有解释。此外,我无法找到一个有效的示例。
I need to build a Windows service/client using https protocol. The user should be authenticated on the server using username/password, provided on the client side. I use Transport level protection with TLS encryption. The service is self-hosted (no IIS). Documentation is very vague and most description just repeats the name of the variable with no explanations. Also I was not able to find a functioning example.
我的代码分布在多个函数中。为简单起见,下面是一些我认为与该问题相关的代码片段。请随时询问更多详细信息。
My code is distributed across multiple functions. For simplicity reasons, below are some code snippets that I think relevant to the question. Feel free to ask for more details.
服务器:
private static Binding CreateWebHttpBinding()
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var binding = new WebHttpBinding(WebHttpSecurityMode.Transport)
{
ReaderQuotas = _readerQuotas,
MaxReceivedMessageSize = 2147483647,
OpenTimeout = TimeSpan.MaxValue,
CloseTimeout = TimeSpan.MaxValue,
SendTimeout = TimeSpan.MaxValue,
ReceiveTimeout = TimeSpan.MaxValue,
TransferMode = TransferMode.Buffered
};
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
// I have no idea what Windows actually means - is it the client Windows system or the server Windows?
返回绑定;
}
return binding; }
var address = new Uri[] { new Uri($"https://localhost:443/MyApp/{serviceName}.svc") };
var host = new ServiceHost(serviceType, address);
var endpoint = host.AddServiceEndpoint(serviceContract, CreateWebHttpBinding(), "");
endpoint.Behaviors.Add(new WebHttpBehavior { DefaultBodyStyle = WebMessageBodyStyle.Wrapped });
host.Open();
客户:
endpointAddress = $"https://{middlewareHost}:443/MyApp/{serviceName}.svc";
binding = CreateWebHttpBinding(); // same as for the server side
var channelFactory = new ChannelFactory<T>(binding, new EndpointAddress(new Uri(endpointAddress)));
if (channelFactory.Credentials != null)
{
channelFactory.Credentials.Windows.ClientCredential =
new NetworkCredential(userName, userPassword);
channelFactory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
// Here is another totally mysterious setting ^
}
ClientCredentials clientCredentials = null;
foreach (var b in channelFactory.Endpoint.Behaviors)
{
clientCredentials = b as ClientCredentials;
if (clientCredentials != null)
{
break;
}
}
if (clientCredentials == null)
{
clientCredentials = new ClientCredentials();
channelFactory.Endpoint.Behaviors.Add(clientCredentials);
}
clientCredentials.UserName.UserName = userName;
clientCredentials.UserName.Password = userPassword;
channelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior { DefaultBodyStyle = WebMessageBodyStyle.Wrapped });
channelFactory.CreateChannel()
我正在进行为期两周的工作并完全失败。当我尝试使用http和端口80(传输安全性无)时,我连接,但没有进行身份验证,当我使用https和端口443时,客户端的请求被拒绝,"现有连接
被强行关闭远程主机"。它没有到达我的服务器。我想它被Windows系统拒绝,但由于缺少IIS我不知道 - 如何找到线索。有很多设置,很少或没有文档,没有示例。请
帮助。
I am working on it for two weeks and completely lost. When I try to use http and port 80 (Transport Security None), I get connected, but no authentication happens, when I use https and port 443 the client's request gets rejected with "An existing connection was forcibly closed by the remote host". It does not reach my server. I guess it is rejected by Windows system, but with absence of IIS I don't know - how to find a clue. There are so many settings with little or no documentation and no examples. Please help.
是的,我在服务器端启用了http 80和https 443端口。
And yes, I enabled http 80 and https 443 ports on the server side.
还有一条评论。有些示例使用"WsHttpBinding",而不是"WebHttpBinding"。我实际上尝试过"WsHttpBinding"。除了"WsHttpBinding"之外,它分叉很好。需要直接连接,在互联网上使用
是不可接受的,其中客户端计算机可能位于专用网络中。
One more comment. There are examples that work with "WsHttpBinding", not with "WebHttpBinding". I actually tried "WsHttpBinding" and it forked just fine, except that "WsHttpBinding" requires a direct connection, which is not acceptable for use on the internet, where client computers may be located in a private network.
上述示例还说我需要安装证书:
The aforementioned example also says that I need to install a certificate:
netsh http add sslcert ipport=0.0.0.0:8000 certhash=0000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}
但文章没有提到我可以在哪里获得"appid"。看起来有评论在这里和那里有一些重要的信息缺失,这是非常令人沮丧的。
But the article does not mention where I can get the "appid". Looks like there are comments here and there with some important information missing, which is very frustrating.