WCF错误 - 邮件安全验证失败

时间:2011-06-15 17:33:02

标签: .net wcf web-services

我正在尝试使用新的WCF服务。该服务在分层安全性之前正在运行。现在我收到了这个错误:

An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.

Server stack trace: 
   at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
   at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at MyProject.IntegrationSample.MyProjectService.IMyProjectService.GetData(Int32 value)
   at MyProject.IntegrationSample.MyProjectService.MyProjectServiceClient.GetData(Int32 value) in C:\code\AdvancedFraudSolutions\MyProject4.0\MyProject.IntegrationSample\Service References\MyProjectService\Reference.cs:line 82
   at MyProject.IntegrationSample.Program.Main(String[] args) in C:\code\AdvancedFraudSolutions\MyProject4.0\MyProject.IntegrationSample\Program.cs:line 22
At least one security token in the message could not be validated.

这在跟踪日志中:

Message security verification failed.

这是我的服务配置:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicBinding">
          <security mode="TransportWithMessageCredential"/>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="MyProject.IntegrationServices.MyProjectService" behaviorConfiguration="basicServiceBehavior">
        <endpoint binding="basicHttpBinding" bindingConfiguration="basicBinding"
          name="MyProjectServiceEndpoint" contract="MyProject.IntegrationServices.IMyProjectService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="basicServiceBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization principalPermissionMode="UseAspNetRoles"
            roleProviderName="AspNetSqlRoleProvider" />
          <serviceCredentials>
            <serviceCertificate findValue="MyServiceCert" x509FindType="FindBySubjectName" />
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
              membershipProviderName="AspNetSqlMembershipProvider" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

    <diagnostics>
      <messageLogging maxMessagesToLog="25000" logEntireMessage="true" logMessagesAtServiceLevel="false"  logMalformedMessages="true" 
                      logMessagesAtTransportLevel="true">
        <filters>
          <clear/>
        </filters>
      </messageLogging>
    </diagnostics>

  </system.serviceModel>

这是我的测试客户端代码和配置:

    static void Main(string[] args)
    {
        MyProjectServiceClient client = new MyProjectServiceClient();
        client.ClientCredentials.UserName.UserName = "theuser";
        client.ClientCredentials.UserName.Password = "thepass";

        try
        {
            string result = client.GetData(100);
            client.Close();
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            client.Abort();
            PrintExceptionDetail(ex);
        }

        Console.ReadLine();
    }

    private static void PrintExceptionDetail(Exception ex)
    {
        StringBuilder detail = new StringBuilder();
        while (ex != null)
        {
            detail.AppendLine(ex.Message);
            detail.AppendLine(ex.StackTrace);
            ex = ex.InnerException;
        }

        Console.WriteLine(detail);

        Console.Write("Copy exception detail to clipboard? (y/n) ");
        if (Console.ReadLine().ToLower() == "y")
        {
            Clipboard.SetText(detail.ToString());
        }
    }



<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="MyProjectServiceEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288"
                 maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://localhost:44306/MyProjectService.svc" binding="basicHttpBinding" bindingConfiguration="MyProjectServiceEndpoint"
                contract="MyProjectService.IMyProjectService" name="MyProjectServiceEndpoint"/>
    </client>
  </system.serviceModel>

您可以看到我正在尝试使用basicHttpBinding,TransportWithMessageCredential安全性以及成员资格/角色提供程序进行身份验证/授权。

这是使用IIS express开发的,将在IIS中托管。

错误的原因是什么?

4 个答案:

答案 0 :(得分:6)

我通过在服务主机web.config文件中添加计算机密钥来解决此问题。

服务跟踪日志没有帮助。它只给了我“消息安全验证失败”。然后,我使用

为服务主机web.config文件启用了wcf服务事件日志
 <configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="NewBehavior">
                    <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
                </behavior>
           </serviceBehaviors>
        </behaviors>
    </system>
  </configuration>

我在计算机应用程序事件日志中得到了以下信息,这有助于

  

事件类型:错误   事件源:ServiceModel Audit 4.0.0.0   事件类别:MessageAuthentication   活动编号:4   日期:2013年1月30日   时间:下午3:18:27   用户:N / A.   电脑:CENTDAUD05109DL   描述:   邮件验证失败。    服务:: // mymachine:44304 / UploadService.svc    行动:http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT    CLIENTIDENTITY:    ActivityId:cf20ce8b-2e8c-45b5-9ab6-adc5051080f8    ProviderException:您必须指定非自动生成的计算机密钥才能以加密格式存储密码。指定不同的passwordFormat,或更改machineKey配置以使用非自动生成的解密密钥

然后我将机器密钥添加到服务主机web.config并且它工作正常。下面是示例机器密钥。

 <machineKey 
validationKey= 
"5AD524EF7BEB32A479F8095F8BF7653680066ADE66B5C78F80C3DC1F90
AA3D766F2B69304BFF88DEABEDE1E66D463C81FDEE0FC1A391AD90A6FD1294E7D243B1" 
decryptionKey=
 "0D7AE7BC7581976D76AC1D68C71BCBA978895CB792DC4F7B9F0D67774378A351"  
validation="SHA1" 
decryption="AES"/>

参考,

http://blogs.microsoft.co.il/blogs/urig/archive/2011/01/23/wcf-quot-an-error-occurred-when-verifying-security-for-the-message-quot-and-service-security-audit.aspx

http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/

答案 1 :(得分:1)

我的配置没有任何问题。最后问题是我使用sqlserver express的UserInstance作为成员资格和角色数据库。一旦我正常创建数据库,一切都开始工作了。跛。

答案 2 :(得分:1)

我将系统时间更改为服务器时间。现在它的工作正常。但这不是一个好方法,如果用户来自其他国家,那么他们必须改变服务器时间。所以请任何人建议任何好的方法来做到这一点..

答案 3 :(得分:0)

这很可能是由于客户端和服务器之间的时间关闭。我相信默认是5分钟。您可以通过创建自定义绑定来更改最大时间偏差,也可以只验证时间是否正确。