使用基本身份验证和客户端证书调用WCF服务

时间:2019-07-05 17:32:39

标签: c# wcf ssl-certificate basic-authentication

我们正在将客户端写入同时使用CSR证书和基本身份验证的WCF服务。

我们的C#客户端是通过Visual Studio生成的,我们可以以编程方式设置证书和用户名/密码。但是,我们必须手动发送Basic Auth标头,否则会收到错误:

'The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="HttpBasicAuthentication"'.'

我们的代码是:

var myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
myBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

var ea = new EndpointAddress("https://example.org/myservice");
var client = new MandateWebServiceClient(myBinding, ea);
client.ClientCredentials.UserName.UserName = "wally";
client.ClientCredentials.UserName.Password = "walliesWorld";
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("C:\\some\\path\\to\\csr.pfx", "password");

using (var scope = new OperationContextScope(client.InnerChannel))
{
    var httpRequestProperty = new HttpRequestMessageProperty();
    httpRequestProperty.Headers[HttpRequestHeader.Authorization] =
        "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password));
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

    client.create();
}

使用上面的代码,我们可以成功地与服务对话。如果我们删除using块中的行,则身份验证方案将更改为Anonymous,并得到上面的错误。

以上安排似乎有点hackey。我们已经尝试了所有可能的SecurityMode设置,并且SecurityMode.TransportHttpClientCredentialType.Certificate是允许证书被接受的唯一组合。设置或不设置MessageCredentialType.UserName似乎对系统没有影响。

是否有.Net Framework提供证书和基本身份验证标头而不是手动添加标头的方法?

1 个答案:

答案 0 :(得分:0)

服务器如何同时使用证书身份验证和基本身份验证?这似乎是多余的。由于使用证书对客户端进行身份验证是安全的(颁发证书并建立服务器与客户端之间的关系),为什么我们需要使用基本身份验证对客户端进行身份验证?从而,您确定客户端需要提供证书吗?我认为服务器可能已经使用了传输安全性模式,并设置了基本身份验证,因此客户端可能不需要提供证书。
这是我认为的服务器端配置。
服务器。

Uri uri = new Uri("https://localhost:9900");
        WSHttpBinding binding = new WSHttpBinding();
        binding.Security.Mode = SecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

客户端(通过添加服务引用进行调用,客户端代理类/绑定类型是通过服务MEX端点https://localhost:9900/mex自动生成的)

ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            client.ClientCredentials.UserName.UserName = "administrator";
            client.ClientCredentials.UserName.Password = "abcd1234!";

基于此,我有一个问题,通过添加服务引用调用服务时,客户端上自动生成的绑定类型是什么?
期待您的回复。