【问题标题】:Calling WCF Service with basic auth and client certificate使用基本身份验证和客户端证书调用 WCF 服务
【发布时间】:2019-07-05 17:32:39
【问题描述】:

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

我们的 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,我们会收到上述错误。

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

是否有任何 .Net Framework 方法可以同时提供证书和基本身份验证标头,而不是手动添加标头?

【问题讨论】:

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


    【解决方案1】:

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

    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!";
    

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

    【讨论】:

    • why do we need to authenticate the client with Basic Authentication? 因为这是我无法控制的第三方服务。 are you sure that the client needs to provide a certificate? 是的,因为如果我不提供证书,通常会出现无法建立信任的错误。即使在 SoapUI 上,也需要提供基本身份验证和证书。 what is the auto-generated binding type on the client side when calling the service by adding service reference? 我们提供了 wsdl,因此它是从文件生成的,而不是网络参考。
    • 最后一个回复没有意义,reference.cs和客户端配置仍然会生成。我们可以检查绑定类型,对吗?此外,只要第三方认证确实包括基础认证,还可以有其他方式,但不会更容易。它仍然手动编写http头。
    • 使用客户端 IClientmessageinspector 接口为所有出站消息添加基本标头stackoverflow.com/questions/48512493/…
    • the reference.cs and client configuration will be generated still 是的,字符用完了 :) we can check the binding type 绑定类型与代码 sn-p 中的myBinding.Security.Transport.ClientCredentialType 设置相同(除非我误解了你)@987654331 @
    • 我们管理运行客户端的许多服务器。如果可能的话,我们希望避免启动机器并确保正确安装证书。即使安装了证书,传输模式似乎仍然需要设置,因为 wcf 需要使用证书。在上面我们通过文件而不是密钥库提供 X509 证书。
    猜你喜欢
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 2011-04-09
    • 2013-10-07
    • 1970-01-01
    • 2018-02-12
    • 2013-07-05
    • 1970-01-01
    相关资源
    最近更新 更多