为了账号安全,请及时绑定邮箱和手机立即绑定

使用代码隐藏而不是 Web.Config 端点调用服务时出现不安全或安全错误错误

使用代码隐藏而不是 Web.Config 端点调用服务时出现不安全或安全错误错误

C#
HUH函数 2023-09-16 15:14:34
我有一个具有消息安全性的 WCF 服务,并且我正在尝试将客户端连接到它。使用由 Visual Studio 中的“添加服务引用”自动生成的默认 Web.Config 设置,连接效果非常好,设置如下:端点:  <endpoint address="http://localhost:56017/services/MaternumPdfService.svc/soap"    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMaternumPdfService"    contract="MaternumPdfServiceReference.IMaternumPdfService" name="WSHttpBinding_IMaternumPdfService">    <identity>      <certificate encodedValue="BASE64 IS HERE" />    </identity>  </endpoint>捆绑:    <binding name="WSHttpBinding_IMaternumPdfService" maxReceivedMessageSize="2147483647">      <security>        <message clientCredentialType="UserName" negotiateServiceCredential="false"          establishSecurityContext="false" />      </security>      <readerQuotas maxStringContentLength="2147483647" maxDepth="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>    </binding>这可以顺利进行:        using (MaternumPdfServiceClient pdfService = new MaternumPdfServiceClient("WSHttpBinding_IMaternumPdfService"))        {            pdfService.ClientCredentials.UserName.UserName = "sample";            pdfService.ClientCredentials.UserName.Password = "sample";            pdfService.Open();            if (!pdfService.State.Equals(CommunicationState.Opened))            {                return null;            }            MemoryStream ms = new MemoryStream();            pdfService.GetMaternumPdf(pdftype,params).CopyTo(ms);        }我以为我正在 C# 版本和使用 Web.Config 设置的版本之间构建完全等效的代码,但与第二个版本连接会导致异常:'An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.'具有以下内部异常:An error occurred when verifying security for the message.不是特别清楚...这似乎与消息安全有关,但与 Web.Config 的连接工作得很好,这让我相信我没有在正确的类中设置证书。我调查过:WCF 给出不安全或不正确安全的故障错误服务器和客户端都是本地主机,所以不应该是时间不匹配凭据正确,因为 Web.Config 版本使用相同的凭据并且验证良好我使用的是 HTTP,而不是 HTTPS使用 IISExpress,而不是 IIS就是这样。我认为我将客户端证书设置在错误的位置,如果不是通过 ClientCredentials.ClientCertificate.Certificate 或端点的身份,我应该如何设置它?
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

...通常情况下,我的配置错误。我获得了一个名为“MaternumCertificateClient”的证书,而不是我的服务器配置的证书,即“MaternumCertificateServer”。


更重要的是我是如何得出这个错误的。


第一步,我设置 Wireshark 以查看服务器的回复内容:


HTTP/1.1 500 Internal Server Error

Cache-Control: private

Content-Type: application/soap+xml; charset=utf-8

Server: Microsoft-IIS/10.0

Set-Cookie: ASP.NET_SessionId=k0xmopx3eitnvmocv1rjas4h; path=/; HttpOnly

X-AspNet-Version: 4.0.30319

X-SourceFiles: =?UTF-8?B?QzpcREVWXE1BVFxNYXRlcm51bV9hcHBcc2VydmljZXNcTWF0ZXJudW1QZGZTZXJ2aWNlLnN2Y1xzb2Fw?=

X-Powered-By: ASP.NET

Date: Thu, 22 Aug 2019 16:25:19 GMT

Content-Length: 648


<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">

<s:Header>

    <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>

    <a:RelatesTo>urn:uuid:uid is here</a:RelatesTo>

</s:Header>

<s:Body>

    <s:Fault>

        <s:Code>

            <s:Value>s:Sender</s:Value>

            <s:Subcode>

                <s:Value xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</s:Value>

            </s:Subcode>

        </s:Code>

        <s:Reason>

            <s:Text xml:lang="en-GB">An error occurred when verifying security for the message.</s:Text>

        </s:Reason>

    </s:Fault>

</s:Body>

</s:Envelope>

好不了多少,但我至少知道是谁抛出了异常。

因此,正如所示,我使用以下内容设置我的服务器:

<serviceSecurityAudit auditLogLocation=“Application“ 
    serviceAuthorizationAuditLevel=“Failure“ 
    messageAuthenticationAuditLevel=“Failure“ 
    suppressAuditFailure=“true“ />

在配置/system.serviceModel/behaviors/serviceBehaviors/behavior。

然后,Windows 事件查看器会显示有关该错误的详细信息。

显示的消息,

MessageSecurityException: The EncryptedKey clause was not wrapped with the required encryption token 'System.IdentityModel.Tokens.X509SecurityToken'.

表示证书不匹配。我正在加载一个名为 MaternumCertificateClient 的证书,并且我需要 MaternumCertificateServer。此外,这些行

pdfService.ClientCredentials.ClientCertificate.Certificate = cert;

pdfService.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;

pdfService.ClientCredentials.ServiceCertificate.DefaultCertificate = GetCertificate("MaternumCertificateClient");

实际上并不需要;证书是从端点的身份中读取的,并且我的设置不需要这些设置即可工作。


查看完整回答
反对 回复 2023-09-16
?
德玛西亚99

TA贡献1770条经验 获得超3个赞

正如您所指出的,除了我们使用证书对客户端进行身份验证之外,不需要在客户端提供证书。比如下面的配置。

<wsHttpBinding>  
    <binding name="WSHttpBinding_ICalculator">  
      <security mode="Message">  
        <message clientCredentialType="Certificate" />  
      </security>  
    </binding>  
  </wsHttpBinding>


在服务器端的绑定配置中,只有用户名/密码需要凭证。

  <security>
    <message clientCredentialType="UserName" negotiateServiceCredential="false"
      establishSecurityContext="false" />
  </security>

证书通过使用公钥加密 SOAP 消息来提供消息安全性。在通信过程中,客户端和服务器端交换证书的公钥。我们甚至可以指定服务器域名作为身份,它只是用来保证服务器的身份。
另外,如果你的回复解决了你的问题。请标记为有用,以便帮助遇到类似问题的其他人。
如果有什么需要我帮忙的,请随时告诉我。


查看完整回答
反对 回复 2023-09-16
  • 2 回答
  • 0 关注
  • 92 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信