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

Ron*_*rby 0 .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.
Run Code Online (Sandbox Code Playgroud)

这在跟踪日志中:

Message security verification failed.
Run Code Online (Sandbox Code Playgroud)

这是我的服务配置:

<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>
Run Code Online (Sandbox Code Playgroud)

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

    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>
Run Code Online (Sandbox Code Playgroud)

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

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

错误的原因是什么?

Dig*_*mar 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>
Run Code Online (Sandbox Code Playgroud)

我在计算机应用程序事件日志中得到以下内容,

事件类型:错误事件源:ServiceModel审计4.0.0.0事件类别:MessageAuthentication事件ID:4日期:30/01/2013时间:3:18:27 PM用户: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"/>
Run Code Online (Sandbox Code Playgroud)

参考文献,

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

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